Do not check for parameters shadowing fields in function declarations.
authorAaron Ballman <aaron@aaronballman.com>
Wed, 5 Dec 2018 18:56:57 +0000 (18:56 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Wed, 5 Dec 2018 18:56:57 +0000 (18:56 +0000)
We would issue a false-positive diagnostic for parameters in function declarations shadowing fields; we now only issue the diagnostic on a function definition instead.

llvm-svn: 348400

clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaDecl.cpp
clang/test/SemaCXX/warn-shadow.cpp

index 4f891e0..d82bd20 100644 (file)
@@ -12141,6 +12141,18 @@ bool Sema::CheckParmsForFunctionDef(ArrayRef<ParmVarDecl *> Parameters,
       if (!Param->getType().isConstQualified())
         Diag(Param->getLocation(), diag::err_attribute_pointers_only)
             << Attr->getSpelling() << 1;
+
+    // Check for parameter names shadowing fields from the class.
+    if (LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
+      // The owning context for the parameter should be the function, but we
+      // want to see if this function's declaration context is a record.
+      DeclContext *DC = Param->getDeclContext();
+      if (DC && DC->isFunctionOrMethod()) {
+        if (auto *RD = dyn_cast<CXXRecordDecl>(DC->getParent()))
+          CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
+                                     RD, /*DeclIsField*/ false);
+      }
+    }
   }
 
   return HasInvalidParm;
index 5ec5929..da6d414 100644 (file)
@@ -12427,13 +12427,6 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
         D.setInvalidType(true);
       }
     }
-
-    if (LangOpts.CPlusPlus) {
-      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
index 283fb6d..f4a904b 100644 (file)
@@ -201,7 +201,7 @@ void avoidWarningWhenRedefining(int b) { // expected-note {{previous definition
   typedef char l; // no warning or error.\r
  
   typedef char n; // no warning or error. 
-  typedef char n; // no warning or error.\r
+  typedef char n; // no warning or error.
   using n=char; // no warning or error.\r
 }\r
 
@@ -225,7 +225,7 @@ void f(int a) {
 \r
 namespace PR34120 {\r
 struct A {\r
-  int B; // expected-note {{declared here}}\r
+  int B; // expected-note {{declared here}}\r
 };\r
 \r
 class C : public A {\r
@@ -233,8 +233,13 @@ class C : public A {
   void E() {\r
     extern void f(int B); // Ok\r
   }\r
+  void F(int B); // Ok, declaration; not definition.\r
+  void G(int B);\r
 };\r
 \r
+void C::G(int B) { // expected-warning {{parameter 'B' shadows member inherited from type 'A'}}\r
+}\r
+\r
 class Private {\r
   int B;\r
 };\r