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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits