In this testcase we were crashing while trying to gimplify a switch, because
the types of the switch condition and case constants didn't match.  This ICE
started with my -Wswitch-with-enum-bit-fields fix where I used the unlowered
type so that we're able to get hold of the enum type.  The problem with that
is with ordinary bit-fields: we'll get the underlying type (e.g. long int),
but subsequent perform_integral_promotions promotes that to int, see
cp_perform_integral_promotions.  Fixed by using the type of the condition in
case we're not dealing with an enum bit-field, i.e. do what we've been doing
before the -Wswitch fix, which ought to make this fix very safe.

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

2015-03-27  Marek Polacek  <pola...@redhat.com>

        PR c++/65556
        * semantics.c (finish_switch_cond): If the unlowered type is not an
        enum, use the type of the condition.

        * c-c++-common/pr65556.c: New test.

diff --git gcc/cp/semantics.c gcc/cp/semantics.c
index f325e41..74af7e8 100644
--- gcc/cp/semantics.c
+++ gcc/cp/semantics.c
@@ -1165,6 +1165,8 @@ finish_switch_cond (tree cond, tree switch_stmt)
        }
       /* We want unlowered type here to handle enum bit-fields.  */
       orig_type = unlowered_expr_type (cond);
+      if (TREE_CODE (orig_type) != ENUMERAL_TYPE)
+       orig_type = TREE_TYPE (cond);
       if (cond != error_mark_node)
        {
          /* Warn if the condition has boolean value.  */
diff --git gcc/testsuite/c-c++-common/pr65556.c 
gcc/testsuite/c-c++-common/pr65556.c
index e69de29..c6729a1 100644
--- gcc/testsuite/c-c++-common/pr65556.c
+++ gcc/testsuite/c-c++-common/pr65556.c
@@ -0,0 +1,23 @@
+/* PR c++/65556 */
+/* { dg-do compile } */
+
+struct S
+{
+  long l: 1;
+  long l2: 41;
+  unsigned long ul: 1;
+  unsigned long ul2: 41;
+} s;
+
+void
+fn ()
+{
+  switch (s.l)
+    case 0:;
+  switch (s.ul)
+    case 0:;
+  switch (s.l2)
+    case 0:;
+  switch (s.ul2)
+    case 0:;
+}

        Marek

Reply via email to