Commit d17519a7 authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r309569:

------------------------------------------------------------------------
r309569 | alexfh | 2017-07-31 08:21:26 -0700 (Mon, 31 Jul 2017) | 39 lines

Fix -Wshadow false positives with function-local classes.

Summary:
Fixes http://llvm.org/PR33947.

https://godbolt.org/g/54XRMT

void f(int a) {
  struct A {
    void g(int a) {}
    A() { int a; }
  };
}

3 : <source>:3:16: warning: declaration shadows a local variable [-Wshadow]
    void g(int a) {}
               ^
1 : <source>:1:12: note: previous declaration is here
void f(int a) {
           ^
4 : <source>:4:15: warning: declaration shadows a local variable [-Wshadow]
    A() { int a; }
              ^
1 : <source>:1:12: note: previous declaration is here
void f(int a) {
           ^
2 warnings generated.

The local variable `a` of the function `f` can't be accessed from a method of
the function-local class A, thus no shadowing occurs and no diagnostic is
needed.

Reviewers: rnk, rsmith, arphaman, Quuxplusone

Reviewed By: rnk, Quuxplusone

Subscribers: Quuxplusone, cfe-commits

Differential Revision: https://reviews.llvm.org/D35941
------------------------------------------------------------------------

llvm-svn: 310674
parent 2ab63b13
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -6999,6 +6999,21 @@ void Sema::CheckShadow(NamedDecl *D, NamedDecl *ShadowedDecl,
          return;
        }
      }
      if (cast<VarDecl>(ShadowedDecl)->hasLocalStorage()) {
        // A variable can't shadow a local variable in an enclosing scope, if
        // they are separated by a non-capturing declaration context.
        for (DeclContext *ParentDC = NewDC;
             ParentDC && !ParentDC->Equals(OldDC);
             ParentDC = getLambdaAwareParentOfDeclContext(ParentDC)) {
          // Only block literals, captured statements, and lambda expressions
          // can capture; other scopes don't.
          if (!isa<BlockDecl>(ParentDC) && !isa<CapturedDecl>(ParentDC) &&
              !isLambdaCallOperator(ParentDC)) {
            return;
          }
        }
      }
    }
  }
+9 −0
Original line number Diff line number Diff line
@@ -213,3 +213,12 @@ typedef int externC; // expected-note {{previous declaration is here}}
void handleLinkageSpec() {
  typedef void externC; // expected-warning {{declaration shadows a typedef in the global namespace}}
}

namespace PR33947 {
void f(int a) {
  struct A {
    void g(int a) {}
    A() { int a; }
  };
}
}