aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libtcc.c6
-rw-r--r--tcc.h2
-rw-r--r--tccgen.c17
-rw-r--r--tests/tcctest.c16
4 files changed, 37 insertions, 4 deletions
diff --git a/libtcc.c b/libtcc.c
index c6b8d38..01280de 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -745,6 +745,12 @@ static int tcc_compile(TCCState *s1)
char_pointer_type.t = VT_BYTE;
mk_pointer(&char_pointer_type);
+#if PTR_SIZE == 4
+ size_type.t = VT_INT;
+#else
+ size_type.t = VT_LLONG;
+#endif
+
func_old_type.t = VT_FUNC;
func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
diff --git a/tcc.h b/tcc.h
index 95d5030..a674f92 100644
--- a/tcc.h
+++ b/tcc.h
@@ -1117,7 +1117,7 @@ ST_DATA Sym *local_stack;
ST_DATA Sym *local_label_stack;
ST_DATA Sym *global_label_stack;
ST_DATA Sym *define_stack;
-ST_DATA CType char_pointer_type, func_old_type, int_type;
+ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
ST_DATA SValue vstack[VSTACK_SIZE], *vtop;
ST_DATA int rsym, anon_sym, ind, loc;
diff --git a/tccgen.c b/tccgen.c
index 6031611..36a1879 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -64,7 +64,7 @@ ST_DATA int func_vc;
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
ST_DATA char *funcname;
-ST_DATA CType char_pointer_type, func_old_type, int_type;
+ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
/* ------------------------------------------------------------------------- */
static void gen_cast(CType *type);
@@ -325,6 +325,17 @@ ST_FUNC void vpushi(int v)
vsetc(&int_type, VT_CONST, &cval);
}
+/* push a pointer sized constant */
+static void vpushs(long long v)
+{
+ CValue cval;
+ if (PTR_SIZE == 4)
+ cval.i = (int)v;
+ else
+ cval.ull = v;
+ vsetc(&size_type, VT_CONST, &cval);
+}
+
/* push long long constant */
static void vpushll(long long v)
{
@@ -3575,12 +3586,12 @@ ST_FUNC void unary(void)
if (!(type.t & VT_VLA)) {
if (size < 0)
tcc_error("sizeof applied to an incomplete type");
- vpushi(size);
+ vpushs(size);
} else {
vla_runtime_type_size(&type, &align);
}
} else {
- vpushi(align);
+ vpushs(align);
}
vtop->type.t |= VT_UNSIGNED;
break;
diff --git a/tests/tcctest.c b/tests/tcctest.c
index eeabb7c..9598fa4 100644
--- a/tests/tcctest.c
+++ b/tests/tcctest.c
@@ -2155,6 +2155,8 @@ void c99_vla_test(int size1, int size2)
#endif
}
+typedef __SIZE_TYPE__ uintptr_t;
+
void sizeof_test(void)
{
int a;
@@ -2175,6 +2177,20 @@ void sizeof_test(void)
ptr = NULL;
printf("sizeof(**ptr) = %d\n", sizeof (**ptr));
+ /* The type of sizeof should be as large as a pointer, actually
+ it should be size_t. */
+ printf("sizeof(sizeof(int) = %d\n", sizeof(sizeof(int)));
+ uintptr_t t = 1;
+ uintptr_t t2;
+ /* Effectively <<32, but defined also on 32bit machines. */
+ t <<= 16;
+ t <<= 16;
+ t++;
+ /* This checks that sizeof really can be used to manipulate
+ uintptr_t objects, without truncation. */
+ t2 = t & -sizeof(uintptr_t);
+ printf ("%lu %lu\n", t, t2);
+
/* some alignof tests */
printf("__alignof__(int) = %d\n", __alignof__(int));
printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int));