+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.
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
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;
}
+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.
--- /dev/null
+// { 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" } }