History

Fix local extern vardecl

see testcases. A local 'extern int i' declaration needs to refer to the global declaration, not to a local one it might be shadowing. Doesn't seem to happen in the wild very often as this was broken forever.

Michael Matz committed 7 years ago

Commit 1fd37091 parent e6980f64 files · +31 −1Browse files

Unified · Split

4 files
  1. tccgen.c +3 −1
  2. tests/tcctest.c +16 −0
  3. tests/tests2/60_errors_and_warnings.c +9 −0
  4. tests/tests2/60_errors_and_warnings.expect +3 −0
tccgen.c+3−1
@@ -995,7 +995,9 @@ static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad) · 994 unmodified lines
995{995{
996 Sym *s;996 Sym *s;
997 s = sym_find(v);997 s = sym_find(v);
998 if (!s) {998 if (!s || (!(s->type.t & VT_EXTERN) && (s->type.t & VT_BTYPE) != VT_FUNC)) {
999 if (s && !is_compatible_types(&s->type, type))
1000 tcc_error("conflicting types for '%s'", get_tok_str(s->v, NULL));
999 /* push forward reference */1001 /* push forward reference */
1000 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);1002 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
1001 s->type.t |= VT_EXTERN;1003 s->type.t |= VT_EXTERN;
tests/tcctest.c+16−0
@@ -77,6 +77,7 @@ void expr_test(); · 76 unmodified lines
77void macro_test();77void macro_test();
78void recursive_macro_test();78void recursive_macro_test();
79void scope_test();79void scope_test();
80void scope_test2();
80void forward_test();81void forward_test();
81void funcptr_test();82void funcptr_test();
82void loop_test();83void loop_test();
@@ -718,6 +719,7 @@ int main(int argc, char **argv) · 635 unmodified lines
718 macro_test();719 macro_test();
719 recursive_macro_test();720 recursive_macro_test();
720 scope_test();721 scope_test();
722 scope_test2();
721 forward_test();723 forward_test();
722 funcptr_test();724 funcptr_test();
723 loop_test();725 loop_test();
@@ -800,6 +802,20 @@ void scope_test() · 76 unmodified lines
800 printf("g5=%d\n", g);802 printf("g5=%d\n", g);
801}803}
802 804
805int st2_i;
806int *st2_p = &st2_i;
807void scope_test2()
808{
809 char a[50];
810 st2_i = 42;
811 for (int st2_i = 1; st2_i < 10; st2_i++) {
812 extern int st2_i;
813 st2_i++;
814 printf("exloc: %d\n", st2_i);
815 }
816 printf("exloc: %d\n", *st2_p);
817}
818
803void array_test()819void array_test()
804{820{
805 int i, j, a[4];821 int i, j, a[4];
tests/tests2/60_errors_and_warnings.c+9−0
@@ -151,4 +151,13 @@ int ga = 0.42 { 2 }; · 150 unmodified lines
151struct S { int a, b; };151struct S { int a, b; };
152struct T { struct S x; };152struct T { struct S x; };
153struct T gt = { 42 a: 1, 43 };153struct T gt = { 42 a: 1, 43 };
154#elif defined test_conflicting_types
155int i;
156void foo(void) {
157 int i;
158 {
159 extern double i;
160 i = 42.2;
161 }
162}
154#endif163#endif
tests/tests2/60_errors_and_warnings.expect+3−0
@@ -71,3 +71,6 @@ · 70 unmodified lines
71 71
72[test_invalid_3]72[test_invalid_3]
7360_errors_and_warnings.c:153: error: ',' expected (got "a")7360_errors_and_warnings.c:153: error: ',' expected (got "a")
74
75[test_conflicting_types]
7660_errors_and_warnings.c:159: error: conflicting types for 'i'

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