+2017-06-29 Peter Bergner <bergner@vnet.ibm.com>
+
+ PR middle-end/81194
+ * cfgexpand.c (expand_gimple_stmt_1): Handle switch statements
+ with only one label.
+ * stmt.c (expand_case): Assert NCASES is greater than one.
+
2017-06-29 Richard Biener <rguenther@suse.de>
* tree-cfg.c (group_case_labels_stmt): Return whether we changed
case GIMPLE_PREDICT:
break;
case GIMPLE_SWITCH:
- expand_case (as_a <gswitch *> (stmt));
+ {
+ gswitch *swtch = as_a <gswitch *> (stmt);
+ if (gimple_switch_num_labels (swtch) == 1)
+ expand_goto (CASE_LABEL (gimple_switch_default_label (swtch)));
+ else
+ expand_case (swtch);
+ }
break;
case GIMPLE_ASM:
expand_asm_stmt (as_a <gasm *> (stmt));
/* cleanup_tree_cfg removes all SWITCH_EXPR with their index
expressions being INTEGER_CST. */
gcc_assert (TREE_CODE (index_expr) != INTEGER_CST);
-
+
+ /* Optimization of switch statements with only one label has already
+ occurred, so we should never see them at this point. */
+ gcc_assert (ncases > 1);
do_pending_stack_adjust ();
--- /dev/null
+// { dg-do compile }
+// { dg-options "-O2 -std=c++17 -fno-exceptions" }
+
+template <class a> struct b { typedef a *c; };
+class e {};
+template <typename a> class d {
+public:
+ typedef typename b<a>::c c;
+ c begin();
+ c end();
+};
+struct f {
+ enum { g } h;
+};
+struct i {
+ d<f *> j();
+};
+struct l {
+ d<i *> k();
+};
+class ac;
+class o {
+public:
+ o(int *, int *, int *, ac *);
+};
+class ac {
+public:
+ ac(e);
+ virtual o *ae(int *, int *, int *, int *);
+};
+class p {
+ void af(f *m) {
+ switch (m->h)
+ case f::g:
+ ag();
+ }
+
+public:
+ void n() {
+ l ah;
+ for (i *ai : ah.k())
+ for (f *m : ai->j())
+ af(m);
+ }
+ virtual void ag() { __builtin_unreachable(); }
+};
+template <typename = int> class an : o {
+public:
+ an(int *, int *, int *, int *, ac *);
+};
+class q : ac {
+public:
+ q() : ac([]() -> e {}()) {}
+ o *ae(int *ap, int *aq, int *ar, int *as) { an(ap, aq, ar, as, this); }
+};
+template <typename at>
+an<at>::an(int *, int *aq, int *ar, int *as, ac *au) : o(aq, ar, as, au) {
+ p().n();
+}
+void av() { new q; }