]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR c++/39371 (Incorrectly rejects switch((unsigned int)boolvar))
authorRichard Guenther <rguenther@suse.de>
Thu, 4 Jun 2009 12:35:25 +0000 (12:35 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 4 Jun 2009 12:35:25 +0000 (12:35 +0000)
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.

From-SVN: r148165

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/switch2.C
gcc/testsuite/g++.dg/other/switch3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/pr40335.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wswitch-1.C
gcc/testsuite/g++.dg/warn/switch1.C [new file with mode: 0644]

index 395196af05ea1ca606346eebc1f406d7b321e5cd..b5d7a52e574e5fa634d814ad0c379dc1923c0719 100644 (file)
@@ -1,3 +1,13 @@
+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).
+
 2009-04-23  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/38228
index 6a659533ea54323dbf78ff7cbd19c2bf761922e2..cef56338016c0e5a7171f77894c05ae867985966 100644 (file)
@@ -2807,7 +2807,8 @@ finish_case_label (tree low_value, tree high_value)
   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 1d5961838de5333e25e7c3d202fa2bbfe39de460..fc6469689a99934bea24900aa4a2805c820cd8bc 100644 (file)
@@ -943,8 +943,6 @@ finish_switch_cond (tree cond, tree switch_stmt)
   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)
@@ -961,18 +959,6 @@ finish_switch_cond (tree cond, tree switch_stmt)
          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 f82b286b9f08296009e760ff2eb7de9b80cc1a77..dc619a19ea5ea88c03ae19f262d81d11014dda1b 100644 (file)
@@ -1,3 +1,15 @@
+2009-06-04  Richard Guenther  <rguenther@suse.de>
+
+       Backport from mainline
+       2009-03-09  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/39371
+       * 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.
+
 2009-05-26  Richard Guenther  <rguenther@suse.de>
 
        Backport from mainline
index 2590273c5d9c00e58b6832ba436bb7b6228fe2af..f7374cb7474c9a54bfc69696cb269bd3c20f8a92 100644 (file)
@@ -1,5 +1,5 @@
 // { dg-do compile }
-// { dg-options "-O2" }
+// { dg-options "-O2 -w" }
 
 extern int foo (int);
 
diff --git a/gcc/testsuite/g++.dg/other/switch3.C b/gcc/testsuite/g++.dg/other/switch3.C
new file mode 100644 (file)
index 0000000..4f9b548
--- /dev/null
@@ -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;
+    }
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr40335.C b/gcc/testsuite/g++.dg/torture/pr40335.C
new file mode 100644 (file)
index 0000000..14ea95d
--- /dev/null
@@ -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 9b05cd16c5deb226190b9987ac9f760a2eb8db83..6a2094466cf5c2984bb0ba6cfc1e526b3aec63cd 100644 (file)
@@ -50,14 +50,14 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
     {
     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;
 }
diff --git a/gcc/testsuite/g++.dg/warn/switch1.C b/gcc/testsuite/g++.dg/warn/switch1.C
new file mode 100644 (file)
index 0000000..49c17e9
--- /dev/null
@@ -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;
+    }
+}