[cfe-dev] Local extern declarations

Douglas Gregor dgregor at apple.com
Mon Aug 30 08:14:55 PDT 2010


On Aug 29, 2010, at 6:38 AM, Richard Pennington wrote:

> Hi,
> 
> I'm compiling binutils with clang and have run across a small problem.
> Some parts of binutils use something like:
> 
> int i;
> 
> void f()
> {
> 	extern int i;
> }
> 
> with -Werror -Wall. This causes -Wshadow to complain about a shadowed 
> variable.
> My first thought was to add
> 
>   if (D->getLinkage() == ExternalLinkage)
>     return;
> 
> to CheckShadow() in SemaDecl.cxx, which worked for binutils, but when I 
> tried to update the warn-shadow.c clang test case, I noticed what might 
> be a deeper problem. I added this to warn-shadow.c:
> 
> void f() {
>     extern int i;
> }
> 
> When I compile with my Sema modification turned off, I get:
> 
> warn-shadow.c:34:16: error: declaration shadows a variable in the global 
> scope [-Wshadow]
>     extern int i;
>                ^
> warn-shadow.c:3:5: note: previous declaration is here 
> 
> int i;          // expected-note 3 {{previous declaration is here}}
>     ^
> 
> Which I expect, but then I get
> 
> warn-shadow.c:47:16: error: declaration shadows a local variable 
> [-Wshadow]
> void test4(int i) { // expected-warning {{declaration shadows a variable 
> in the global scope}}
>                ^
> warn-shadow.c:34:16: note: previous declaration is here 
> 
>     extern int i;
>                ^
> 
> The problem is that my "extern int i;" becomes the previous declaration. 
> Notice the "shadows a local variable".
> 
> It seems to me that local extern declarations that shadow file scope 
> extern declarations should either be discarded, or not made visible 
> outside of the scope of their declaration for the purposes of detecting 
> shadowing (or anything else for that matter).
> 
> Thoughts?


For shadowing, yes: only those names visible to normal name lookup should be considered. The issue here is that these names *should* be found when performing redeclarations, so that we can detect redeclaration problems across local scopes, e.g., in

  void f() {
    extern int x;
  }

  void g() {
    extern float x;
  }

which leaves us in an unfortunate place: we need to find those local externs for redeclaration lookup, but we shouldn't find them for shadowing, so we may actually need two different lookups (one redeclaration, one ordinary) to implement the semantics properly.

	- Doug



More information about the cfe-dev mailing list