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
995995 {
996996 Sym *s;
997997 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));
9991001 /* push forward reference */
10001002 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
10011003 s->type.t |= VT_EXTERN;
tests/tcctest.c+16−0
@@ -77,6 +77,7 @@ void expr_test(); · 76 unmodified lines
7777 void macro_test();
7878 void recursive_macro_test();
7979 void scope_test();
80+void scope_test2();
8081 void forward_test();
8182 void funcptr_test();
8283 void loop_test();
@@ -718,6 +719,7 @@ int main(int argc, char **argv) · 635 unmodified lines
718719 macro_test();
719720 recursive_macro_test();
720721 scope_test();
722+ scope_test2();
721723 forward_test();
722724 funcptr_test();
723725 loop_test();
@@ -800,6 +802,20 @@ void scope_test() · 76 unmodified lines
800802 printf("g5=%d\n", g);
801803 }
802804
805+int st2_i;
806+int *st2_p = &st2_i;
807+void 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+
803819 void array_test()
804820 {
805821 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
151151 struct S { int a, b; };
152152 struct T { struct S x; };
153153 struct T gt = { 42 a: 1, 43 };
154+#elif defined test_conflicting_types
155+int i;
156+void foo(void) {
157+ int i;
158+ {
159+ extern double i;
160+ i = 42.2;
161+ }
162+}
154163 #endif
tests/tests2/60_errors_and_warnings.expect+3−0
@@ -71,3 +71,6 @@ · 70 unmodified lines
7171
7272 [test_invalid_3]
7373 60_errors_and_warnings.c:153: error: ',' expected (got "a")
74+
75+[test_conflicting_types]
76+60_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