Commit 94b765a1 authored by Lev Walkin's avatar Lev Walkin

Merge branch 'master' of github.com:vlm/asn1c

parents b89b340e 3d6fcfec
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
*.lo *.lo
*.libs *.libs
*.deps *.deps
*.core
# / # /
/autom4te.cache /autom4te.cache
......
...@@ -14,6 +14,16 @@ static asn1p_expr_type_e _find_terminal_type(arg_t *arg); ...@@ -14,6 +14,16 @@ 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 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(asn1cnst_range_t *r); /* -1, 0, 1 */
static int
ulong_optimization(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);
}
int int
asn1c_emit_constraint_checking_code(arg_t *arg) { asn1c_emit_constraint_checking_code(arg_t *arg) {
asn1cnst_range_t *r_size; asn1cnst_range_t *r_size;
...@@ -24,6 +34,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) { ...@@ -24,6 +34,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
int got_something = 0; int got_something = 0;
int alphabet_table_compiled; int alphabet_table_compiled;
int produce_st = 0; int produce_st = 0;
int ulong_optimize = 0;
ct = expr->combined_constraints; ct = expr->combined_constraints;
if(ct == NULL) if(ct == NULL)
...@@ -93,7 +104,10 @@ asn1c_emit_constraint_checking_code(arg_t *arg) { ...@@ -93,7 +104,10 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
case ASN_BASIC_INTEGER: case ASN_BASIC_INTEGER:
case ASN_BASIC_ENUMERATED: case ASN_BASIC_ENUMERATED:
if(native_long_sign(r_value) >= 0) { if(native_long_sign(r_value) >= 0) {
ulong_optimize = ulong_optimization(etype, r_size, r_value);
if(!ulong_optimize) {
OUT("unsigned long value;\n"); OUT("unsigned long value;\n");
}
} else { } else {
OUT("long value;\n"); OUT("long value;\n");
} }
...@@ -124,7 +138,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) { ...@@ -124,7 +138,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
OUT("}\n"); OUT("}\n");
OUT("\n"); OUT("\n");
if(r_value) if((r_value) && (!ulong_optimize))
emit_value_determination_code(arg, etype, r_value); emit_value_determination_code(arg, etype, r_value);
if(r_size) if(r_size)
emit_size_determination_code(arg, etype); emit_size_determination_code(arg, etype);
...@@ -140,10 +154,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) { ...@@ -140,10 +154,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
/* /*
* Optimization for unsigned longs. * Optimization for unsigned longs.
*/ */
if(!r_size && r_value if(ulong_optimize) {
&& (etype == ASN_BASIC_INTEGER
|| etype == ASN_BASIC_ENUMERATED)
&& native_long_sign(r_value) == 0) {
OUT("\n"); OUT("\n");
OUT("/* Constraint check succeeded */\n"); OUT("/* Constraint check succeeded */\n");
OUT("return 0;\n"); OUT("return 0;\n");
......
...@@ -314,7 +314,8 @@ asn_GT2time_prec(const GeneralizedTime_t *st, int *frac_value, int frac_digits, ...@@ -314,7 +314,8 @@ asn_GT2time_prec(const GeneralizedTime_t *st, int *frac_value, int frac_digits,
while(fd > frac_digits) while(fd > frac_digits)
fv /= 10, fd--; fv /= 10, fd--;
while(fd < frac_digits) { while(fd < frac_digits) {
int new_fv = fv * 10; int volatile new_fv = fv * 10;
/* GCC 4.x is being too smart without volatile */
if(new_fv / 10 != fv) { if(new_fv / 10 != fv) {
/* Too long precision request */ /* Too long precision request */
fv = 0; fv = 0;
...@@ -441,7 +442,8 @@ asn_GT2time_frac(const GeneralizedTime_t *st, int *frac_value, int *frac_digits, ...@@ -441,7 +442,8 @@ asn_GT2time_frac(const GeneralizedTime_t *st, int *frac_value, int *frac_digits,
*/ */
for(buf++; buf < end; buf++) { for(buf++; buf < end; buf++) {
int v = *buf; int v = *buf;
int new_fvalue; int volatile new_fvalue;
/* GCC 4.x is being too smart without volatile */
switch(v) { switch(v) {
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
......
...@@ -339,6 +339,9 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun ...@@ -339,6 +339,9 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
ASN_DEBUG("INTEGER body %ld 0x%2x..0x%2x", ASN_DEBUG("INTEGER body %ld 0x%2x..0x%2x",
(long)chunk_size, *lstart, lstop[-1]); (long)chunk_size, *lstart, lstop[-1]);
if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
return XPBD_SYSTEM_FAILURE;
/* /*
* We may have received a tag here. It will be processed inline. * We may have received a tag here. It will be processed inline.
* Use strtoul()-like code and serialize the result. * Use strtoul()-like code and serialize the result.
...@@ -396,7 +399,9 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun ...@@ -396,7 +399,9 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
} }
{ {
long new_value = value * 10; long volatile new_value = value * 10;
/* GCC 4.x optimizes (new_value) without `volatile'
* so the following check does not detect overflow. */
if(new_value / 10 != value) if(new_value / 10 != value)
/* Overflow */ /* Overflow */
...@@ -445,8 +450,6 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun ...@@ -445,8 +450,6 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
* places as a decimal value. * places as a decimal value.
* Switch decoding mode. */ * Switch decoding mode. */
ASN_DEBUG("INTEGER re-evaluate as hex form"); ASN_DEBUG("INTEGER re-evaluate as hex form");
if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
return XPBD_SYSTEM_FAILURE;
state = ST_SKIPSPHEX; state = ST_SKIPSPHEX;
lp = lstart - 1; lp = lstart - 1;
continue; continue;
...@@ -474,8 +477,6 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun ...@@ -474,8 +477,6 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
continue; continue;
case ST_DIGITS: case ST_DIGITS:
ASN_DEBUG("INTEGER re-evaluate as hex form"); ASN_DEBUG("INTEGER re-evaluate as hex form");
if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
return XPBD_SYSTEM_FAILURE;
state = ST_SKIPSPHEX; state = ST_SKIPSPHEX;
lp = lstart - 1; lp = lstart - 1;
continue; continue;
......
...@@ -691,7 +691,8 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length, ...@@ -691,7 +691,8 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
value = 0; value = 0;
} }
if(1) { if(1) {
long new_value = value * 10; long volatile new_value = value * 10;
/* GCC 4.x is being too smart without volatile */
if(new_value / 10 != value if(new_value / 10 != value
|| (value = new_value + (*oid_text - 0x30)) < 0) { || (value = new_value + (*oid_text - 0x30)) < 0) {
/* Overflow */ /* Overflow */
......
...@@ -100,7 +100,6 @@ check_unsigned(uint8_t *buf, int size, unsigned long check_long, int check_ret) ...@@ -100,7 +100,6 @@ check_unsigned(uint8_t *buf, int size, unsigned long check_long, int check_ret)
printf(" (%lu, %d) vs (%lu, %d)\n", printf(" (%lu, %d) vs (%lu, %d)\n",
rlong, ret, check_long, check_ret); rlong, ret, check_long, check_ret);
assert(ret == check_ret); assert(ret == check_ret);
printf("%lu %lu\n", rlong, check_long);
assert(rlong == check_long); assert(rlong == check_long);
if(check_ret == 0) { if(check_ret == 0) {
...@@ -122,13 +121,13 @@ check_unsigned(uint8_t *buf, int size, unsigned long check_long, int check_ret) ...@@ -122,13 +121,13 @@ check_unsigned(uint8_t *buf, int size, unsigned long check_long, int check_ret)
assert(rlong == rlong2); assert(rlong == rlong2);
} }
return 0; return;
shared_scratch_start = scratch; shared_scratch_start = scratch;
ret = INTEGER_print(&asn_DEF_INTEGER, &val, 0, _print2buf, scratch); ret = INTEGER_print(&asn_DEF_INTEGER, &val, 0, _print2buf, scratch);
assert(shared_scratch_start < scratch + sizeof(scratch)); assert(shared_scratch_start < scratch + sizeof(scratch));
assert(ret == 0); assert(ret == 0);
ret = snprintf(verify, sizeof(verify), "%ld", check_long); ret = snprintf(verify, sizeof(verify), "%lu", check_long);
assert(ret < sizeof(verify)); assert(ret < sizeof(verify));
ret = strcmp(scratch, verify); ret = strcmp(scratch, verify);
printf(" [%s] vs [%s]: %d%s\n", printf(" [%s] vs [%s]: %d%s\n",
...@@ -208,8 +207,8 @@ main(int ac, char **av) { ...@@ -208,8 +207,8 @@ main(int ac, char **av) {
CHECK(buf12, -32768, 0); CHECK(buf12, -32768, 0);
CHECK(buf13, -128, 0); CHECK(buf13, -128, 0);
UCHECK(buf14, 0x800000, 0); UCHECK(buf14, 0x800000, 0);
UCHECK(buf15, 0x80000000, 0); UCHECK(buf15, 0x80000000UL, 0);
UCHECK(buf16, 0xffff0000, 0); UCHECK(buf16, 0xffff0000UL, 0);
check_xer(-1, "", 0); check_xer(-1, "", 0);
check_xer(-1, "<INTEGER></INTEGER>", 0); check_xer(-1, "<INTEGER></INTEGER>", 0);
...@@ -240,6 +239,8 @@ main(int ac, char **av) { ...@@ -240,6 +239,8 @@ main(int ac, char **av) {
check_xer(0, "<INTEGER>+2147483647</INTEGER>", 2147483647); check_xer(0, "<INTEGER>+2147483647</INTEGER>", 2147483647);
check_xer(0, "<INTEGER>2147483647</INTEGER>", 2147483647); check_xer(0, "<INTEGER>2147483647</INTEGER>", 2147483647);
if(sizeof(long) == 4) { if(sizeof(long) == 4) {
check_xer( 0, "<INTEGER>-2147483648</INTEGER>", -2147483648);
check_xer(-1, "<INTEGER>-2147483649</INTEGER>", 0);
check_xer(-1, "<INTEGER>2147483648</INTEGER>", 0); check_xer(-1, "<INTEGER>2147483648</INTEGER>", 0);
check_xer(-1, "<INTEGER>2147483649</INTEGER>", 0); check_xer(-1, "<INTEGER>2147483649</INTEGER>", 0);
check_xer(-1, "<INTEGER>3147483649</INTEGER>", 0); check_xer(-1, "<INTEGER>3147483649</INTEGER>", 0);
...@@ -247,6 +248,30 @@ main(int ac, char **av) { ...@@ -247,6 +248,30 @@ main(int ac, char **av) {
check_xer(-1, "<INTEGER>5147483649</INTEGER>", 0); /* special */ check_xer(-1, "<INTEGER>5147483649</INTEGER>", 0); /* special */
check_xer(-1, "<INTEGER>9147483649</INTEGER>", 0); check_xer(-1, "<INTEGER>9147483649</INTEGER>", 0);
check_xer(-1, "<INTEGER>9999999999</INTEGER>", 0); check_xer(-1, "<INTEGER>9999999999</INTEGER>", 0);
check_xer(-1, "<INTEGER>-5147483649</INTEGER>", 0);/* special */
check_xer(-1, "<INTEGER>-9147483649</INTEGER>", 0);
check_xer(-1, "<INTEGER>-9999999999</INTEGER>", 0);
}
if(sizeof(long) == 8) {
check_xer(0, "<INTEGER>2147483648</INTEGER>", 2147483648);
check_xer(0, "<INTEGER>2147483649</INTEGER>", 2147483649);
check_xer(0, "<INTEGER>3147483649</INTEGER>", 3147483649);
check_xer(0, "<INTEGER>4147483649</INTEGER>", 4147483649);
check_xer(0, "<INTEGER>5147483649</INTEGER>", 5147483649);
check_xer(0, "<INTEGER>9147483649</INTEGER>", 9147483649);
check_xer(0, "<INTEGER>9999999999</INTEGER>", 9999999999);
check_xer(0, "<INTEGER>9223372036854775807</INTEGER>", 9223372036854775807);
check_xer(-1, "<INTEGER>9223372036854775808</INTEGER>", 0);
check_xer(-1, "<INTEGER>10223372036854775807</INTEGER>", 0);
check_xer(-1, "<INTEGER>50223372036854775807</INTEGER>", 0);
check_xer(-1, "<INTEGER>100223372036854775807</INTEGER>", 0);
check_xer(-1, "<INTEGER>500223372036854775807</INTEGER>", 0);
check_xer(0, "<INTEGER>-9223372036854775808</INTEGER>", -9223372036854775808);
check_xer(-1, "<INTEGER>-9223372036854775809</INTEGER>", 0);
check_xer(-1, "<INTEGER>-10223372036854775807</INTEGER>", 0);
check_xer(-1, "<INTEGER>-50223372036854775807</INTEGER>", 0);
check_xer(-1, "<INTEGER>-100223372036854775807</INTEGER>", 0);
check_xer(-1, "<INTEGER>-500223372036854775807</INTEGER>", 0);
} }
return 0; return 0;
......
...@@ -400,13 +400,16 @@ main() { ...@@ -400,13 +400,16 @@ main() {
check_parse("1.2147483647.3", 3); check_parse("1.2147483647.3", 3);
if(sizeof(long) == 4) { if(sizeof(long) == 4) {
check_parse("1.2147483648.3", -1); /* overflow on ILP32 */ check_parse("1.2147483648.3", -1); /* overflow on ILP32 */
check_parse("1.2147483649.3", -1); /* overflow on ILP32 */
check_parse("1.3000000000.3", -1); check_parse("1.3000000000.3", -1);
check_parse("1.4000000000.3", -1); check_parse("1.4000000000.3", -1);
check_parse("1.5000000000.3", -1); check_parse("1.5000000000.3", -1);
check_parse("1.6000000000.3", -1); check_parse("1.6000000000.3", -1);
check_parse("1.9000000000.3", -1); check_parse("1.9000000000.3", -1);
} else { } else if(sizeof(long) == 8) {
check_parse("1.2147483648.3", 3); check_parse("1.2147483648.3", 3);
check_parse("1.9223372036854775807.3", 3);
check_parse("1.9223372036854775808.3", -1);
} }
check_parse("1.900a0000000.3", -1); check_parse("1.900a0000000.3", -1);
check_parse("1.900a.3", -1); check_parse("1.900a.3", -1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment