[PATCH] D28350: [Sema] Avoid -Wshadow warning when a "redefinition of " error is presented
This revision was automatically updated to reflect the committed changes. Closed by commit rL291564: [Sema] Avoid -Wshadow warning when a "redefinition of " error is presented (authored by arphaman). Changed prior to commit: https://reviews.llvm.org/D28350?vs=83214=83806#toc Repository: rL LLVM https://reviews.llvm.org/D28350 Files: cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/SemaCXX/warn-shadow-in-lambdas.cpp cfe/trunk/test/SemaCXX/warn-shadow.cpp Index: cfe/trunk/test/SemaCXX/warn-shadow.cpp === --- cfe/trunk/test/SemaCXX/warn-shadow.cpp +++ cfe/trunk/test/SemaCXX/warn-shadow.cpp @@ -97,3 +97,13 @@ void test8() { int bob; // expected-warning {{declaration shadows a variable in the global namespace}} } + +namespace rdar29067894 { + +void avoidWarningWhenRedefining(int b) { // expected-note {{previous definition is here}} + int a = 0; // expected-note {{previous definition is here}} + int a = 1; // expected-error {{redefinition of 'a'}} + int b = 2; // expected-error {{redefinition of 'b'}} +} + +} Index: cfe/trunk/test/SemaCXX/warn-shadow-in-lambdas.cpp === --- cfe/trunk/test/SemaCXX/warn-shadow-in-lambdas.cpp +++ cfe/trunk/test/SemaCXX/warn-shadow-in-lambdas.cpp @@ -137,3 +137,11 @@ auto g3 = [param] // expected-note {{variable 'param' is explicitly captured here}} (auto param) { ; }; // expected-warning {{declaration shadows a local variable}} } + +void avoidWarningWhenRedefining() { + int a = 1; + auto l = [b = a] { // expected-note {{previous definition is here}} +// Don't warn on redefinitions. +int b = 0; // expected-error {{redefinition of 'b'}} + }; +} Index: cfe/trunk/lib/Sema/SemaDecl.cpp === --- cfe/trunk/lib/Sema/SemaDecl.cpp +++ cfe/trunk/lib/Sema/SemaDecl.cpp @@ -6426,9 +6426,10 @@ } } - // Diagnose shadowed variables before filtering for scope. - if (D.getCXXScopeSpec().isEmpty()) -CheckShadow(S, NewVD, Previous); + // Find the shadowed declaration before filtering for scope. + NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty() +? getShadowedDeclaration(NewVD, Previous) +: nullptr; // Don't consider existing declarations that are in a different // scope and are out-of-semantic-context declarations (if the new @@ -6523,6 +6524,10 @@ } } + // Diagnose shadowed variables iff this isn't a redeclaration. + if (ShadowedDecl && !D.isRedeclaration()) +CheckShadow(NewVD, ShadowedDecl, Previous); + ProcessPragmaWeak(S, NewVD); // If this is the first declaration of an extern C variable, update @@ -6596,33 +6601,40 @@ return SourceLocation(); } -/// \brief Diagnose variable or built-in function shadowing. Implements -/// -Wshadow. -/// -/// This method is called whenever a VarDecl is added to a "useful" -/// scope. -/// -/// \param S the scope in which the shadowing name is being declared -/// \param R the lookup of the name -/// -void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) { +/// \brief Return the declaration shadowed by the given variable \p D, or null +/// if it doesn't shadow any declaration or shadowing warnings are disabled. +NamedDecl *Sema::getShadowedDeclaration(const VarDecl *D, +const LookupResult ) { // Return if warning is ignored. if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc())) -return; +return nullptr; // Don't diagnose declarations at file scope. if (D->hasGlobalStorage()) -return; - - DeclContext *NewDC = D->getDeclContext(); +return nullptr; // Only diagnose if we're shadowing an unambiguous field or variable. if (R.getResultKind() != LookupResult::Found) -return; +return nullptr; - NamedDecl* ShadowedDecl = R.getFoundDecl(); - if (!isa(ShadowedDecl) && !isa(ShadowedDecl)) -return; + NamedDecl *ShadowedDecl = R.getFoundDecl(); + return isa(ShadowedDecl) || isa(ShadowedDecl) + ? ShadowedDecl + : nullptr; +} + +/// \brief Diagnose variable or built-in function shadowing. Implements +/// -Wshadow. +/// +/// This method is called whenever a VarDecl is added to a "useful" +/// scope. +/// +/// \param ShadowedDecl the declaration that is shadowed by the given variable +/// \param R the lookup of the name +/// +void Sema::CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl, + const LookupResult ) { + DeclContext *NewDC = D->getDeclContext(); if (FieldDecl *FD = dyn_cast(ShadowedDecl)) { // Fields are not shadowed by variables in C++ static methods. @@ -6733,7 +6745,8 @@ LookupResult R(*this, D->getDeclName(), D->getLocation(), Sema::LookupOrdinaryName, Sema::ForRedeclaration);
[PATCH] D28350: [Sema] Avoid -Wshadow warning when a "redefinition of " error is presented
rnk accepted this revision. rnk added a comment. This revision is now accepted and ready to land. lgtm Repository: rL LLVM https://reviews.llvm.org/D28350 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28350: [Sema] Avoid -Wshadow warning when a "redefinition of " error is presented
arphaman created this revision. arphaman added reviewers: rsmith, rnk, bruno. arphaman added a subscriber: cfe-commits. arphaman set the repository for this revision to rL LLVM. This patch ensures that clang avoids the redundant -Wshadow warning for variables that already get a "redefinition of " error. Repository: rL LLVM https://reviews.llvm.org/D28350 Files: include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp test/SemaCXX/warn-shadow-in-lambdas.cpp test/SemaCXX/warn-shadow.cpp Index: test/SemaCXX/warn-shadow.cpp === --- test/SemaCXX/warn-shadow.cpp +++ test/SemaCXX/warn-shadow.cpp @@ -97,3 +97,13 @@ void test8() { int bob; // expected-warning {{declaration shadows a variable in the global namespace}} } + +namespace rdar29067894 { + +void avoidWarningWhenRedefining(int b) { // expected-note {{previous definition is here}} + int a = 0; // expected-note {{previous definition is here}} + int a = 1; // expected-error {{redefinition of 'a'}} + int b = 2; // expected-error {{redefinition of 'b'}} +} + +} Index: test/SemaCXX/warn-shadow-in-lambdas.cpp === --- test/SemaCXX/warn-shadow-in-lambdas.cpp +++ test/SemaCXX/warn-shadow-in-lambdas.cpp @@ -137,3 +137,11 @@ auto g3 = [param] // expected-note {{variable 'param' is explicitly captured here}} (auto param) { ; }; // expected-warning {{declaration shadows a local variable}} } + +void avoidWarningWhenRedefining() { + int a = 1; + auto l = [b = a] { // expected-note {{previous definition is here}} +// Don't warn on redefinitions. +int b = 0; // expected-error {{redefinition of 'b'}} + }; +} Index: lib/Sema/SemaDecl.cpp === --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -6425,9 +6425,10 @@ } } - // Diagnose shadowed variables before filtering for scope. - if (D.getCXXScopeSpec().isEmpty()) -CheckShadow(S, NewVD, Previous); + // Find the shadowed declaration before filtering for scope. + NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty() +? getShadowedDeclaration(NewVD, Previous) +: nullptr; // Don't consider existing declarations that are in a different // scope and are out-of-semantic-context declarations (if the new @@ -6522,6 +6523,10 @@ } } + // Diagnose shadowed variables iff this isn't a redeclaration. + if (ShadowedDecl && !D.isRedeclaration()) +CheckShadow(NewVD, ShadowedDecl, Previous); + ProcessPragmaWeak(S, NewVD); // If this is the first declaration of an extern C variable, update @@ -6595,33 +6600,40 @@ return SourceLocation(); } -/// \brief Diagnose variable or built-in function shadowing. Implements -/// -Wshadow. -/// -/// This method is called whenever a VarDecl is added to a "useful" -/// scope. -/// -/// \param S the scope in which the shadowing name is being declared -/// \param R the lookup of the name -/// -void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) { +/// \brief Return the declaration shadowed by the given variable \p D, or null +/// if it doesn't shadow any declaration or shadowing warnings are disabled. +NamedDecl *Sema::getShadowedDeclaration(const VarDecl *D, +const LookupResult ) { // Return if warning is ignored. if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc())) -return; +return nullptr; // Don't diagnose declarations at file scope. if (D->hasGlobalStorage()) -return; - - DeclContext *NewDC = D->getDeclContext(); +return nullptr; // Only diagnose if we're shadowing an unambiguous field or variable. if (R.getResultKind() != LookupResult::Found) -return; +return nullptr; - NamedDecl* ShadowedDecl = R.getFoundDecl(); - if (!isa(ShadowedDecl) && !isa(ShadowedDecl)) -return; + NamedDecl *ShadowedDecl = R.getFoundDecl(); + return isa(ShadowedDecl) || isa(ShadowedDecl) + ? ShadowedDecl + : nullptr; +} + +/// \brief Diagnose variable or built-in function shadowing. Implements +/// -Wshadow. +/// +/// This method is called whenever a VarDecl is added to a "useful" +/// scope. +/// +/// \param ShadowedDecl the declaration that is shadowed by the given variable +/// \param R the lookup of the name +/// +void Sema::CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl, + const LookupResult ) { + DeclContext *NewDC = D->getDeclContext(); if (FieldDecl *FD = dyn_cast(ShadowedDecl)) { // Fields are not shadowed by variables in C++ static methods. @@ -6732,7 +6744,8 @@ LookupResult R(*this, D->getDeclName(), D->getLocation(), Sema::LookupOrdinaryName, Sema::ForRedeclaration); LookupName(R, S); - CheckShadow(S, D, R); + if (NamedDecl *ShadowedDecl = getShadowedDeclaration(D, R)) +