windelbouwman / ppci

A compiler for ARM, X86, MSP430, xtensa and more implemented in pure Python
https://ppci.readthedocs.io/en/latest/
BSD 2-Clause "Simplified" License
335 stars 35 forks source link

ppci-cc: handling of big constants with L specifier #94

Open tstreiff opened 4 years ago

tstreiff commented 4 years ago

In x86_64, ints are 32bit and longs are 64bit.

long l1 = 9223372036854775807; // LONG_MAX long l2 = -9223372036854775808; // LONG_MIN long l3 = -9223372036854775808L; // same value but... ^ Integer value too big for type (9223372036854775807)

The value is OK for an "int" constant (with no type specifier) but is too big for a "long" constant (L type specifier)

tstreiff commented 4 years ago

This is checked in semantics.py/on_number() The subtle point is that integer constants are always positive, so this function does not know if a sign has been found just before. And the maximum absolute value is not the same for negative et positive values.

According to the C standard, the "L" specifiers implies "long int" or "long long int" (the 1st of the two large enough to hold the value) A possible fix for integers would be: 1) We let the compiler find the shortest type suitable for the value 2) If a specifier is given, we "upgrade" the type found in 1) I am not sure step 2) is really necessary because type of integer constants is rarely used (their type is adjusted on demand) An exception is passing a constant to a "old-style" (ie K&R) function: specifying the type of a constant in a function call can help the compiler choose how to put it on the stack (on an architecture where ints are 16bit and longs are 32bit, passing 0 requires one level of stack, whereas passing 0L requires two)