History

be stricter with aliasing

Refactoring (no logical changes): - use memcpy in tccgen.c:ieee_finite(double d) - use union to store attribute flags in Sym Makefile: "CFLAGS+=-fno-strict-aliasing" basically not necessary anymore but I left it for now because gcc sometimes behaves unexpectedly without. Also: - configure: back to mode 100755 - tcc.h: remove unused variables tdata/tbss_section - x86_64-gen.c: adjust gfunc_sret for prototype

grischka committed 12 years ago

Commit 3fe2a951 parent 2bd0daa6 files · +92 −89Browse files

Unified · Split

6 files
  1. configure +0 −0
  2. i386-gen.c +2 −2
  3. libtcc.c +4 −4
  4. tcc.h +26 −31
  5. tccgen.c +50 −47
  6. x86_64-gen.c +10 −5
configure+0−0

File mode changed from 100644 to 100755.

i386-gen.c+2−2
@@ -457,7 +457,7 @@ ST_FUNC void gfunc_call(int nb_args) · 456 unmodified lines
457457 }
458458 save_regs(0); /* save used temporary registers */
459459 func_sym = vtop->type.ref;
460− func_call = FUNC_CALL(func_sym->r);
460+ func_call = func_sym->a.func_call;
461461 /* fast call case */
462462 if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
463463 func_call == FUNC_FASTCALLW) {
@@ -505,7 +505,7 @@ ST_FUNC void gfunc_prolog(CType *func_type) · 41 unmodified lines
505505 CType *type;
506506
507507 sym = func_type->ref;
508− func_call = FUNC_CALL(sym->r);
508+ func_call = sym->a.func_call;
509509 addr = 8;
510510 loc = 0;
511511 func_vc = 0;
libtcc.c+4−4
@@ -493,11 +493,11 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, · 492 unmodified lines
493493 if (sym->type.t & VT_EXPORT)
494494 other |= 1;
495495 if (sym_type == STT_FUNC && sym->type.ref) {
496− int attr = sym->type.ref->r;
497− if (FUNC_EXPORT(attr))
496+ Sym *ref = sym->type.ref;
497+ if (ref->a.func_export)
498498 other |= 1;
499− if (FUNC_CALL(attr) == FUNC_STDCALL && can_add_underscore) {
500− sprintf(buf1, "_%s@%d", name, FUNC_ARGS(attr) * PTR_SIZE);
499+ if (ref->a.func_call == FUNC_STDCALL && can_add_underscore) {
500+ sprintf(buf1, "_%s@%d", name, ref->a.func_args * PTR_SIZE);
501501 name = buf1;
502502 other |= 2;
503503 can_add_underscore = 0;
tcc.h+26−31
@@ -326,11 +326,35 @@ typedef struct SValue { · 325 unmodified lines
326326 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
327327 } SValue;
328328
329+struct Attribute {
330+ unsigned
331+ func_call : 3, /* calling convention (0..5), see below */
332+ aligned : 5, /* alignement (0..16) */
333+ packed : 1,
334+ func_export : 1,
335+ func_import : 1,
336+ func_args : 5,
337+ func_proto : 1,
338+ mode : 4,
339+ weak : 1,
340+ fill : 10; // 10 bits left to fit well in union below
341+};
342+
343+/* GNUC attribute definition */
344+typedef struct AttributeDef {
345+ struct Attribute a;
346+ struct Section *section;
347+ int alias_target; /* token */
348+} AttributeDef;
349+
329350 /* symbol management */
330351 typedef struct Sym {
331352 int v; /* symbol token */
332353 char *asm_label; /* associated asm label */
333− long r; /* associated register */
354+ union {
355+ long r; /* associated register */
356+ struct Attribute a;
357+ };
334358 union {
335359 long c; /* associated number */
336360 int *d; /* define token stream */
@@ -381,34 +405,6 @@ typedef struct DLLReference { · 44 unmodified lines
381405 char name[1];
382406 } DLLReference;
383407
384−/* GNUC attribute definition */
385−typedef struct AttributeDef {
386− unsigned
387− func_call : 3, /* calling convention (0..5), see below */
388− aligned : 5, /* alignement (0..16) */
389− packed : 1,
390− func_export : 1,
391− func_import : 1,
392− func_args : 5,
393− func_proto : 1,
394− mode : 4,
395− weak : 1,
396− fill : 10;
397− struct Section *section;
398− int alias_target; /* token */
399−} AttributeDef;
400−
401−/* gr: wrappers for casting sym->r for other purposes */
402−#define FUNC_CALL(r) (((AttributeDef*)&(r))->func_call)
403−#define FUNC_EXPORT(r) (((AttributeDef*)&(r))->func_export)
404−#define FUNC_IMPORT(r) (((AttributeDef*)&(r))->func_import)
405−#define FUNC_ARGS(r) (((AttributeDef*)&(r))->func_args)
406−#define FUNC_PROTO(r) (((AttributeDef*)&(r))->func_proto)
407−#define FUNC_ALIGN(r) (((AttributeDef*)&(r))->aligned)
408−#define FUNC_PACKED(r) (((AttributeDef*)&(r))->packed)
409−#define ATTR_MODE(r) (((AttributeDef*)&(r))->mode)
410−#define INT_ATTR(ad) (*(int*)(ad))
411−
412408 /* -------------------------------------------------- */
413409
414410 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
@@ -1142,7 +1138,6 @@ ST_FUNC void expect(const char *msg); · 727 unmodified lines
11421138 /* ------------ tccgen.c ------------ */
11431139
11441140 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
1145−ST_DATA Section *tdata_section, *tbss_section; /* thread-local storage sections */
11461141 ST_DATA Section *cur_text_section; /* current section where function code is generated */
11471142 #ifdef CONFIG_TCC_ASM
11481143 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
@@ -1268,7 +1263,7 @@ ST_FUNC void build_got_entries(TCCState *s1); · 119 unmodified lines
12681263 ST_FUNC void tcc_add_runtime(TCCState *s1);
12691264
12701265 ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err);
1271−#ifdef TCC_IS_NATIVE
1266+#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
12721267 ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
12731268 #endif
12741269
tccgen.c+50−47
@@ -103,7 +103,8 @@ ST_INLN int is_float(int t) · 102 unmodified lines
103103 /* XXX: endianness dependent */
104104 ST_FUNC int ieee_finite(double d)
105105 {
106− int *p = (int *)&d;
106+ int p[4];
107+ memcpy(p, &d, sizeof(double));
107108 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
108109 }
109110
@@ -2172,7 +2173,7 @@ static int is_compatible_func(CType *type1, CType *type2) · 2062 unmodified lines
21722173 if (!is_compatible_types(&s1->type, &s2->type))
21732174 return 0;
21742175 /* check func_call */
2175− if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2176+ if (s1->a.func_call != s2->a.func_call)
21762177 return 0;
21772178 /* XXX: not complete */
21782179 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
@@ -2659,15 +2660,15 @@ static void parse_attribute(AttributeDef *ad) · 480 unmodified lines
26592660 } else {
26602661 n = MAX_ALIGN;
26612662 }
2662− ad->aligned = n;
2663+ ad->a.aligned = n;
26632664 break;
26642665 case TOK_PACKED1:
26652666 case TOK_PACKED2:
2666− ad->packed = 1;
2667+ ad->a.packed = 1;
26672668 break;
26682669 case TOK_WEAK1:
26692670 case TOK_WEAK2:
2670− ad->weak = 1;
2671+ ad->a.weak = 1;
26712672 break;
26722673 case TOK_UNUSED1:
26732674 case TOK_UNUSED2:
@@ -2682,12 +2683,12 @@ static void parse_attribute(AttributeDef *ad) · 8 unmodified lines
26822683 case TOK_CDECL1:
26832684 case TOK_CDECL2:
26842685 case TOK_CDECL3:
2685− ad->func_call = FUNC_CDECL;
2686+ ad->a.func_call = FUNC_CDECL;
26862687 break;
26872688 case TOK_STDCALL1:
26882689 case TOK_STDCALL2:
26892690 case TOK_STDCALL3:
2690− ad->func_call = FUNC_STDCALL;
2691+ ad->a.func_call = FUNC_STDCALL;
26912692 break;
26922693 #ifdef TCC_TARGET_I386
26932694 case TOK_REGPARM1:
@@ -2699,26 +2700,26 @@ static void parse_attribute(AttributeDef *ad) · 5 unmodified lines
26992700 else if (n < 0)
27002701 n = 0;
27012702 if (n > 0)
2702− ad->func_call = FUNC_FASTCALL1 + n - 1;
2703+ ad->a.func_call = FUNC_FASTCALL1 + n - 1;
27032704 skip(')');
27042705 break;
27052706 case TOK_FASTCALL1:
27062707 case TOK_FASTCALL2:
27072708 case TOK_FASTCALL3:
2708− ad->func_call = FUNC_FASTCALLW;
2709+ ad->a.func_call = FUNC_FASTCALLW;
27092710 break;
27102711 #endif
27112712 case TOK_MODE:
27122713 skip('(');
27132714 switch(tok) {
27142715 case TOK_MODE_DI:
2715− ad->mode = VT_LLONG + 1;
2716+ ad->a.mode = VT_LLONG + 1;
27162717 break;
27172718 case TOK_MODE_HI:
2718− ad->mode = VT_SHORT + 1;
2719+ ad->a.mode = VT_SHORT + 1;
27192720 break;
27202721 case TOK_MODE_SI:
2721− ad->mode = VT_INT + 1;
2722+ ad->a.mode = VT_INT + 1;
27222723 break;
27232724 default:
27242725 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
@@ -2728,10 +2729,10 @@ static void parse_attribute(AttributeDef *ad) · 3 unmodified lines
27282729 skip(')');
27292730 break;
27302731 case TOK_DLLEXPORT:
2731− ad->func_export = 1;
2732+ ad->a.func_export = 1;
27322733 break;
27332734 case TOK_DLLIMPORT:
2734− ad->func_import = 1;
2735+ ad->a.func_import = 1;
27352736 break;
27362737 default:
27372738 if (tcc_state->warn_unsupported)
@@ -2873,10 +2874,10 @@ static void struct_decl(CType *type, int u, int tdef) · 135 unmodified lines
28732874 get_tok_str(v, NULL));
28742875 }
28752876 size = type_size(&type1, &align);
2876− if (ad.aligned) {
2877− if (align < ad.aligned)
2878− align = ad.aligned;
2879− } else if (ad.packed) {
2877+ if (ad.a.aligned) {
2878+ if (align < ad.a.aligned)
2879+ align = ad.a.aligned;
2880+ } else if (ad.a.packed) {
28802881 align = 1;
28812882 } else if (*tcc_state->pack_stack_ptr) {
28822883 if (align > *tcc_state->pack_stack_ptr)
@@ -3118,8 +3119,8 @@ static int parse_btype(CType *type, AttributeDef *ad) · 235 unmodified lines
31183119 case TOK_ATTRIBUTE1:
31193120 case TOK_ATTRIBUTE2:
31203121 parse_attribute(ad);
3121− if (ad->mode) {
3122− u = ad->mode -1;
3122+ if (ad->a.mode) {
3123+ u = ad->a.mode -1;
31233124 t = (t & ~VT_BTYPE) | u;
31243125 }
31253126 break;
@@ -3143,11 +3144,11 @@ static int parse_btype(CType *type, AttributeDef *ad) · 17 unmodified lines
31433144 type->ref = s->type.ref;
31443145 if (s->r) {
31453146 /* get attributes from typedef */
3146− if (0 == ad->aligned)
3147− ad->aligned = FUNC_ALIGN(s->r);
3148− if (0 == ad->func_call)
3149− ad->func_call = FUNC_CALL(s->r);
3150− ad->packed |= FUNC_PACKED(s->r);
3147+ if (0 == ad->a.aligned)
3148+ ad->a.aligned = s->a.aligned;
3149+ if (0 == ad->a.func_call)
3150+ ad->a.func_call = s->a.func_call;
3151+ ad->a.packed |= s->a.packed;
31513152 }
31523153 next();
31533154 typespec_found = 1;
@@ -3287,8 +3288,9 @@ static void post_type(CType *type, AttributeDef *ad) · 133 unmodified lines
32873288 type->t |= VT_PTR;
32883289 }
32893290 /* we push a anonymous symbol which will contain the function prototype */
3290− ad->func_args = arg_size;
3291− s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3291+ ad->a.func_args = arg_size;
3292+ s = sym_push(SYM_FIELD, type, 0, l);
3293+ s->a = ad->a;
32923294 s->next = first;
32933295 type->t = VT_FUNC;
32943296 type->ref = s;
@@ -5484,10 +5486,10 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 2189 unmodified lines
54845486 if (flexible_array)
54855487 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
54865488 /* take into account specified alignment if bigger */
5487− if (ad->aligned) {
5488− if (ad->aligned > align)
5489− align = ad->aligned;
5490− } else if (ad->packed) {
5489+ if (ad->a.aligned) {
5490+ if (ad->a.aligned > align)
5491+ align = ad->a.aligned;
5492+ } else if (ad->a.packed) {
54915493 align = 1;
54925494 }
54935495 if ((r & VT_VALMASK) == VT_LOCAL) {
@@ -5869,12 +5871,12 @@ static int decl0(int l, int is_for_loop_init) · 375 unmodified lines
58695871 parse_attribute(&ad);
58705872 }
58715873
5872− if (ad.weak)
5874+ if (ad.a.weak)
58735875 type.t |= VT_WEAK;
58745876 #ifdef TCC_TARGET_PE
5875− if (ad.func_import)
5877+ if (ad.a.func_import)
58765878 type.t |= VT_IMPORT;
5877− if (ad.func_export)
5879+ if (ad.a.func_export)
58785880 type.t |= VT_EXPORT;
58795881 #endif
58805882 if (tok == '{') {
@@ -5895,22 +5897,22 @@ static int decl0(int l, int is_for_loop_init) · 14 unmodified lines
58955897
58965898 sym = sym_find(v);
58975899 if (sym) {
5900+ Sym *ref;
58985901 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
58995902 goto func_error1;
59005903
5901− r = sym->type.ref->r;
5902−
5903− if (!FUNC_PROTO(r))
5904+ ref = sym->type.ref;
5905+ if (0 == ref->a.func_proto)
59045906 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
59055907
59065908 /* use func_call from prototype if not defined */
5907− if (FUNC_CALL(r) != FUNC_CDECL
5908− && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5909− FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5909+ if (ref->a.func_call != FUNC_CDECL
5910+ && type.ref->a.func_call == FUNC_CDECL)
5911+ type.ref->a.func_call = ref->a.func_call;
59105912
59115913 /* use export from prototype */
5912− if (FUNC_EXPORT(r))
5913− FUNC_EXPORT(type.ref->r) = 1;
5914+ if (ref->a.func_export)
5915+ type.ref->a.func_export = 1;
59145916
59155917 /* use static from prototype */
59165918 if (sym->type.t & VT_STATIC)
@@ -5921,7 +5923,7 @@ static int decl0(int l, int is_for_loop_init) · 4 unmodified lines
59215923 tcc_error("incompatible types for redefinition of '%s'",
59225924 get_tok_str(v, NULL));
59235925 }
5924− FUNC_PROTO(type.ref->r) = 0;
5926+ type.ref->a.func_proto = 0;
59255927 /* if symbol is already defined, then put complete type */
59265928 sym->type = type;
59275929 } else {
@@ -5980,15 +5982,16 @@ static int decl0(int l, int is_for_loop_init) · 52 unmodified lines
59805982 if (btype.t & VT_TYPEDEF) {
59815983 /* save typedefed type */
59825984 /* XXX: test storage specifiers ? */
5983− sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5985+ sym = sym_push(v, &type, 0, 0);
5986+ sym->a = ad.a;
59845987 sym->type.t |= VT_TYPEDEF;
59855988 } else {
59865989 r = 0;
59875990 if ((type.t & VT_BTYPE) == VT_FUNC) {
59885991 /* external function definition */
59895992 /* specific case for func_call attribute */
5990− ad.func_proto = 1;
5991− type.ref->r = INT_ATTR(&ad);
5993+ ad.a.func_proto = 1;
5994+ type.ref->a = ad.a;
59925995 } else if (!(type.t & VT_ARRAY)) {
59935996 /* not lvalue if array */
59945997 r |= lvalue_type(type.t);
@@ -6039,7 +6042,7 @@ static int decl0(int l, int is_for_loop_init) · 44 unmodified lines
60396042 }
60406043 next();
60416044 }
6042− ad.aligned = 0;
6045+ ad.a.aligned = 0;
60436046 }
60446047 }
60456048 return 0;
x86_64-gen.c+10−5
@@ -933,7 +933,8 @@ typedef enum X86_64_Mode { · 932 unmodified lines
933933 x86_64_mode_x87
934934 } X86_64_Mode;
935935
936−static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b) {
936+static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b)
937+{
937938 if (a == b)
938939 return a;
939940 else if (a == x86_64_mode_none)
@@ -950,7 +951,8 @@ static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b) { · 10 unmodified lines
950951 return x86_64_mode_sse;
951952 }
952953
953−static X86_64_Mode classify_x86_64_inner(CType *ty) {
954+static X86_64_Mode classify_x86_64_inner(CType *ty)
955+{
954956 X86_64_Mode mode;
955957 Sym *f;
956958
@@ -988,7 +990,8 @@ static X86_64_Mode classify_x86_64_inner(CType *ty) { · 31 unmodified lines
988990 assert(0);
989991 }
990992
991−static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count) {
993+static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count)
994+{
992995 X86_64_Mode mode;
993996 int size, align, ret_t = 0;
994997
@@ -1045,7 +1048,8 @@ static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *p · 50 unmodified lines
10451048 return mode;
10461049 }
10471050
1048−ST_FUNC int classify_x86_64_va_arg(CType *ty) {
1051+ST_FUNC int classify_x86_64_va_arg(CType *ty)
1052+{
10491053 /* This definition must be synced with stdarg.h */
10501054 enum __va_arg_type {
10511055 __va_gen_reg, __va_float_reg, __va_stack
@@ -1061,7 +1065,8 @@ ST_FUNC int classify_x86_64_va_arg(CType *ty) { · 9 unmodified lines
10611065
10621066 /* Return the number of registers needed to return the struct, or 0 if
10631067 returning via struct pointer. */
1064−int gfunc_sret(CType *vt, CType *ret, int *ret_align) {
1068+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align)
1069+{
10651070 int size, align, reg_count;
10661071 *ret_align = 1; // Never have to re-align return values for x86-64
10671072 return (classify_x86_64_arg(vt, ret, &size, &align, &reg_count) != x86_64_mode_memory);