Patchwork [C++] PR 31952

login
register
mail settings
Submitter Paolo Carlini
Date May 15, 2013, 3:22 a.m.
Message ID <5192FF75.8010108@oracle.com>
Download mbox | patch
Permalink /patch/243874/
State New
Headers show

Comments

Paolo Carlini - May 15, 2013, 3:22 a.m.
Hi,

here is a patch to produce permerrors for all the cases of shadowing 
mentioned in the PR (the comment gives references to the Standard). I 
took the occasion to change the existing pair of errors added by Janis 
to error + inform (thus I had to tweak 3 testcases).

Of course we have the option of changing the latter hard errors too to 
permerrors, that would allow to have a simpler combined check. I'm 
attaching the variant.

Tested x86_64-linux.

Thanks,
Paolo.

///////////////////////////
/cp
2013-05-14  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/31952
	* name-lookup.c (pushdecl_maybe_friend_1): Diagnose illegal
	redeclarations.

/testsuite
2013-05-14  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/31952
	* g++.dg/parse/pr31952-1.C: New.
	* g++.dg/parse/pr31952-2.C: Likewise.
	* g++.dg/parse/pr31952-3.C: Likewise.

	* g++.dg/parse/pr18770.C: Adjust dg-errors to dg-messages.
	* g++.old-deja/g++.jason/cond.C: Likewise.
	* g++.dg/cpp0x/range-for5.C: Likewise.

Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 198915)
+++ cp/name-lookup.c	(working copy)
@@ -1125,13 +1125,30 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
 		 outermost block of the controlled statement.
 		 Redeclaring a variable from a for or while condition is
 		 detected elsewhere.  */
-	      else if (VAR_P (oldlocal)
-		       && oldscope == current_binding_level->level_chain
-		       && (oldscope->kind == sk_cond
-			   || oldscope->kind == sk_for))
+	      /* Also error per the following C++11 specifications:
+		 3.3.3/3:  The name declared in an exception-declaration (...)
+		 shall not be redeclared in the outermost block of the handler.
+		 3.3.3/2:  A parameter name shall not be redeclared (...) in
+		 the outermost block of any handler associated with a
+		 function-try-block.
+		 3.4.1/15: The function parameter names shall not be redeclared
+		 in the exception-declaration nor in the outermost block of a
+		 handler for the function-try-block.  */
+	      else if ((VAR_P (oldlocal)
+			&& oldscope == current_binding_level->level_chain
+			&& (oldscope->kind == sk_cond
+			    || oldscope->kind == sk_for
+			    || oldscope->kind == sk_catch))
+		       || (TREE_CODE (oldlocal) == PARM_DECL
+			   && (current_binding_level->kind == sk_catch
+			       || (current_binding_level->level_chain->kind
+				   == sk_catch))
+			   && in_function_try_handler))
 		{
-		  error ("redeclaration of %q#D", x);
-		  error ("%q+#D previously declared here", oldlocal);
+		  if (permerror (input_location, "redeclaration of %q#D", x))
+		    inform (input_location, "%q+#D previously declared here",
+			    oldlocal);
+		  nowarn = true;
 		}
 
 	      if (warn_shadow && !nowarn)
Jason Merrill - May 15, 2013, 3:39 p.m.
On 05/14/2013 11:22 PM, Paolo Carlini wrote:
> here is a patch to produce permerrors for all the cases of shadowing
> mentioned in the PR (the comment gives references to the Standard). I
> took the occasion to change the existing pair of errors added by Janis
> to error + inform (thus I had to tweak 3 testcases).

OK.

> Of course we have the option of changing the latter hard errors too to
> permerrors, that would allow to have a simpler combined check. I'm
> attaching the variant.

I think let's leave them as errors, the reason for making the new ones 
permerror rather than error is to allow broken code that's currently 
accepted to still be accepted with -fpermissive.

Jason

