aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPeter Bergner <bergner@vnet.ibm.com>2017-06-29 07:58:32 -0500
committerPeter Bergner <bergner@gcc.gnu.org>2017-06-29 07:58:32 -0500
commitf66459c1605ab66390ad5b5c54e425f96607d9eb (patch)
treefc3f329844a8125ad6b273d8b28aeb02e1aa8f15 /gcc
parent3c7bb4891238d341dcd1404cf45b041fc1af0720 (diff)
downloadgcc-f66459c1605ab66390ad5b5c54e425f96607d9eb.zip
gcc-f66459c1605ab66390ad5b5c54e425f96607d9eb.tar.gz
gcc-f66459c1605ab66390ad5b5c54e425f96607d9eb.tar.bz2
re PR middle-end/81194 (ICE during RTL pass: expand)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/cfgexpand.c8
-rw-r--r--gcc/stmt.c5
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/pr81194.C60
5 files changed, 83 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 578068b..c11b478 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index c1f80727..d61c261 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -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));
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 9b5157d..fdf29a5 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -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 ();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ad77af2..2f0b29b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..249fcf3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr81194.C
@@ -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; }