re PR tree-optimization/82128 (ICE on valid code)
authorRichard Biener <rguenther@suse.de>
Wed, 13 Sep 2017 08:13:03 +0000 (08:13 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 13 Sep 2017 08:13:03 +0000 (08:13 +0000)
2017-09-13  Richard Biener  <rguenther@suse.de>

PR middle-end/82128
* gimple-fold.c (gimple_fold_call): Update SSA name in-place to
default-def to avoid breaking iterator update with the weird
interaction with cgraph_update_edges_for_call_stmt_node.

* g++.dg/pr82128.C: New testcase.

From-SVN: r252062

gcc/ChangeLog
gcc/gimple-fold.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/pr82128.C [new file with mode: 0644]

index 26a7b75a45e337610dcd3abbdaf41639357cca64..e73946b1b1d780f058c2a6751d0ac78c53cc31d5 100644 (file)
@@ -1,3 +1,10 @@
+2017-09-13  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/82128
+       * gimple-fold.c (gimple_fold_call): Update SSA name in-place to
+       default-def to avoid breaking iterator update with the weird
+       interaction with cgraph_update_edges_for_call_stmt_node.
+
 2017-09-13  Richard Biener  <rguenther@suse.de>
 
        * tree-cfg.c (verify_gimple_assign_binary): Add verification
index a1dce4c5c6bfaba872d029329188688c97e761fb..0ec225610aa207591fdcb840c6700f2d170c97cc 100644 (file)
@@ -3862,24 +3862,18 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
                  tree fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
                  gimple *new_stmt = gimple_build_call (fndecl, 0);
                  gimple_set_location (new_stmt, gimple_location (stmt));
+                 /* If the call had a SSA name as lhs morph that into
+                    an uninitialized value.  */
                  if (lhs && TREE_CODE (lhs) == SSA_NAME)
                    {
                      tree var = create_tmp_var (TREE_TYPE (lhs));
-                     tree def = get_or_create_ssa_default_def (cfun, var);
-
-                     /* To satisfy condition for
-                        cgraph_update_edges_for_call_stmt_node,
-                        we need to preserve GIMPLE_CALL statement
-                        at position of GSI iterator.  */
-                     update_call_from_tree (gsi, def);
-                     gsi_insert_before (gsi, new_stmt, GSI_NEW_STMT);
-                   }
-                 else
-                   {
-                     gimple_set_vuse (new_stmt, gimple_vuse (stmt));
-                     gimple_set_vdef (new_stmt, gimple_vdef (stmt));
-                     gsi_replace (gsi, new_stmt, false);
+                     SET_SSA_NAME_VAR_OR_IDENTIFIER (lhs, var);
+                     SSA_NAME_DEF_STMT (lhs) = gimple_build_nop ();
+                     set_ssa_default_def (cfun, var, lhs);
                    }
+                 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
+                 gimple_set_vdef (new_stmt, gimple_vdef (stmt));
+                 gsi_replace (gsi, new_stmt, false);
                  return true;
                }
            }
index ed0a85863638e3dadf00d97b8f3f54bfa446bc2b..c0b0e9ac232f8dcf3ae619badbd231fab09107df 100644 (file)
@@ -1,3 +1,10 @@
+2017-09-13  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/82128
+       * gimple-fold.c (gimple_fold_call): Update SSA name in-place to
+       default-def to avoid breaking iterator update with the weird
+       interaction with cgraph_update_edges_for_call_stmt_node.
+
 2017-09-13  Kugan Vivekanandarajah  <kuganv@linaro.org>
 
        * gcc.target/aarch64/pr63304_1.c: Remove-mno-fix-cortex-a53-843419.
diff --git a/gcc/testsuite/g++.dg/pr82128.C b/gcc/testsuite/g++.dg/pr82128.C
new file mode 100644 (file)
index 0000000..98bb27a
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-do compile }
+// { dg-options "-O3 -fno-tree-forwprop" }
+
+class A {
+      virtual unsigned long m_fn1() const;
+        virtual int &m_fn2(unsigned long) const;
+};
+class C : A {
+public:
+      int &m_fn2(unsigned long) const;
+        unsigned long m_fn1() const;
+};
+class B {
+      void m_fn3(const A &, const int &, const C &, int &) const;
+};
+void B::m_fn3(const A &, const int &, const C &, int &) const {
+      C &a(a);
+        for (long b = 0; a.m_fn1(); b++)
+             a.m_fn2(0);
+}