aaron.ballman created this revision. aaron.ballman added reviewers: lebedev.ri, rsmith, dblaikie.
This patch diagnoses parameter names that shadow the names of inherited fields under -Wshadow-field. It addresses PR34120. Note, unlike GCC, we take into account the accessibility of the field when deciding whether to warn or not. https://reviews.llvm.org/D52421 Files: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/SemaCXX/warn-shadow.cpp
Index: test/SemaCXX/warn-shadow.cpp =================================================================== --- test/SemaCXX/warn-shadow.cpp +++ test/SemaCXX/warn-shadow.cpp @@ -222,3 +222,23 @@ }; } } + +namespace PR34120 { +struct A { + int B; // expected-note {{declared here}} +}; + +class C : public A { + void D(int B) {} // expected-warning {{parameter 'B' shadows member inherited from type 'A'}} + void E() { + extern void f(int B); // Ok + } +}; + +class Private { + int B; +}; +class Derived : Private { + void D(int B) {} // Ok +}; +} Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -2852,7 +2852,8 @@ // Check if there is a field shadowing. void Sema::CheckShadowInheritedFields(const SourceLocation &Loc, DeclarationName FieldName, - const CXXRecordDecl *RD) { + const CXXRecordDecl *RD, + bool DeclIsField) { if (Diags.isIgnored(diag::warn_shadow_field, Loc)) return; @@ -2892,7 +2893,7 @@ if (AS_none != CXXRecordDecl::MergeAccess(P.Access, BaseField->getAccess())) { Diag(Loc, diag::warn_shadow_field) - << FieldName << RD << Base; + << FieldName << RD << Base << DeclIsField; Diag(BaseField->getLocation(), diag::note_shadow_field); Bases.erase(It); } Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -12379,6 +12379,13 @@ } } + if (LangOpts.CPlusPlus && II) { + DeclarationNameInfo DNI = GetNameForDeclarator(D); + if (auto *RD = dyn_cast<CXXRecordDecl>(CurContext)) + CheckShadowInheritedFields(DNI.getLoc(), DNI.getName(), RD, + /*DeclIsField*/ false); + } + // Temporarily put parameter variables in the translation unit, not // the enclosing context. This prevents them from accidentally // looking like class members in C++. Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -10524,7 +10524,8 @@ /// Check if there is a field shadowing. void CheckShadowInheritedFields(const SourceLocation &Loc, DeclarationName FieldName, - const CXXRecordDecl *RD); + const CXXRecordDecl *RD, + bool DeclIsField = true); /// Check if the given expression contains 'break' or 'continue' /// statement that produces control flow different from GCC. Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -9418,10 +9418,9 @@ "__final is a GNU extension, consider using C++11 final">, InGroup<GccCompat>; -def warn_shadow_field : - Warning<"non-static data member %0 of %1 shadows member inherited from " - "type %2">, - InGroup<ShadowField>, DefaultIgnore; +def warn_shadow_field : Warning< + "%select{parameter|non-static data member}3 %0 %select{|of %1 }3shadows " + "member inherited from type %2">, InGroup<ShadowField>, DefaultIgnore; def note_shadow_field : Note<"declared here">; def err_multiversion_required_in_redecl : Error<
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits