summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaDecl.cpp15
-rw-r--r--test/SemaCXX/warn-shadow.cpp9
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; }
+ };
+}
+}