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]

[PATCH][4.3] Backport fix for PR39371, fix PR40335


This fixes the wrong-code PR40335 on the 4.3 branch by backporting
the change from PR39371.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to
the branch and the new testcase to 4.4/trunk.

Richard.

2009-06-04  Richard Guenther  <rguenther@suse.de>

	Backport from mainline
	2009-03-09  Jakub Jelinek  <jakub@redhat.com>

	PR c++/39371
	* semantics.c (finish_switch_cond): Don't call get_unwidened.
	* decl.c (finish_case_label): Pass SWITCH_STMT_TYPE as 3rd argument
	instead of TREE_TYPE (cond).

	* g++.dg/opt/switch2.C: Add -w to dg-options.
	* g++.dg/warn/Wswitch-1.C: Adjust expected warnings.
	* g++.dg/warn/switch1.C: New test.
	* g++.dg/other/switch3.C: New test.
	* g++.dg/torture/pr40335.C: New testcase.
 
Index: gcc/testsuite/g++.dg/other/switch3.C
===================================================================
--- gcc/testsuite/g++.dg/other/switch3.C	(revision 0)
+++ gcc/testsuite/g++.dg/other/switch3.C	(revision 144732)
@@ -0,0 +1,25 @@
+// PR c++/39371
+// { dg-do compile }
+
+void
+foo (bool b)
+{
+  switch ((unsigned int) b)
+    {
+    case 1:
+    case 2:
+      break;
+    }
+}
+
+void
+bar (unsigned char b)
+{
+  switch ((unsigned int) b)
+    {
+    case 1:
+    case 257:
+    case 513:
+      break;
+    }
+}
Index: gcc/testsuite/g++.dg/opt/switch2.C
===================================================================
--- gcc/testsuite/g++.dg/opt/switch2.C	(revision 144731)
+++ gcc/testsuite/g++.dg/opt/switch2.C	(revision 144732)
@@ -1,5 +1,5 @@
 // { dg-do compile }
-// { dg-options "-O2" }
+// { dg-options "-O2 -w" }
 
 extern int foo (int);
 
Index: gcc/testsuite/g++.dg/warn/switch1.C
===================================================================
--- gcc/testsuite/g++.dg/warn/switch1.C	(revision 0)
+++ gcc/testsuite/g++.dg/warn/switch1.C	(revision 144732)
@@ -0,0 +1,15 @@
+// { dg-do compile { target { int32plus } } }
+
+signed char sc;
+
+void
+foo (void)
+{
+  switch (sc)
+    {
+    case 1:
+    case 2 * __SCHAR_MAX__ + 3:		// { dg-warning "case label value exceeds maximum" }
+    case - 2 * __SCHAR_MAX__ - 1:	// { dg-warning "case label value is less than minimum" }
+      break;
+    }
+}
Index: gcc/testsuite/g++.dg/warn/Wswitch-1.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wswitch-1.C	(revision 144731)
+++ gcc/testsuite/g++.dg/warn/Wswitch-1.C	(revision 144732)
@@ -50,14 +50,14 @@ foo (int i, int j, enum e ei, enum e ej,
     {
     case e1: return 1;
     case e2: return 2;
-    case 3: return 3; /* { dg-warning "case value '3' not in enumerated type 'e'" "excess 3" } */
+    case 3: return 3; /* { dg-warning "exceeds maximum value" } */
     }
   switch (ep)
     {
     case e1: return 1;
     case e2: return 2;
-    case 3: return 3;
+    case 3: return 3; /* { dg-warning "exceeds maximum value" } */
     default: break;
-    } /* Since there is a default, no warning about ``case 3'' */
+    }
   return 0;
 }
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 144731)
+++ gcc/cp/decl.c	(revision 144732)
@@ -2806,7 +2806,8 @@ finish_case_label (tree low_value, tree
   if (!check_switch_goto (switch_stack->level))
     return error_mark_node;
 
-  r = c_add_case_label (switch_stack->cases, cond, TREE_TYPE (cond),
+  r = c_add_case_label (switch_stack->cases, cond,
+			SWITCH_STMT_TYPE (switch_stack->switch_stmt),
 			low_value, high_value);
 
   /* After labels, make any new cleanups in the function go into their
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 144731)
+++ gcc/cp/semantics.c	(revision 144732)
@@ -945,8 +945,6 @@ finish_switch_cond (tree cond, tree swit
   tree orig_type = NULL;
   if (!processing_template_decl)
     {
-      tree index;
-
       /* Convert the condition to an integer or enumeration type.  */
       cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true);
       if (cond == NULL_TREE)
@@ -963,18 +961,6 @@ finish_switch_cond (tree cond, tree swit
 	  cond = perform_integral_promotions (cond);
 	  cond = maybe_cleanup_point_expr (cond);
 	}
-
-      if (cond != error_mark_node)
-	{
-	  index = get_unwidened (cond, NULL_TREE);
-	  /* We can't strip a conversion from a signed type to an unsigned,
-	     because if we did, int_fits_type_p would do the wrong thing
-	     when checking case values for being in range,
-	     and it's too hard to do the right thing.  */
-	  if (TYPE_UNSIGNED (TREE_TYPE (cond))
-	      == TYPE_UNSIGNED (TREE_TYPE (index)))
-	    cond = index;
-	}
     }
   if (check_for_bare_parameter_packs (cond))
     cond = error_mark_node;
Index: gcc/testsuite/g++.dg/torture/pr40335.C
===================================================================
*** gcc/testsuite/g++.dg/torture/pr40335.C	(revision 0)
--- gcc/testsuite/g++.dg/torture/pr40335.C	(revision 0)
***************
*** 0 ****
--- 1,16 ----
+ /* { dg-do run } */
+ 
+ extern "C" void abort (void);
+ int
+ main (void)
+ {
+   int i = -1; 
+   switch ((signed char) i)
+     {
+       case 255: /* { dg-bogus "exceeds maximum value" "" { xfail *-*-* } } */
+ 	abort ();
+       default:
+ 	break;
+     }
+ }
+ 


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