Patch

Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 198915)
+++ cp/name-lookup.c	(working copy)
@@ -1131,8 +1131,33 @@  pushdecl_maybe_friend_1 (tree x, bool is_friend)
 			   || oldscope->kind == sk_for))
 		{
 		  error ("redeclaration of %q#D", x);
-		  error ("%q+#D previously declared here", oldlocal);
+		  inform (input_location, "%q+#D previously declared here",
+			  oldlocal);
+		  nowarn = true;
 		}
+	      /* C++11:
+		 3.3.3/3:  The name declared in an exception-declaration (...)
+		 shall not be redeclared in the outermost block of the handler.
+		 3.3.3/2:  A parameter name shall not be redeclared (...) in
+		 the outermost block of any handler associated with a
+		 function-try-block.
+		 3.4.1/15: The function parameter names shall not be redeclared
+		 in the exception-declaration nor in the outermost block of a
+		 handler for the function-try-block.  */
+	      else if ((VAR_P (oldlocal)
+			&& oldscope == current_binding_level->level_chain
+			&& oldscope->kind == sk_catch)
+		       || (TREE_CODE (oldlocal) == PARM_DECL
+			   && (current_binding_level->kind == sk_catch
+			       || (current_binding_level->level_chain->kind
+				   == sk_catch))
+			   && in_function_try_handler))
+		{
+		  if (permerror (input_location, "redeclaration of %q#D", x))
+		    inform (input_location, "%q+#D previously declared here",
+			    oldlocal);
+		  nowarn = true;
+		}
 
 	      if (warn_shadow && !nowarn)
 		{
Index: testsuite/g++.dg/cpp0x/range-for5.C
===================================================================
--- testsuite/g++.dg/cpp0x/range-for5.C	(revision 198891)
+++ testsuite/g++.dg/cpp0x/range-for5.C	(working copy)
@@ -47,7 +47,7 @@  void test1()
 
   //Check the correct scopes
   int i;
-  for (int i : a)		// { dg-error "previously declared" }
+  for (int i : a)		// { dg-message "previously declared" }
   {
     int i;			// { dg-error "redeclaration" }
   }
Index: testsuite/g++.dg/parse/pr18770.C
===================================================================
--- testsuite/g++.dg/parse/pr18770.C	(revision 198891)
+++ testsuite/g++.dg/parse/pr18770.C	(working copy)
@@ -11,7 +11,7 @@  extern int j;
 void
 e0 (void)
 {
-  for (int i = 0;	// { dg-error "previously declared here" "prev" }
+  for (int i = 0;	// { dg-message "previously declared here" "prev" }
        i < 10; ++i)
     {
       int i = 2;	// { dg-error "redeclaration" "redecl" }
@@ -24,7 +24,7 @@  e1 (void)
 {
   int i;
   for (i = 0;
-       int k = j; i++)	// { dg-error "previously declared here" "prev" }
+       int k = j; i++)	// { dg-message "previously declared here" "prev" }
     {
       int k = 2;	// { dg-error "redeclaration" "redecl" }
       foo (k);
@@ -34,7 +34,7 @@  e1 (void)
 void
 e2 (void)
 {
-  if (int i = 1)	// { dg-error "previously declared here" "prev" }
+  if (int i = 1)	// { dg-message "previously declared here" "prev" }
     {
       int i = 2;	// { dg-error "redeclaration" "redecl" }
       foo (i);
@@ -44,7 +44,7 @@  e2 (void)
 void
 e3 (void)
 {
-  if (int i = 1)	// { dg-error "previously declared here" "prev" }
+  if (int i = 1)	// { dg-message "previously declared here" "prev" }
     {
       foo (i);
     }
@@ -58,7 +58,7 @@  e3 (void)
 void
 e4 (void)
 {
-  while (int i = 1)	// { dg-error "previously declared here" "prev" }
+  while (int i = 1)	// { dg-message "previously declared here" "prev" }
     {
       int i = 2;	// { dg-error "redeclaration" "redecl" }
       foo (i);
@@ -68,7 +68,7 @@  e4 (void)
 void
 e5 (void)
 {
-  switch (int i = j)	// { dg-error "previously declared here" "prev" }
+  switch (int i = j)	// { dg-message "previously declared here" "prev" }
     {
     int i;		// { dg-error "redeclaration" "redecl" }
     default:
Index: testsuite/g++.dg/parse/pr31952-1.C
===================================================================
--- testsuite/g++.dg/parse/pr31952-1.C	(revision 0)
+++ testsuite/g++.dg/parse/pr31952-1.C	(working copy)
@@ -0,0 +1,41 @@ 
+// PR c++/31952
+
+int
+f0 (int bar)  // { dg-message "previously" }
+try
+{
+  return 0;
+}
+catch (...)
+{
+  int bar = 0; // { dg-error "redeclaration" }
+  return 1;
+}
+
+int
+f1 (int bar)
+try
+{
+  return 0;
+}
+catch (...)
+{
+  {
+    int bar = 0; // Ok, not outermost block.
+  }
+  return 1;
+}
+
+int
+f2 (int bar)
+{
+  try
+    {
+      return 0;
+    }
+  catch (...)
+    {
+      int bar = 0; // Ok, not a function-try-block.
+      return 1;
+    }
+}
Index: testsuite/g++.dg/parse/pr31952-2.C
===================================================================
--- testsuite/g++.dg/parse/pr31952-2.C	(revision 0)
+++ testsuite/g++.dg/parse/pr31952-2.C	(working copy)
@@ -0,0 +1,49 @@ 
+// PR c++/31952
+
+void
+f0()
+{
+  try
+  {
+  }
+  catch (void *e)  // { dg-message "previously" }
+  {
+    void *e;       // { dg-error "redeclaration" }
+  }
+}
+
+void
+f1()
+{
+  try
+  {
+  }
+  catch (void *e)
+  {
+    {
+      void *e; // Ok, not outermost block.
+    }
+  }
+}
+
+void
+f2()
+try
+{
+}
+catch (void *e)  // { dg-message "previously" }
+{
+  void *e;       // { dg-error "redeclaration" }
+}
+
+void
+f3()
+try
+{
+}
+catch (void *e)
+{
+  {
+    void *e; // Ok, not outermost block.
+  }
+}
Index: testsuite/g++.dg/parse/pr31952-3.C
===================================================================
--- testsuite/g++.dg/parse/pr31952-3.C	(revision 0)
+++ testsuite/g++.dg/parse/pr31952-3.C	(working copy)
@@ -0,0 +1,25 @@ 
+// PR c++/31952
+
+int
+f0 (int bar)     // { dg-message "previously" }
+try
+{
+  return 0;
+}
+catch (int bar)  // { dg-error "redeclaration" }
+{
+  return 1;
+}
+
+int
+f1 (int bar)
+{
+  try
+  {
+    return 0;
+  }
+  catch (int bar)  // Ok, not a function-try-block.
+  {
+    return 1;
+  }
+}
Index: testsuite/g++.old-deja/g++.jason/cond.C
===================================================================
--- testsuite/g++.old-deja/g++.jason/cond.C	(revision 198891)
+++ testsuite/g++.old-deja/g++.jason/cond.C	(working copy)
@@ -6,7 +6,7 @@  int main()
 {
   float i;
   
-  if (int i = 1)		// { dg-error "previously" }
+  if (int i = 1)		// { dg-message "previously" }
     {
       char i;			// { dg-error "redeclaration" } 
       char j;
@@ -17,17 +17,17 @@  int main()
       char j;
     }
 
-  while (int i = 0)		// { dg-error "previously" }
+  while (int i = 0)		// { dg-message "previously" }
     {
       int i;			// { dg-error "redeclaration" }
     }
 
-  for (; int i = 0; )		// { dg-error "previously" }
+  for (; int i = 0; )		// { dg-message "previously" }
     {
       int i;			// { dg-error "redeclaration" }
     }
 
-  switch (int i = 0)		// { dg-error "previously" }
+  switch (int i = 0)		// { dg-message "previously" }
     {
     default:
       int i;			// { dg-error "redeclaration" }