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