diff options
author | Alexander Kornienko <alexfh@google.com> | 2017-07-31 15:21:26 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2017-07-31 15:21:26 +0000 |
commit | 86e9daf19ba45dd6f133d0df160c8f464f27a7d8 (patch) | |
tree | ce2dcbdce55505af7fb40cbbb65a2290de212eeb /lib/Sema/SemaDecl.cpp | |
parent | c38987d1ea4e93148913cb26d8a1b556305523c7 (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.cpp | 15 |
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; + } + } + } } } |