re PR middle-end/81194 (ICE during RTL pass: expand)
authorPeter Bergner <bergner@vnet.ibm.com>
Thu, 29 Jun 2017 12:58:32 +0000 (07:58 -0500)
committerPeter Bergner <bergner@gcc.gnu.org>
Thu, 29 Jun 2017 12:58:32 +0000 (07:58 -0500)
gcc/
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.

gcc/testsuite/
PR middle-end/81194
* g++.dg/pr81194.C: New test.

From-SVN: r249783

gcc/ChangeLog
gcc/cfgexpand.c
gcc/stmt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/pr81194.C [new file with mode: 0644]

index 578068bd3436cd5fb91f18296a4651be9a3e8f12..c11b478777afc8fea903aa2ae92037c77ce645a8 100644 (file)
@@ -1,3 +1,10 @@
+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
index c1f80727d3060f34bdb96cf7f2a9cbb1a93da84e..d61c261a17241488c749aea58b0d81d045d98bba 100644 (file)
@@ -3566,7 +3566,13 @@ expand_gimple_stmt_1 (gimple *stmt)
     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));
index 9b5157d345bc6bdac2d81f91a3f5d349522246de..fdf29a5c837c68447639c00d53bba8b5192f80ea 100644 (file)
@@ -1142,7 +1142,10 @@ expand_case (gswitch *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 ();
 
index ad77af28b93705b74e5371defd6663fb416c030b..2f0b29ba7004655b4a13251e49d44db87f4173ac 100644 (file)
@@ -1,3 +1,8 @@
+2017-06-29  Peter Bergner  <bergner@vnet.ibm.com>
+
+       PR middle-end/81194
+       * g++.dg/pr81194.C: New test.
+
 2017-06-29  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ipa/80565
diff --git a/gcc/testsuite/g++.dg/pr81194.C b/gcc/testsuite/g++.dg/pr81194.C
new file mode 100644 (file)
index 0000000..249fcf3
--- /dev/null
@@ -0,0 +1,60 @@
+// { 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; }