This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH], c++] Fix PR30566 and PR41825


On 05/13/2010 12:48 AM, Jason Merrill wrote:
On 05/12/2010 03:52 AM, Shujing Zhao wrote:
+           {
+             tree decl = scope->names;
+             if ((decl == context)
+                  || (decl && scope->kind == sk_function_parms
+                 && DECL_CONTEXT (decl) == context))

Looking at scope->names is the wrong way to handle this; this test won't stop when you get to the context of oldlocal if it happens to be a function with no parameters. Instead, look for


scope->kind == sk_function_parms && scope->this_entity == context

+              break;
+             if (decl)
+               {
+                 tree type = TREE_TYPE (decl);
+                 if (TREE_CODE (type) == RECORD_TYPE
+                 && !LAMBDA_TYPE_P (type))

And this test would trigger on a variable; you want


scope->kind == sk_class && !LAMBDA_TYPE_P (scope->this_entity)

You are right. Thanks. The Wshadow-6.C is changed too to test the struct variable shadowing.
Tested with no regression i686-pc-linux-gnu.
Is it ok?


Thanks
Pearly
gcc/cp/
2010-05-13  Shujing Zhao  <pearly.zhao@oracle.com>

	PR c++/30566
	PR c++/41825
	* name-lookup.c (pushdecl_maybe_friend): Avoid the warnings about
	shadowing the outer parameter or variables by the declaration of
	nested function in nested structure or class. Warn the shadowing by
	the declaration of nested lambda expression.

gcc/testsuite/
2010-05-13  Shujing Zhao  <pearly.zhao@oracle.com>

	* testsuite/g++.dg/warn/Wshadow-4.C: Adjust.
	* testsuite/g++.dg/warn/Wshadow-5.C: New test.
	* testsuite/g++.dg/warn/Wshadow-6.C: New test.

Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 159145)
+++ cp/name-lookup.c	(working copy)
@@ -1016,15 +1016,18 @@
 	  else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
 		   /* Inline decls shadow nothing.  */
 		   && !DECL_FROM_INLINE (x)
-		   && TREE_CODE (oldlocal) == PARM_DECL
+		   && (TREE_CODE (oldlocal) == PARM_DECL
+		       || TREE_CODE (oldlocal) == VAR_DECL)
 		   /* Don't check the `this' parameter.  */
-		   && !DECL_ARTIFICIAL (oldlocal))
+		   && !DECL_ARTIFICIAL (oldlocal)
+		   && !DECL_ARTIFICIAL (x))
 	    {
-	      bool err = false;
+	      bool nowarn = false;
 
 	      /* Don't complain if it's from an enclosing function.  */
 	      if (DECL_CONTEXT (oldlocal) == current_function_decl
-		  && TREE_CODE (x) != PARM_DECL)
+		  && TREE_CODE (x) != PARM_DECL
+		  && TREE_CODE (oldlocal) == PARM_DECL)
 		{
 		  /* Go to where the parms should be and see if we find
 		     them there.  */
@@ -1038,17 +1041,42 @@
 		  if (b->kind == sk_function_parms)
 		    {
 		      error ("declaration of %q#D shadows a parameter", x);
-		      err = true;
+		      nowarn = true;
 		    }
 		}
 
-	      if (warn_shadow && !err)
+	      /* The local structure or class can't use parameters of
+		 the containing function anyway.  */
+	      if (DECL_CONTEXT (oldlocal) != current_function_decl)
 		{
-		  warning_at (input_location, OPT_Wshadow,
-			      "declaration of %q#D shadows a parameter", x);
-		  warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
-			      "shadowed declaration is here");
+		  cxx_scope *scope = current_binding_level;
+		  tree context = DECL_CONTEXT (oldlocal);
+		  for (; scope; scope = scope->level_chain)
+		   {
+		     if (scope->kind == sk_function_parms
+			 && scope->this_entity == context)
+		      break;
+		     if (scope->kind == sk_class
+			 && !LAMBDA_TYPE_P (scope->this_entity))
+		       {
+			 nowarn = true;
+			 break;
+		       }
+		   }
 		}
+
+	      if (warn_shadow && !nowarn)
+		{
+		  if (TREE_CODE (oldlocal) == PARM_DECL)
+		    warning_at (input_location, OPT_Wshadow,
+				"declaration of %q#D shadows a parameter", x);
+		  else
+		    warning_at (input_location, OPT_Wshadow,
+				"declaration of %qD shadows a previous local",
+				x);
+		   warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
+			       "shadowed declaration is here");
+		}
 	    }
 
 	  /* Maybe warn if shadowing something else.  */
