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

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

parents b89b340e 3d6fcfec
......@@ -3,6 +3,7 @@
*.lo
*.libs
*.deps
*.core
# /
/autom4te.cache
......
......@@ -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 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
asn1c_emit_constraint_checking_code(arg_t *arg) {
asn1cnst_range_t *r_size;
......@@ -24,6 +34,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
int got_something = 0;
int alphabet_table_compiled;
int produce_st = 0;
int ulong_optimize = 0;
ct = expr->combined_constraints;
if(ct == NULL)
......@@ -93,7 +104,10 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
case ASN_BASIC_INTEGER:
case ASN_BASIC_ENUMERATED:
if(native_long_sign(r_value) >= 0) {
OUT("unsigned long value;\n");
ulong_optimize = ulong_optimization(etype, r_size, r_value);
if(!ulong_optimize) {
OUT("unsigned long value;\n");
}
} else {
OUT("long value;\n");
}
......@@ -124,7 +138,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
OUT("}\n");
OUT("\n");
if(r_value)
if((r_value) && (!ulong_optimize))
emit_value_determination_code(arg, etype, r_value);
if(r_size)
emit_size_determination_code(arg, etype);
......@@ -140,10 +154,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
/*
* Optimization for unsigned longs.
*/
if(!r_size && r_value
&& (etype == ASN_BASIC_INTEGER
|| etype == ASN_BASIC_ENUMERATED)
&& native_long_sign(r_value) == 0) {
if(ulong_optimize) {
OUT("\n");
OUT("/* Constraint check succeeded */\n");
OUT("return 0;\n");
......
......@@ -314,7 +314,8 @@ asn_GT2time_prec(const GeneralizedTime_t *st, int *frac_value, int frac_digits,
while(fd > frac_digits)
fv /= 10, fd--;
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) {
/* Too long precision request */
fv = 0;
......@@ -441,7 +442,8 @@ asn_GT2time_frac(const GeneralizedTime_t *st, int *frac_value, int *frac_digits,
*/
for(buf++; buf < end; buf++) {
int v = *buf;
int new_fvalue;
int volatile new_fvalue;
/* GCC 4.x is being too smart without volatile */
switch(v) {
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
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
ASN_DEBUG("INTEGER body %ld 0x%2x..0x%2x",
(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.
* 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
}
{
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)
/* Overflow */
......@@ -445,8 +450,6 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
* places as a decimal value.
* Switch decoding mode. */
ASN_DEBUG("INTEGER re-evaluate as hex form");
if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
return XPBD_SYSTEM_FAILURE;
state = ST_SKIPSPHEX;
lp = lstart - 1;
continue;
......@@ -474,8 +477,6 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
continue;
case ST_DIGITS:
ASN_DEBUG("INTEGER re-evaluate as hex form");
if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
return XPBD_SYSTEM_FAILURE;
state = ST_SKIPSPHEX;
lp = lstart - 1;
continue;
......
......@@ -691,7 +691,8 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
value = 0;
}
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
|| (value = new_value + (*oid_text - 0x30)) < 0) {
/* Overflow */
......
......@@ -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",
rlong, ret, check_long, check_ret);
assert(ret == check_ret);
printf("%lu %lu\n", rlong, check_long);
assert(rlong == check_long);
if(check_ret == 0) {
......@@ -122,13 +121,13 @@ check_unsigned(uint8_t *buf, int size, unsigned long check_long, int check_ret)
assert(rlong == rlong2);
}
return 0;
return;
shared_scratch_start = scratch;
ret = INTEGER_print(&asn_DEF_INTEGER, &val, 0, _print2buf, scratch);
assert(shared_scratch_start < scratch + sizeof(scratch));
assert(ret == 0);
ret = snprintf(verify, sizeof(verify), "%ld", check_long);
ret = snprintf(verify, sizeof(verify), "%lu", check_long);
assert(ret < sizeof(verify));
ret = strcmp(scratch, verify);
printf(" [%s] vs [%s]: %d%s\n",
......@@ -208,8 +207,8 @@ main(int ac, char **av) {
CHECK(buf12, -32768, 0);
CHECK(buf13, -128, 0);
UCHECK(buf14, 0x800000, 0);
UCHECK(buf15, 0x80000000, 0);
UCHECK(buf16, 0xffff0000, 0);
UCHECK(buf15, 0x80000000UL, 0);
UCHECK(buf16, 0xffff0000UL, 0);
check_xer(-1, "", 0);
check_xer(-1, "<INTEGER></INTEGER>", 0);
......@@ -240,6 +239,8 @@ main(int ac, char **av) {
check_xer(0, "<INTEGER>+2147483647</INTEGER>", 2147483647);
check_xer(0, "<INTEGER>2147483647</INTEGER>", 2147483647);
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>2147483649</INTEGER>", 0);
check_xer(-1, "<INTEGER>3147483649</INTEGER>", 0);
......@@ -247,6 +248,30 @@ main(int ac, char **av) {
check_xer(-1, "<INTEGER>5147483649</INTEGER>", 0); /* special */
check_xer(-1, "<INTEGER>9147483649</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;
......
......@@ -400,13 +400,16 @@ main() {
check_parse("1.2147483647.3", 3);
if(sizeof(long) == 4) {
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.4000000000.3", -1);
check_parse("1.5000000000.3", -1);
check_parse("1.6000000000.3", -1);
check_parse("1.9000000000.3", -1);
} else {
} else if(sizeof(long) == 8) {
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.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