Opened 10 hours ago

Last modified 9 hours ago

#1847 new defect

integer overflow when running 6.0.0pre1 tests (2)

Reported by: zerica Owned by:
Priority: major Milestone: someday
Component: unknown Version: 6.0.0
Keywords: Cc:
Estimated difficulty: medium

Description

similarly to the previous ticket, i'm building chicken with the clang integer ub sanitizers, which also trap here:

Can hold maximum value 9223372036854775807...
Can hold minimum value -9223372036854775808...

Error: illegal instruction

	Call history:

	compiler-tests.scm:352: g1093	  
	compiler-tests.scm:352: chicken.base#print	  
	compiler-tests.scm:352: scheme#call-with-current-continuation	  
	compiler-tests.scm:352: chicken.condition#with-exception-handler	  
	compiler-tests.scm:352: ##sys#call-with-values	  
	compiler-tests.scm:352: k1108	  
	compiler-tests.scm:352: g1111	  
	compiler-tests.scm:352: chicken.base#print	  
	compiler-tests.scm:352: scheme#call-with-current-continuation	  
	compiler-tests.scm:352: chicken.condition#with-exception-handler	  
	compiler-tests.scm:352: ##sys#call-with-values	  
	compiler-tests.scm:352: k1126	  
	compiler-tests.scm:352: g1129	  
	compiler-tests.scm:353: chicken.base#print	  
	compiler-tests.scm:353: chicken.base#print	  
	compiler-tests.scm:353: chicken.base#print	  	<--
make: *** [rules.make:1017: check] Error 70

this is right before the test code attempts to confirm the c variables can't take a value outside their bounds. i'm not sure where exactly the code that checks whether an integer is representable in a 64 bit c variable lives, but it seems to trigger the overflow before checking whether the operation is actually valid. if so, that would be ub and therefore unsound

Change History (2)

comment:1 Changed 10 hours ago by zerica

linking the full ubsan runtime yields more information:

Can hold maximum value 9223372036854775807...
Can hold minimum value -9223372036854775808...
chicken.h:2759:39: runtime error: negation of -9223372036854775808 cannot be represented in type 'long'; cast to an unsigned type to negate this value to itself
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior chicken.h:2759:39 

so the ub seems to occur in this function

inline static C_long C_num_to_long(C_word x)
{
  if(x & C_FIXNUM_BIT) {
    return (C_long)C_unfix(x);
  } else {
    if (C_bignum_negativep(x)) return -(C_long)C_bignum_digits(x)[0];
    else return (C_long)C_bignum_digits(x)[0];
  }
}

where -(C_long)x is unsound when x is INT64_MIN

Last edited 9 hours ago by zerica (previous) (diff)

comment:2 Changed 9 hours ago by zerica

hm, no, i mightve been wrong here. this was logged before:

chicken.h:2622:17: runtime error: implicit conversion from type 'unsigned long' of value 9223372036854775808 (64-bit, unsigned) to type 'int64_t' (aka 'long') changed the value to -9223372036854775808 (64-bit, signed)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior chicken.h:2622:17 

which points to C_s64 num = C_bignum_digits(x)[0]; in

inline static C_s64 C_num_to_int64(C_word x)
{
  if(x & C_FIXNUM_BIT) {
    return (C_s64)C_unfix(x);
  } else {
    C_s64 num = C_bignum_digits(x)[0];
#ifndef C_SIXTY_FOUR
    if (C_bignum_size(x) > 1) num |= (C_s64)(((C_u64)C_bignum_digits(x)[1]) << 32);
#endif
    if (C_bignum_negativep(x)) return -num;
    else return num;
  }
}
Note: See TracTickets for help on using tickets.