diff --git a/libasn1compiler/asn1c_constraint.c b/libasn1compiler/asn1c_constraint.c index 24023f09..bd6087e0 100644 --- a/libasn1compiler/asn1c_constraint.c +++ b/libasn1compiler/asn1c_constraint.c @@ -12,16 +12,16 @@ static int emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype, as static int emit_size_determination_code(arg_t *arg, asn1p_expr_type_e etype); static asn1p_expr_type_e _find_terminal_type(arg_t *arg); static int emit_range_comparison_code(arg_t *arg, asn1cnst_range_t *range, const char *varname, asn1c_integer_t natural_start, asn1c_integer_t natural_stop); -static int native_long_sign(asn1cnst_range_t *r); /* -1, 0, 1 */ +static int native_long_sign(arg_t *arg, asn1cnst_range_t *r); /* -1, 0, 1 */ static int -ulong_optimization(asn1p_expr_type_e etype, asn1cnst_range_t *r_size, +ulong_optimization(arg_t *arg, asn1p_expr_type_e etype, asn1cnst_range_t *r_size, asn1cnst_range_t *r_value) { return (!r_size && r_value && (etype == ASN_BASIC_INTEGER || etype == ASN_BASIC_ENUMERATED) - && native_long_sign(r_value) == 0); + && native_long_sign(arg, r_value) == 0); } int @@ -104,8 +104,8 @@ asn1c_emit_constraint_checking_code(arg_t *arg) { switch(etype) { case ASN_BASIC_INTEGER: case ASN_BASIC_ENUMERATED: - if(native_long_sign(r_value) >= 0) { - ulong_optimize = ulong_optimization(etype, r_size, r_value); + if(native_long_sign(arg, r_value) >= 0) { + ulong_optimize = ulong_optimization(arg, etype, r_size, r_value); if(!ulong_optimize) { OUT("unsigned long value;\n"); } @@ -643,7 +643,7 @@ emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype, asn1cnst_rang break; } - if(native_long_sign(r_value) >= 0) { + if(native_long_sign(arg, r_value) >= 0) { /* Special case for treating unsigned longs */ OUT("if(asn_INTEGER2ulong(st, &value)) {\n"); INDENT(+1); @@ -710,7 +710,12 @@ _find_terminal_type(arg_t *arg) { } static int -native_long_sign(asn1cnst_range_t *r) { +native_long_sign(arg_t *arg, asn1cnst_range_t *r) { + if(!(arg->flags & A1C_USE_WIDE_TYPES) && r->left.type == ARE_VALUE + && r->left.value >= 0 && r->left.value <= 2147483647 + && r->right.type == ARE_MAX) { + return 1; + } if(r->left.type == ARE_VALUE && r->left.value >= 0 && r->right.type == ARE_VALUE diff --git a/libasn1compiler/asn1c_misc.c b/libasn1compiler/asn1c_misc.c index 665b748e..99c275b2 100644 --- a/libasn1compiler/asn1c_misc.c +++ b/libasn1compiler/asn1c_misc.c @@ -406,6 +406,9 @@ asn1c_type_fits_long(arg_t *arg, asn1p_expr_t *expr) { asn1constraint_range_free(range); /* Special case for unsigned */ + if(!(arg->flags & A1C_USE_WIDE_TYPES) && left.type == ARE_VALUE + && left.value >= 0 && left.value <= 2147483647 && right.type == ARE_MAX) + return FL_FITS_UNSIGN; if(left.type == ARE_VALUE && left.value >= 0 && right.type == ARE_VALUE diff --git a/tests/tests-asn1c-compiler/50-constraint-OK.asn1.-Pgen-PER b/tests/tests-asn1c-compiler/50-constraint-OK.asn1.-Pgen-PER index 7020fd2c..6499e919 100644 --- a/tests/tests-asn1c-compiler/50-constraint-OK.asn1.-Pgen-PER +++ b/tests/tests-asn1c-compiler/50-constraint-OK.asn1.-Pgen-PER @@ -77,7 +77,7 @@ per_type_encoder_f Int2_encode_uper; int Int2_constraint(asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { - long value; + unsigned long value; if(!sptr) { ASN__CTFAIL(app_key, td, sptr, diff --git a/tests/tests-asn1c-compiler/90-cond-int-type-OK.asn1.-P b/tests/tests-asn1c-compiler/90-cond-int-type-OK.asn1.-P index 7b280523..2767118c 100644 --- a/tests/tests-asn1c-compiler/90-cond-int-type-OK.asn1.-P +++ b/tests/tests-asn1c-compiler/90-cond-int-type-OK.asn1.-P @@ -356,7 +356,7 @@ asn_TYPE_descriptor_t asn_DEF_NO_IntegerLowHigh = { /*** <<< TYPE-DECLS [CN-IntegerLowMax] >>> ***/ -typedef long CN_IntegerLowMax_t; +typedef unsigned long CN_IntegerLowMax_t; /*** <<< FUNC-DECLS [CN-IntegerLowMax] >>> ***/ @@ -374,7 +374,7 @@ xer_type_encoder_f CN_IntegerLowMax_encode_xer; int CN_IntegerLowMax_constraint(asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { - long value; + unsigned long value; if(!sptr) { ASN__CTFAIL(app_key, td, sptr, @@ -383,7 +383,7 @@ CN_IntegerLowMax_constraint(asn_TYPE_descriptor_t *td, const void *sptr, return -1; } - value = *(const long *)sptr; + value = *(const unsigned long *)sptr; if((value >= 1)) { /* Constraint check succeeded */ @@ -403,6 +403,11 @@ CN_IntegerLowMax_constraint(asn_TYPE_descriptor_t *td, const void *sptr, /*** <<< STAT-DEFS [CN-IntegerLowMax] >>> ***/ +static const asn_INTEGER_specifics_t asn_SPC_CN_IntegerLowMax_specs_1 = { + 0, 0, 0, 0, 0, + 0, /* Native long size */ + 1 /* Unsigned representation */ +}; static const ber_tlv_tag_t asn_DEF_CN_IntegerLowMax_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; @@ -420,7 +425,7 @@ asn_TYPE_descriptor_t asn_DEF_CN_IntegerLowMax = { 0, /* No OER visible constraints */ 0, /* No PER visible constraints */ 0, 0, /* No members */ - 0 /* No specifics */ + &asn_SPC_CN_IntegerLowMax_specs_1 /* Additional specs */ }; diff --git a/tests/tests-asn1c-compiler/90-cond-int-type-OK.asn1.-Pgen-PER b/tests/tests-asn1c-compiler/90-cond-int-type-OK.asn1.-Pgen-PER index 68101885..c6bdd60d 100644 --- a/tests/tests-asn1c-compiler/90-cond-int-type-OK.asn1.-Pgen-PER +++ b/tests/tests-asn1c-compiler/90-cond-int-type-OK.asn1.-Pgen-PER @@ -398,7 +398,7 @@ asn_TYPE_descriptor_t asn_DEF_NO_IntegerLowHigh = { /*** <<< TYPE-DECLS [CN-IntegerLowMax] >>> ***/ -typedef long CN_IntegerLowMax_t; +typedef unsigned long CN_IntegerLowMax_t; /*** <<< FUNC-DECLS [CN-IntegerLowMax] >>> ***/ @@ -418,7 +418,7 @@ per_type_encoder_f CN_IntegerLowMax_encode_uper; int CN_IntegerLowMax_constraint(asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { - long value; + unsigned long value; if(!sptr) { ASN__CTFAIL(app_key, td, sptr, @@ -427,7 +427,7 @@ CN_IntegerLowMax_constraint(asn_TYPE_descriptor_t *td, const void *sptr, return -1; } - value = *(const long *)sptr; + value = *(const unsigned long *)sptr; if((value >= 1)) { /* Constraint check succeeded */ @@ -455,6 +455,11 @@ static asn_per_constraints_t asn_PER_type_CN_IntegerLowMax_constr_1 GCC_NOTUSED /*** <<< STAT-DEFS [CN-IntegerLowMax] >>> ***/ +static const asn_INTEGER_specifics_t asn_SPC_CN_IntegerLowMax_specs_1 = { + 0, 0, 0, 0, 0, + 0, /* Native long size */ + 1 /* Unsigned representation */ +}; static const ber_tlv_tag_t asn_DEF_CN_IntegerLowMax_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; @@ -472,7 +477,7 @@ asn_TYPE_descriptor_t asn_DEF_CN_IntegerLowMax = { 0, /* No OER visible constraints */ &asn_PER_type_CN_IntegerLowMax_constr_1, 0, 0, /* No members */ - 0 /* No specifics */ + &asn_SPC_CN_IntegerLowMax_specs_1 /* Additional specs */ };