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.
This commit is contained in:
		
							parent
							
								
									e6980f6cc7
								
							
						
					
					
						commit
						1fd3709379
					
				
					 4 changed files with 31 additions and 1 deletions
				
			
		
							
								
								
									
										4
									
								
								tccgen.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								tccgen.c
									
										
									
									
									
								
							| 
						 | 
					@ -995,7 +995,9 @@ static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Sym *s;
 | 
					    Sym *s;
 | 
				
			||||||
    s = sym_find(v);
 | 
					    s = sym_find(v);
 | 
				
			||||||
    if (!s) {
 | 
					    if (!s || (!(s->type.t & VT_EXTERN) && (s->type.t & VT_BTYPE) != VT_FUNC)) {
 | 
				
			||||||
 | 
					        if (s && !is_compatible_types(&s->type, type))
 | 
				
			||||||
 | 
					            tcc_error("conflicting types for '%s'", get_tok_str(s->v, NULL));
 | 
				
			||||||
        /* push forward reference */
 | 
					        /* push forward reference */
 | 
				
			||||||
        s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
 | 
					        s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
 | 
				
			||||||
        s->type.t |= VT_EXTERN;
 | 
					        s->type.t |= VT_EXTERN;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,6 +77,7 @@ void expr_test();
 | 
				
			||||||
void macro_test();
 | 
					void macro_test();
 | 
				
			||||||
void recursive_macro_test();
 | 
					void recursive_macro_test();
 | 
				
			||||||
void scope_test();
 | 
					void scope_test();
 | 
				
			||||||
 | 
					void scope_test2();
 | 
				
			||||||
void forward_test();
 | 
					void forward_test();
 | 
				
			||||||
void funcptr_test();
 | 
					void funcptr_test();
 | 
				
			||||||
void loop_test();
 | 
					void loop_test();
 | 
				
			||||||
| 
						 | 
					@ -718,6 +719,7 @@ int main(int argc, char **argv)
 | 
				
			||||||
    macro_test();
 | 
					    macro_test();
 | 
				
			||||||
    recursive_macro_test();
 | 
					    recursive_macro_test();
 | 
				
			||||||
    scope_test();
 | 
					    scope_test();
 | 
				
			||||||
 | 
					    scope_test2();
 | 
				
			||||||
    forward_test();
 | 
					    forward_test();
 | 
				
			||||||
    funcptr_test();
 | 
					    funcptr_test();
 | 
				
			||||||
    loop_test();
 | 
					    loop_test();
 | 
				
			||||||
| 
						 | 
					@ -800,6 +802,20 @@ void scope_test()
 | 
				
			||||||
    printf("g5=%d\n", g);
 | 
					    printf("g5=%d\n", g);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int st2_i;
 | 
				
			||||||
 | 
					int *st2_p = &st2_i;
 | 
				
			||||||
 | 
					void scope_test2()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char a[50];
 | 
				
			||||||
 | 
					    st2_i = 42;
 | 
				
			||||||
 | 
					    for (int st2_i = 1; st2_i < 10; st2_i++) {
 | 
				
			||||||
 | 
					        extern int st2_i;
 | 
				
			||||||
 | 
					        st2_i++;
 | 
				
			||||||
 | 
					        printf("exloc: %d\n", st2_i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    printf("exloc: %d\n", *st2_p);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void array_test()
 | 
					void array_test()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int i, j, a[4];
 | 
					    int i, j, a[4];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -151,4 +151,13 @@ int ga = 0.42 { 2 };
 | 
				
			||||||
struct S { int a, b; };
 | 
					struct S { int a, b; };
 | 
				
			||||||
struct T { struct S x; };
 | 
					struct T { struct S x; };
 | 
				
			||||||
struct T gt = { 42 a: 1, 43 };
 | 
					struct T gt = { 42 a: 1, 43 };
 | 
				
			||||||
 | 
					#elif defined test_conflicting_types
 | 
				
			||||||
 | 
					int i;
 | 
				
			||||||
 | 
					void foo(void) {
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        extern double i;
 | 
				
			||||||
 | 
					        i = 42.2;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,3 +71,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[test_invalid_3]
 | 
					[test_invalid_3]
 | 
				
			||||||
60_errors_and_warnings.c:153: error: ',' expected (got "a")
 | 
					60_errors_and_warnings.c:153: error: ',' expected (got "a")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[test_conflicting_types]
 | 
				
			||||||
 | 
					60_errors_and_warnings.c:159: error: conflicting types for 'i'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue