summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2017-07-31 15:21:26 +0000
committerAlexander Kornienko <alexfh@google.com>2017-07-31 15:21:26 +0000
commit86e9daf19ba45dd6f133d0df160c8f464f27a7d8 (patch)
treece2dcbdce55505af7fb40cbbb65a2290de212eeb /lib/Sema/SemaDecl.cpp
parentc38987d1ea4e93148913cb26d8a1b556305523c7 (diff)
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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@309569 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp15
1 files changed, 15 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;
+ }
+ }
+ }
}
}