History

Make sizeof() be of type size_t

This matters when sizeof is directly used in arithmetic, ala "uintptr_t t; t &= -sizeof(long)" (for alignment). When sizeof isn't size_t (as it's specified to be) this masking will truncate the high bits of the uintptr_t object (if uintptr_t is larger than uint).

Michael Matz committed 14 years ago

Commit 718fd591 parent b068e294 files · +37 −4Browse files

Unified · Split

4 files
  1. libtcc.c +6 −0
  2. tcc.h +1 −1
  3. tccgen.c +14 −3
  4. tests/tcctest.c +16 −0
libtcc.c+6−0
@@ -745,6 +745,12 @@ static int tcc_compile(TCCState *s1) · 744 unmodified lines
745 char_pointer_type.t = VT_BYTE;745 char_pointer_type.t = VT_BYTE;
746 mk_pointer(&char_pointer_type);746 mk_pointer(&char_pointer_type);
747 747
748#if PTR_SIZE == 4
749 size_type.t = VT_INT;
750#else
751 size_type.t = VT_LLONG;
752#endif
753
748 func_old_type.t = VT_FUNC;754 func_old_type.t = VT_FUNC;
749 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);755 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
750 756
tcc.h+1−1
@@ -1117,7 +1117,7 @@ ST_DATA Sym *local_stack; · 1116 unmodified lines
1117ST_DATA Sym *local_label_stack;1117ST_DATA Sym *local_label_stack;
1118ST_DATA Sym *global_label_stack;1118ST_DATA Sym *global_label_stack;
1119ST_DATA Sym *define_stack;1119ST_DATA Sym *define_stack;
1120ST_DATA CType char_pointer_type, func_old_type, int_type;1120ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
1121ST_DATA SValue vstack[VSTACK_SIZE], *vtop;1121ST_DATA SValue vstack[VSTACK_SIZE], *vtop;
1122ST_DATA int rsym, anon_sym, ind, loc;1122ST_DATA int rsym, anon_sym, ind, loc;
1123 1123
tccgen.c+14−3
@@ -64,7 +64,7 @@ ST_DATA int func_vc; · 63 unmodified lines
64ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */64ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
65ST_DATA char *funcname;65ST_DATA char *funcname;
66 66
67ST_DATA CType char_pointer_type, func_old_type, int_type;67ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
68 68
69/* ------------------------------------------------------------------------- */69/* ------------------------------------------------------------------------- */
70static void gen_cast(CType *type);70static void gen_cast(CType *type);
@@ -325,6 +325,17 @@ ST_FUNC void vpushi(int v) · 254 unmodified lines
325 vsetc(&int_type, VT_CONST, &cval);325 vsetc(&int_type, VT_CONST, &cval);
326}326}
327 327
328/* push a pointer sized constant */
329static void vpushs(long long v)
330{
331 CValue cval;
332 if (PTR_SIZE == 4)
333 cval.i = (int)v;
334 else
335 cval.ull = v;
336 vsetc(&size_type, VT_CONST, &cval);
337}
338
328/* push long long constant */339/* push long long constant */
329static void vpushll(long long v)340static void vpushll(long long v)
330{341{
@@ -3575,12 +3586,12 @@ ST_FUNC void unary(void) · 3244 unmodified lines
3575 if (!(type.t & VT_VLA)) {3586 if (!(type.t & VT_VLA)) {
3576 if (size < 0)3587 if (size < 0)
3577 tcc_error("sizeof applied to an incomplete type");3588 tcc_error("sizeof applied to an incomplete type");
3578 vpushi(size);3589 vpushs(size);
3579 } else {3590 } else {
3580 vla_runtime_type_size(&type, &align);3591 vla_runtime_type_size(&type, &align);
3581 }3592 }
3582 } else {3593 } else {
3583 vpushi(align);3594 vpushs(align);
3584 }3595 }
3585 vtop->type.t |= VT_UNSIGNED;3596 vtop->type.t |= VT_UNSIGNED;
3586 break;3597 break;
tests/tcctest.c+16−0
@@ -2155,6 +2155,8 @@ void c99_vla_test(int size1, int size2) · 2154 unmodified lines
2155#endif2155#endif
2156}2156}
2157 2157
2158typedef __SIZE_TYPE__ uintptr_t;
2159
2158void sizeof_test(void)2160void sizeof_test(void)
2159{2161{
2160 int a;2162 int a;
@@ -2175,6 +2177,20 @@ void sizeof_test(void) · 14 unmodified lines
2175 ptr = NULL;2177 ptr = NULL;
2176 printf("sizeof(**ptr) = %d\n", sizeof (**ptr));2178 printf("sizeof(**ptr) = %d\n", sizeof (**ptr));
2177 2179
2180 /* The type of sizeof should be as large as a pointer, actually
2181 it should be size_t. */
2182 printf("sizeof(sizeof(int) = %d\n", sizeof(sizeof(int)));
2183 uintptr_t t = 1;
2184 uintptr_t t2;
2185 /* Effectively <<32, but defined also on 32bit machines. */
2186 t <<= 16;
2187 t <<= 16;
2188 t++;
2189 /* This checks that sizeof really can be used to manipulate
2190 uintptr_t objects, without truncation. */
2191 t2 = t & -sizeof(uintptr_t);
2192 printf ("%lu %lu\n", t, t2);
2193
2178 /* some alignof tests */2194 /* some alignof tests */
2179 printf("__alignof__(int) = %d\n", __alignof__(int));2195 printf("__alignof__(int) = %d\n", __alignof__(int));
2180 printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int));2196 printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int));