freebasic / fbfrog

FreeBASIC binding creation tool
Other
34 stars 17 forks source link

Cast necessary after integer promotion sometimes omitted #3

Open rversteegen opened 3 years ago

rversteegen commented 3 years ago
typedef unsigned int jit_uint;
#define jit_label_undefined ((size_t)~((jit_uint)0))

(which has value 4294967295 on both x86-linux and x86_64-linux) is translated by fbfrog (latest git head) to

type jit_uint as ulong
#define jit_label_undefined cuint(not cast(jit_uint, 0))

which has value 4294967295 on x86-linux and 18446744073709551615 on x86_64-linux.

On the other hand

#define jit_label_undefined ((size_t)~((unsigned int)0))

translates to

const jit_label_undefined = cuint(culng(not culng(0)))

which has the correct value, 4294967295, on x86 and x86_64.

The double casts are necessary to paper over the difference in integer promotion rules between FB and C (which promote to integer and int respectively).

rversteegen commented 3 years ago

Another example:

#define jit_min_int     (((int)1) << (sizeof(int) * 8 - 1))

In C this evaluates to -2147483648 on x86/x86_86-linux, but fbfrog translates to

#define jit_min_int3 (clng(1) shl ((sizeof(long) * 8) - 1))

which is -2147483648 on x86 but 2147483648 on x86_64; the type is integer in both cases.

dkl commented 3 years ago

Looks like the typedef cast is what breaks it, this seems to work:

#define jit_label_undefined2    ((size_t)~((unsigned int)0))
const jit_label_undefined2 = cuint(culng(not culng(0)))
dkl commented 3 years ago

Potential fix in fe043a7a, but there are some side-effects which might require some testing with real bindings first. Also I'm pretty sure there are more missing cases, so if there's anything easy & obvious, it can probably be fixed aswell.