History

Fix more attribute placements

when parsing the type in this cast: (int (__attribute__(X) *)(int))foo we ignored the attribute, which matters if it's e.g. a 'stdcall' attribute on the function pointer. Only this particular placement was misparsed. Putting the attribute after the '*' or outside the inner parens worked. This idiom seems to be used on SQLite, perhaps this fixes a compilation problem on win32 with that.

Michael Matz committed 7 years ago

Commit 3e007191 parent 325241c3 files · +79 −25Browse files

Unified · Split

3 files
  1. tccgen.c +53 −24
  2. tccpe.c +1 −1
  3. tests/tests2/82_attribs_position.c +25 −0
tccgen.c+53−24
@@ -846,6 +846,52 @@ ST_FUNC Sym *external_global_sym(int v, CType *type, int r) · 845 unmodified lines
846 return s;846 return s;
847}847}
848 848
849/* Merge symbol attributes. */
850static void merge_symattr(struct SymAttr *sa, struct SymAttr *sa1)
851{
852 if (sa1->aligned && !sa->aligned)
853 sa->aligned = sa1->aligned;
854 sa->packed |= sa1->packed;
855 sa->weak |= sa1->weak;
856 if (sa1->visibility != STV_DEFAULT) {
857 int vis = sa->visibility;
858 if (vis == STV_DEFAULT
859 || vis > sa1->visibility)
860 vis = sa1->visibility;
861 sa->visibility = vis;
862 }
863 sa->dllexport |= sa1->dllexport;
864 sa->nodecorate |= sa1->nodecorate;
865 sa->dllimport |= sa1->dllimport;
866}
867
868/* Merge function attributes. */
869static void merge_funcattr(struct FuncAttr *fa, struct FuncAttr *fa1)
870{
871 if (fa1->func_call && !fa->func_call)
872 fa->func_call = fa1->func_call;
873 if (fa1->func_type && !fa->func_type)
874 fa->func_type = fa1->func_type;
875 if (fa1->func_args && !fa->func_args)
876 fa->func_args = fa1->func_args;
877}
878
879/* Merge attributes. */
880static void merge_attr(AttributeDef *ad, AttributeDef *ad1)
881{
882 merge_symattr(&ad->a, &ad1->a);
883 merge_funcattr(&ad->f, &ad1->f);
884
885 if (ad1->section)
886 ad->section = ad1->section;
887 if (ad1->alias_target)
888 ad->alias_target = ad1->alias_target;
889 if (ad1->asm_label)
890 ad->asm_label = ad1->asm_label;
891 if (ad1->attr_mode)
892 ad->attr_mode = ad1->attr_mode;
893}
894
849/* Merge some type attributes. */895/* Merge some type attributes. */
850static void patch_type(Sym *sym, CType *type)896static void patch_type(Sym *sym, CType *type)
851{897{
@@ -905,20 +951,8 @@ static void patch_storage(Sym *sym, AttributeDef *ad, CType *type) · 53 unmodified lines
905 if (sym->a.dllimport != ad->a.dllimport)951 if (sym->a.dllimport != ad->a.dllimport)
906 tcc_error("incompatible dll linkage for redefinition of '%s'",952 tcc_error("incompatible dll linkage for redefinition of '%s'",
907 get_tok_str(sym->v, NULL));953 get_tok_str(sym->v, NULL));
908 sym->a.dllexport |= ad->a.dllexport;
909#endif954#endif
910 sym->a.weak |= ad->a.weak;955 merge_symattr(&sym->a, &ad->a);
911 if (ad->a.visibility) {
912 int vis = sym->a.visibility;
913 int vis2 = ad->a.visibility;
914 if (vis == STV_DEFAULT)
915 vis = vis2;
916 else if (vis2 != STV_DEFAULT)
917 vis = (vis < vis2) ? vis : vis2;
918 sym->a.visibility = vis;
919 }
920 if (ad->a.aligned)
921 sym->a.aligned = ad->a.aligned;
922 if (ad->asm_label)956 if (ad->asm_label)
923 sym->asm_label = ad->asm_label;957 sym->asm_label = ad->asm_label;
924 update_storage(sym);958 update_storage(sym);
@@ -4000,14 +4034,8 @@ do_decl: · 3075 unmodified lines
4000 4034
4001static void sym_to_attr(AttributeDef *ad, Sym *s)4035static void sym_to_attr(AttributeDef *ad, Sym *s)
4002{4036{
4003 if (s->a.aligned && 0 == ad->a.aligned)4037 merge_symattr(&ad->a, &s->a);
4004 ad->a.aligned = s->a.aligned;4038 merge_funcattr(&ad->f, &s->f);
4005 if (s->f.func_call && 0 == ad->f.func_call)
4006 ad->f.func_call = s->f.func_call;
4007 if (s->f.func_type && 0 == ad->f.func_type)
4008 ad->f.func_type = s->f.func_type;
4009 if (s->a.packed)
4010 ad->a.packed = 1;
4011}4039}
4012 4040
4013/* Add type qualifiers to a type. If the type is an array then the qualifiers4041/* Add type qualifiers to a type. If the type is an array then the qualifiers
@@ -4294,9 +4322,10 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 280 unmodified lines
4294 l = 0;4322 l = 0;
4295 else if (parse_btype(&pt, &ad1))4323 else if (parse_btype(&pt, &ad1))
4296 l = FUNC_NEW;4324 l = FUNC_NEW;
4297 else if (td)4325 else if (td) {
4298 return 0;4326 merge_attr (ad, &ad1);
4299 else4327 return 0;
4328 } else
4300 l = FUNC_OLD;4329 l = FUNC_OLD;
4301 first = NULL;4330 first = NULL;
4302 plast = &first;4331 plast = &first;
tccpe.c+1−1
@@ -1747,7 +1747,7 @@ ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd) · 1746 unmodified lines
1747 ret = pe_load_def(s1, fd);1747 ret = pe_load_def(s1, fd);
1748 else if (pe_load_res(s1, fd) == 0)1748 else if (pe_load_res(s1, fd) == 0)
1749 ret = 0;1749 ret = 0;
1750 else if (read_mem(fd, 0, buf, 4) && 0 == memcmp(buf, "MZ\220", 4))1750 else if (read_mem(fd, 0, buf, 4) && 0 == memcmp(buf, "MZ", 2))
1751 ret = pe_load_dll(s1, filename);1751 ret = pe_load_dll(s1, filename);
1752 return ret;1752 return ret;
1753}1753}
tests/tests2/82_attribs_position.c+25−0
@@ -16,6 +16,13 @@ void __attribute__((stdcall)) foo (void) · 15 unmodified lines
16{16{
17}17}
18 18
19#define __stdcall __attribute__((stdcall))
20extern int some_stdcall_func (int, int, int) __stdcall;
21__stdcall int __stdcall some_stdcall_func(int foo, int bar, int baz) {
22 //printf("Hello from stdcall: %i %i %i\n", foo, bar, baz);
23 return 43;
24}
25
19/* The actual attribute isn't important, must just be26/* The actual attribute isn't important, must just be
20 parsable. */27 parsable. */
21#define ATTR __attribute__((__noinline__))28#define ATTR __attribute__((__noinline__))
@@ -24,9 +31,11 @@ int ATTR actual_function() { · 2 unmodified lines
24}31}
25 32
26extern int printf (const char *, ...);33extern int printf (const char *, ...);
34static int globalvar;
27int main()35int main()
28{36{
29 void *function_pointer = &actual_function;37 void *function_pointer = &actual_function;
38 int localvar = 42, i;
30 39
31 int a = ((ATTR int(*) (void)) function_pointer)();40 int a = ((ATTR int(*) (void)) function_pointer)();
32 printf("%i\n", a);41 printf("%i\n", a);
@@ -36,5 +45,21 @@ int main() · 3 unmodified lines
36 int b = ( (int(ATTR *)(void)) function_pointer)();45 int b = ( (int(ATTR *)(void)) function_pointer)();
37 printf("%i\n", b);46 printf("%i\n", b);
38 47
48 /* All these should work and leave the stack pointer in its original
49 position. */
50 some_stdcall_func(1, 10, 100);
51 ((int __stdcall (*)(int, int, int))some_stdcall_func) (2, 20, 200);
52 ((int(*__stdcall)(int, int, int))some_stdcall_func) (3, 30, 300);
53 for (i = 0; i < 1024; i++) {
54 globalvar = i;
55 /* This was once misparsed at <= gitrev 325241c0, forgetting
56 the stdcall attribute on the function pointer leading to
57 stack increment being done twice (in callee and caller).
58 This will clobber 'i' and 'localvar' which is how we detect
59 this. */
60 ((int(__stdcall*)(int, int, int))some_stdcall_func) (4, 40, 400);
61 if (localvar != 42 || globalvar != i)
62 printf("error, localvar=%d i=%d globalvar=%d\n", localvar, i, globalvar);
63 }
39 return 0;64 return 0;
40}65}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t