public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: Diagnose [basic.scope.block]/2 violations even in compound-stmt of function-try-block [PR52953]
@ 2023-08-31  7:20 Jakub Jelinek
  2023-08-31 19:52 ` Jason Merrill
  0 siblings, 1 reply; 5+ messages in thread
From: Jakub Jelinek @ 2023-08-31  7:20 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

Hi!

As the following testcase shows, while check_local_shadow diagnoses most of
the [basic.scope.block]/2 violations, it doesn't diagnose when parameter's
name is redeclared inside of the compound-stmt of a function-try-block.

There is in that case an extra scope (sk_try with parent artificial
sk_block with for FUNCTION_NEEDS_BODY_BLOCK another sk_block and only then
sk_function_param).

The following patch fixes that.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2023-08-31  Jakub Jelinek  <jakub@redhat.com>

	PR c++/52953
	* cp-tree.h (struct language_function): Add x_in_function_try_block
	member.
	* semantics.cc (begin_function_try_block): Set it.
	(finish_function_try_block): Clear it.
	* name-lookup.cc (check_local_shadow): If in_function_try_block
	and current_binding_level->kind == sk_try, skip another level.

	* g++.dg/diagnostic/redeclaration-3.C: New test.

--- gcc/cp/cp-tree.h.jj	2023-08-30 10:42:53.579169729 +0200
+++ gcc/cp/cp-tree.h	2023-08-30 19:28:20.712246064 +0200
@@ -2110,6 +2110,7 @@ struct GTY(()) language_function {
   BOOL_BITFIELD returns_null : 1;
   BOOL_BITFIELD returns_abnormally : 1;
   BOOL_BITFIELD infinite_loop: 1;
+  BOOL_BITFIELD in_function_try_block : 1;
   BOOL_BITFIELD x_in_function_try_handler : 1;
   BOOL_BITFIELD x_in_base_initializer : 1;
 
--- gcc/cp/semantics.cc.jj	2023-08-28 10:33:11.064187885 +0200
+++ gcc/cp/semantics.cc	2023-08-30 19:28:44.295897427 +0200
@@ -1626,6 +1626,7 @@ begin_function_try_block (tree *compound
   *compound_stmt = begin_compound_stmt (0);
   r = begin_try_block ();
   FN_TRY_BLOCK_P (r) = 1;
+  cp_function_chain->in_function_try_block = 1;
   return r;
 }
 
@@ -1662,6 +1663,7 @@ finish_cleanup (tree cleanup, tree try_b
 void
 finish_function_try_block (tree try_block)
 {
+  cp_function_chain->in_function_try_block = 0;
   finish_try_block (try_block);
   /* FIXME : something queer about CTOR_INITIALIZER somehow following
      the try block, but moving it inside.  */
--- gcc/cp/name-lookup.cc.jj	2023-08-24 15:36:59.272791101 +0200
+++ gcc/cp/name-lookup.cc	2023-08-30 19:40:09.396172794 +0200
@@ -3146,6 +3146,11 @@ check_local_shadow (tree decl)
 	     them there.  */
 	  cp_binding_level *b = current_binding_level->level_chain;
 
+	  if (current_binding_level->kind == sk_try
+	      && cp_function_chain->in_function_try_block)
+	    /* Skip the function-try-block level.  */
+	    b = b->level_chain;
+
 	  if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
 	    /* Skip the ctor/dtor cleanup level.  */
 	    b = b->level_chain;
--- gcc/testsuite/g++.dg/diagnostic/redeclaration-3.C.jj	2023-08-30 18:51:42.252179367 +0200
+++ gcc/testsuite/g++.dg/diagnostic/redeclaration-3.C	2023-08-30 19:44:06.314933892 +0200
@@ -0,0 +1,204 @@
+// PR c++/52953
+// { dg-do compile }
+// { dg-options "-pedantic-errors -Wno-switch-unreachable" }
+
+void
+foo (int x)				// { dg-message "'int x' previously declared here" }
+{
+  int x;				// { dg-error "declaration of 'int x' shadows a parameter" }
+}
+
+void
+bar (int x)				// { dg-message "'int x' previously declared here" }
+try
+{
+  int x;				// { dg-error "declaration of 'int x' shadows a parameter" }
+}
+catch (...)
+{
+}
+
+volatile int v;
+
+void
+baz ()
+{
+#if __cplusplus >= 201103L
+  auto f = [] (int x) { int x; };	// { dg-error "declaration of 'int x' shadows a parameter" "" { target c++11 } }
+					// { dg-message "'int x' previously declared here" "" { target c++11 } .-1 }
+#endif
+  if (int x = 1)			// { dg-message "'int x' previously declared here" }
+    {
+      int x;				// { dg-error "redeclaration of 'int x'" }
+    }
+  if (int x = 0)			// { dg-message "'int x' previously declared here" }
+    ;
+  else
+    {
+      int x;				// { dg-error "redeclaration of 'int x'" }
+    }
+  if (int x = 1)			// { dg-message "'int x' previously declared here" }
+    int x;				// { dg-error "redeclaration of 'int x'" }
+  if (int x = 0)			// { dg-message "'int x' previously declared here" }
+    ;
+  else
+    int x;				// { dg-error "redeclaration of 'int x'" }
+  switch (int x = 1)			// { dg-message "'int x' previously declared here" }
+    {
+      int x;				// { dg-error "redeclaration of 'int x'" }
+    default:;
+    }
+  switch (int x = 1)			// { dg-message "'int x' previously declared here" }
+    int x;				// { dg-error "redeclaration of 'int x'" }
+  while (int x = v)			// { dg-message "'int x' previously declared here" }
+    {
+      int x;				// { dg-error "redeclaration of 'int x'" }
+    }
+  while (int x = v)			// { dg-message "'int x' previously declared here" }
+    int x;				// { dg-error "redeclaration of 'int x'" }
+  for (int x = v; x; ++x)		// { dg-message "'int x' previously declared here" }
+    {
+      int x;				// { dg-error "redeclaration of 'int x'" }
+    }
+  for (int x = v; x; ++x)		// { dg-message "'int x' previously declared here" }
+    int x;				// { dg-error "redeclaration of 'int x'" }
+  for (; int x = v; )			// { dg-message "'int x' previously declared here" }
+    {
+      int x;				// { dg-error "redeclaration of 'int x'" }
+    }
+  for (; int x = v; )			// { dg-message "'int x' previously declared here" }
+    int x;				// { dg-error "redeclaration of 'int x'" }
+  try
+    {
+    }
+  catch (int x)				// { dg-message "'int x' previously declared here" }
+    {
+      int x;				// { dg-error "redeclaration of 'int x'" }
+    }
+  if (int x = 1)
+    if (int x = 1)
+      ;
+  if (int x = 0)
+    ;
+  else
+    if (int x = 1)
+      ;
+  if (int x = 1)
+    switch (int x = 1)
+      ;
+  if (int x = 0)
+    while (int x = v)
+      ;
+  if (int x = 0)
+    for (int x = v; x; ++x)
+      ;
+  switch (int x = 1)
+    switch (int x = 1)
+      {
+      case 1:;
+      }
+  while (int x = 0)
+    if (int x = 1)
+      ;
+  for (int x = v; x; ++x)
+    for (int x = v; x; ++x)
+      ;
+}
+
+void
+qux (int x)				// { dg-message "'int x' previously declared here" }
+try
+{
+}
+catch (int x)				// { dg-error "redeclaration of 'int x'" }
+{
+}
+
+void
+corge (int x)				// { dg-message "'int x' previously declared here" }
+try
+{
+}
+catch (...)
+{
+  int x;				// { dg-error "redeclaration of 'int x'" }
+}
+
+void
+fred (int x)				// { dg-message "'int x' previously declared here" }
+try
+{
+}
+catch (int)
+{
+}
+catch (long)
+{
+  int x;				// { dg-error "redeclaration of 'int x'" }
+}
+
+void
+garply (int x)
+{
+  try
+    {
+      int x;
+    }
+  catch (...)
+    {
+      int x;
+    }
+}
+
+struct S
+{
+  S (int x)				// { dg-message "'int x' previously declared here" }
+  try : s (x)
+  {
+    int x;				// { dg-error "declaration of 'int x' shadows a parameter" }
+  }
+  catch (...)
+  {
+  }
+  int s;
+};
+
+struct T
+{
+  T (int x)				// { dg-message "'int x' previously declared here" }
+  try : t (x)
+  {
+  }
+  catch (...)
+  {
+    int x;				// { dg-error "redeclaration of 'int x'" }
+  }
+  int t;
+};
+
+struct U
+{
+  U (int x) : u (x)
+  {
+    try
+    {
+      int x;
+    }
+    catch (...)
+    {
+      int x;
+    }
+  }
+  int u;
+};
+
+struct V
+{
+  V (int x) : v (x)
+  {
+    {
+      int x;
+    }
+  }
+  int v;
+};

	Jakub


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-09-05 14:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-31  7:20 [PATCH] c++: Diagnose [basic.scope.block]/2 violations even in compound-stmt of function-try-block [PR52953] Jakub Jelinek
2023-08-31 19:52 ` Jason Merrill
2023-09-01 13:24   ` [PATCH] c++, v2: " Jakub Jelinek
2023-09-01 14:34     ` [PATCH] c++, v3: " Jakub Jelinek
2023-09-05 14:15     ` [PATCH] c++, v2: " Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).