diff options
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 15 | ||||
-rw-r--r-- | test/SemaCXX/warn-shadow.cpp | 9 |
2 files changed, 24 insertions, 0 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 31b24f91c1..6bcb023174 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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; + } + } + } } } diff --git a/test/SemaCXX/warn-shadow.cpp b/test/SemaCXX/warn-shadow.cpp index d5f0623eb3..3d09c78628 100644 --- a/test/SemaCXX/warn-shadow.cpp +++ b/test/SemaCXX/warn-shadow.cpp @@ -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; } + }; +} +} |