From 736393e5aea7a1bbe7b0af2f28fc23eb29a9fde2 Mon Sep 17 00:00:00 2001
From: ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 4 Mar 2003 11:06:32 +0000
Subject: [PATCH] 	PR c/9262 	* c-typeck.c (do_case): Attach the
 first case label to the SWITCH_BODY. 	(c_finish_case): Rechain the next
 statements to the SWITCH_STMT.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@63783 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                          |  6 ++++++
 gcc/c-typeck.c                         | 11 ++++++++++-
 gcc/testsuite/ChangeLog                |  8 ++++++++
 gcc/testsuite/gcc.dg/Wswitch-default.c |  4 ++--
 gcc/testsuite/gcc.dg/Wswitch-enum.c    |  6 +++---
 gcc/testsuite/gcc.dg/Wswitch.c         |  6 +++---
 gcc/testsuite/gcc.dg/switch-2.c        | 10 ++++++++++
 gcc/testsuite/gcc.dg/switch-3.c        | 12 ++++++++++++
 8 files changed, 54 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/switch-2.c
 create mode 100644 gcc/testsuite/gcc.dg/switch-3.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0605af928d5a..8de94d8f5e42 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2003-03-04  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+	PR c/9262
+	* c-typeck.c (do_case): Attach the first case label to the SWITCH_BODY.
+	(c_finish_case): Rechain the next statements to the SWITCH_STMT.
+
 Tue Mar  4 11:30:04 CET 2003  Jan Hubicka  <jh@suse.cz>
 
 	* doc/invoke.texi:  Document that unit-at-a-time is enabled for -O3
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 01a7c92a6653..8302a9678f03 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -7184,11 +7184,19 @@ do_case (low_value, high_value)
 
   if (switch_stack)
     {
+      bool switch_was_empty_p = (SWITCH_BODY (switch_stack->switch_stmt) == NULL_TREE);
+
       label = c_add_case_label (switch_stack->cases, 
 				SWITCH_COND (switch_stack->switch_stmt), 
 				low_value, high_value);
       if (label == error_mark_node)
 	label = NULL_TREE;
+      else if (switch_was_empty_p)
+	{
+	  /* Attach the first case label to the SWITCH_BODY.  */
+	  SWITCH_BODY (switch_stack->switch_stmt) = TREE_CHAIN (switch_stack->switch_stmt);
+	  TREE_CHAIN (switch_stack->switch_stmt) = NULL_TREE;
+	}
     }
   else if (low_value)
     error ("case label not within a switch statement");
@@ -7205,7 +7213,8 @@ c_finish_case ()
 {
   struct c_switch *cs = switch_stack;
 
-  RECHAIN_STMTS (cs->switch_stmt, SWITCH_BODY (cs->switch_stmt)); 
+  /* Rechain the next statements to the SWITCH_STMT.  */
+  last_tree = cs->switch_stmt;
 
   /* Pop the stack.  */
   switch_stack = switch_stack->next;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5f34024a2fde..fb4f391b64f4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2003-03-04  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+	* gcc.dg/switch-2.c: New test.
+	* gcc.dg/switch-3.c: New test.
+	* gcc.dg/Wswitch.c: Adjust line numbers.
+	* gcc.dg/Wswitch-default.c: Likewise.
+	* gcc.dg/Wswitch-enum.c: Likewise.
+
 2003-03-04  Alexandre Oliva  <aoliva@redhat.com>
 
 	* gcc.c-torture/execute/20030222-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/Wswitch-default.c b/gcc/testsuite/gcc.dg/Wswitch-default.c
index 3cc7f2ef0918..a1a3d39c1d9d 100644
--- a/gcc/testsuite/gcc.dg/Wswitch-default.c
+++ b/gcc/testsuite/gcc.dg/Wswitch-default.c
@@ -18,8 +18,8 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
     case 4: return 3;
     default: break;
     }
-  switch (ei)
-    { /* { dg-warning "switch missing default case" } */
+  switch (ei) /* { dg-warning "switch missing default case" } */
+    {
     }
   switch (ej)
     {
diff --git a/gcc/testsuite/gcc.dg/Wswitch-enum.c b/gcc/testsuite/gcc.dg/Wswitch-enum.c
index 00e4b552f834..d031b12ce146 100644
--- a/gcc/testsuite/gcc.dg/Wswitch-enum.c
+++ b/gcc/testsuite/gcc.dg/Wswitch-enum.c
@@ -19,9 +19,9 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
     case 4: return 3;
     default: break;
     }
-  switch (ei)
-    { /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" } */
-    } /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" { target *-*-* } 23 } */
+  switch (ei) /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" } */
+    { /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" { target *-*-* } 22 } */
+    }
   switch (ej)
     { /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" { target *-*-* } 28 } */
     default: break;
diff --git a/gcc/testsuite/gcc.dg/Wswitch.c b/gcc/testsuite/gcc.dg/Wswitch.c
index 014919b87bd7..38c3cbbb4461 100644
--- a/gcc/testsuite/gcc.dg/Wswitch.c
+++ b/gcc/testsuite/gcc.dg/Wswitch.c
@@ -19,9 +19,9 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
     case 4: return 3;
     default: break;
     }
-  switch (ei)
-    { /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" } */
-    } /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" { target *-*-* } 23 } */
+  switch (ei) /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" } */
+    { /*{ dg-warning "enumeration value `e2' not handled in switch" "enum e2" { target *-*-* } 22 } */
+    }
   switch (ej)
     {
     default: break;
diff --git a/gcc/testsuite/gcc.dg/switch-2.c b/gcc/testsuite/gcc.dg/switch-2.c
new file mode 100644
index 000000000000..29a966d31a7d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/switch-2.c
@@ -0,0 +1,10 @@
+/* PR c/9262 */
+/* Originator: Rasmus Hahn <rassahah@neofonie.de> */
+/* { dg-do compile } */
+
+int foo(int i)
+{
+  switch (i)
+    case 3:
+      return 1,
+}  /* { dg-error "(parse|syntax) error" } */
diff --git a/gcc/testsuite/gcc.dg/switch-3.c b/gcc/testsuite/gcc.dg/switch-3.c
new file mode 100644
index 000000000000..593c42d8b16e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/switch-3.c
@@ -0,0 +1,12 @@
+/* PR c/9262 */
+/* Originator: Rasmus Hahn <rassahah@neofonie.de> */
+/* { dg-do compile } */
+
+int foo(int i)
+{
+  switch (i)
+    case 3:
+      return 1;
+    case 4:      /* { dg-error "not within a switch statement" } */
+      return 1;
+}
-- 
GitLab