re PR c++/89698 (Run-time error due to optimization of field access after cast at...
authorRichard Biener <rguenther@suse.de>
Fri, 3 May 2019 07:07:28 +0000 (07:07 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 3 May 2019 07:07:28 +0000 (07:07 +0000)
2019-05-03  Richard Biener  <rguenther@suse.de>

PR tree-optimization/89698
* gimple-fold.c (canonicalize_constructor_val): Early out
for constants, handle unfolded INTEGER_CSTs as they appear in
C++ virtual table ctors.

* g++.dg/tree-ssa/pr89698.C: New testcase.

From-SVN: r270833

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

index 65df01190cc1ca893fa143e9f985abe0b3c83db1..5973192491a6fbfd03f18a73d987504172546127 100644 (file)
@@ -1,3 +1,10 @@
+2019-05-03  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/89698
+       * gimple-fold.c (canonicalize_constructor_val): Early out
+       for constants, handle unfolded INTEGER_CSTs as they appear in
+       C++ virtual table ctors.
+
 2019-05-03  Richard Biener  <rguenther@suse.de>
 
        * passes.c (execute_function_todo): Remove dead code.
index d3ef05b52433c5065be815ebced880e2f3129657..1b10bae55caa35b44ffe83ca40d67ca64063ace6 100644 (file)
@@ -207,6 +207,9 @@ create_tmp_reg_or_ssa_name (tree type, gimple *stmt)
 tree
 canonicalize_constructor_val (tree cval, tree from_decl)
 {
+  if (CONSTANT_CLASS_P (cval))
+    return cval;
+
   tree orig_cval = cval;
   STRIP_NOPS (cval);
   if (TREE_CODE (cval) == POINTER_PLUS_EXPR
@@ -257,8 +260,15 @@ canonicalize_constructor_val (tree cval, tree from_decl)
        cval = fold_convert (TREE_TYPE (orig_cval), cval);
       return cval;
     }
-  if (TREE_OVERFLOW_P (cval))
-    return drop_tree_overflow (cval);
+  /* In CONSTRUCTORs we may see unfolded constants like (int (*) ()) 0.  */
+  if (TREE_CODE (cval) == INTEGER_CST)
+    {
+      if (TREE_OVERFLOW_P (cval))
+       cval = drop_tree_overflow (cval);
+      if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
+       cval = fold_convert (TREE_TYPE (orig_cval), cval);
+      return cval;
+    }
   return orig_cval;
 }
 
index ad12005d18ee0b99d2cb635944468552bf186e59..660110d04934c2765e52b2f69d0eabfb96df26f5 100644 (file)
@@ -1,3 +1,8 @@
+2019-05-03  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/89698
+       * g++.dg/tree-ssa/pr89698.C: New testcase.
+
 2019-05-02  Iain Sandoe  <iain@sandoe.co.uk>
 
        * g++.dg/ext/instantiate2.C: Remove special-casing for Darwin.
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr89698.C b/gcc/testsuite/g++.dg/tree-ssa/pr89698.C
new file mode 100644 (file)
index 0000000..9d3b408
--- /dev/null
@@ -0,0 +1,29 @@
+// { dg-do compile }
+// { dg-options "-O -fdump-tree-fre1" }
+
+class A {
+    virtual void f(){};
+public:
+    int x;
+    A(int in): x(in) {};
+};
+
+class B: public A {
+public:
+    int y;
+    B(int in):A(in-1), y(in) {};
+};
+
+void bar(void *);
+void test()
+{
+  B b(2);
+  A* bp = &b;
+  void* vp = dynamic_cast<void*>(bp);
+  bar (vp);
+}
+
+// We should be able to constant fold from the virtual table
+// the offset added to bp for the dynamic cast and forward
+// &b to the argument of bar
+// { dg-final { scan-tree-dump "bar \\\(&b" "fre1" } }