@@ -1074,14 +1102,6 @@
 		  warning (OPT_Wshadow, "declaration of %qD shadows a member of 'this'",
 			   x);
 		}
-	      else if (oldlocal != NULL_TREE
-		       && TREE_CODE (oldlocal) == VAR_DECL)
-		{
-		  warning_at (input_location, OPT_Wshadow,
-			      "declaration of %qD shadows a previous local", x);
-		  warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
-			      "shadowed declaration is here");
-		}
 	      else if (oldglobal != NULL_TREE
 		       && TREE_CODE (oldglobal) == VAR_DECL)
 		/* XXX shadow warnings in outer-more namespaces */
Index: testsuite/g++.dg/warn/Wshadow-4.C
===================================================================
--- testsuite/g++.dg/warn/Wshadow-4.C	(revision 159145)
+++ testsuite/g++.dg/warn/Wshadow-4.C	(working copy)
@@ -8,13 +8,13 @@
     int GetMainURL() const;
 };
 
-int foo(int infoo)		// { dg-warning "shadowed declaration" }
+int foo(int infoo)		// { dg-bogus "shadowed declaration" }
 {
   int outfoo( INetURLObject( infoo ).GetMainURL()); // { dg-bogus "shadows" }
   extern void f(int infoo);
   struct A
   {
-    void f(int infoo) { }	// { dg-warning "shadows a parameter" }
+    void f(int infoo) { }	// { dg-bogus "shadows a parameter" }
   };
   return outfoo;
 }
@@ -22,11 +22,11 @@
 // PR c++/39763
 int foo2(void)
 {
-    int infoo = 0;		// { dg-warning "shadowed declaration" }
+    int infoo = 0;		// { dg-bogus "shadowed declaration" }
     int outfoo( INetURLObject( infoo ).GetMainURL()); // { dg-bogus "shadows" }
     struct A
     {
-      void f(int infoo) { }	// { dg-warning "shadows a previous local" }
+      void f(int infoo) { }	// { dg-bogus "shadows a previous local" }
     };
     return outfoo;
 }
Index: testsuite/g++.dg/warn/Wshadow-5.C
===================================================================
--- testsuite/g++.dg/warn/Wshadow-5.C	(revision 0)
+++ testsuite/g++.dg/warn/Wshadow-5.C	(revision 0)
@@ -0,0 +1,33 @@
+// Wshadows was giving warnings for nested function parameters in nested class
+// or structure that we didn't want.
+// { dg-do compile }
+// { dg-options "-Wshadow" }
+
+// PR c++/41825
+int f (int n)
+{
+    int bar (int n) { return n++; } // { dg-error "a function-definition is not allowed here" }
+    return bar (n); // { dg-error "was not declared in this scope" }
+}
+
+int g (int i)
+{
+    struct {
+        int bar (int i) { return i++; } // { dg-bogus "shadows" }
+    } s;
+
+    return s.bar (i);
+}
+
+// PR c++/30566
+void h( int x )
+{
+  class InnerClass
+    {
+      public:
+              static int g( int x ) // { dg-bogus "shadows" }
+                {
+                  // empty
+                }
+    };
+}
Index: testsuite/g++.dg/warn/Wshadow-6.C
===================================================================
--- testsuite/g++.dg/warn/Wshadow-6.C	(revision 0)
+++ testsuite/g++.dg/warn/Wshadow-6.C	(revision 0)
@@ -0,0 +1,38 @@
+// Test the parameter of nested lambda function shadows a parameter.
+// { dg-do compile }
+// { dg-options "-std=c++0x -Wshadow" }
+
+struct S {};
+int f1(int x)   // { dg-warning "shadowed declaration" }
+{
+ int t = 0;
+ int m = 0;     // { dg-warning "shadowed declaration" }
+ [&t] (int x) { // { dg-warning "shadows a parameter" }
+   int m = 1;   // { dg-warning "shadows a previous local" }
+   t = t + x + m;
+ };
+ return t;
+}
+
+void f2(struct S i, int j) {
+  struct A {
+    struct S x;
+    void g(struct S i) { // { dg-warning "shadowed declaration" }
+	  struct S x;    // { dg-warning "shadows a member of" }
+	  struct S y;    // { dg-warning "shadowed declaration" }
+	  int t;
+	   [&t](struct S i){   // { dg-warning "shadows a parameter" }
+		 int j = 1;    // { dg-bogus "shadows" }
+		 struct S y;   // { dg-warning "shadows a previous local" }
+ 		 t = j;
+	   };
+    }
+  };
+}
+
+void f3(int i) {
+ [=]{
+   int j = i;
+   int i; // { dg-warning "shadows a member of" }
+ };
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]