aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Pinski <pinskia@physics.uc.edu>2006-03-01 15:15:38 +0000
committerAndrew Pinski <pinskia@gcc.gnu.org>2006-03-01 07:15:38 -0800
commit1809ff6b9a9fd3ff2097bc802f328d8530ab2420 (patch)
treedbc68e04e55cfcfd5acfe0bb930d61ef8c0bef2c
parentc10bc6e9a0f720a8e8db03c90960017218fe9879 (diff)
downloadgcc-1809ff6b9a9fd3ff2097bc802f328d8530ab2420.zip
gcc-1809ff6b9a9fd3ff2097bc802f328d8530ab2420.tar.gz
gcc-1809ff6b9a9fd3ff2097bc802f328d8530ab2420.tar.bz2
re PR middle-end/26022 (ICE with references and virtual functions)
2006-01-23 Andrew Pinski <pinskia@physics.uc.edu> PR middle-end/26022 Revert: PR middle-end/24437 * tree-ssa-ccp.c (fold_stmt): Move folding of OBJ_TYPE_REF with a call expr to ... * fold-const.c (fold_ternary) <case CALL_EXPR>: Here. 2006-02-28 Andrew Pinski <pinskia@physics.uc.edu> PR middle-end/26022 * g++.dg/opt/return-slot1.C: New test. From-SVN: r111602
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/fold-const.c20
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/opt/return-slot1.C14
-rw-r--r--gcc/tree-ssa-ccp.c34
5 files changed, 62 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b141b3e..b912f61 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2006-01-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR middle-end/26022
+ Revert:
+ PR middle-end/24437
+ * tree-ssa-ccp.c (fold_stmt): Move folding of OBJ_TYPE_REF
+ with a call expr to ...
+ * fold-const.c (fold_ternary) <case CALL_EXPR>: Here.
+
2006-03-01 Diego Novillo <dnovillo@redhat.com>
* tree-vrp.c (extract_range_from_assert): Remove special
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 81d5f9f..2e89969 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -10565,26 +10565,6 @@ fold_ternary (enum tree_code code, tree type, tree op0, tree op1, tree op2)
&& TREE_CODE (TREE_OPERAND (op0, 0)) == FUNCTION_DECL
&& DECL_BUILT_IN (TREE_OPERAND (op0, 0)))
return fold_builtin (TREE_OPERAND (op0, 0), op1, false);
- /* Check for resolvable OBJ_TYPE_REF. The only sorts we can resolve
- here are when we've propagated the address of a decl into the
- object slot. */
- if (TREE_CODE (op0) == OBJ_TYPE_REF
- && lang_hooks.fold_obj_type_ref
- && TREE_CODE (OBJ_TYPE_REF_OBJECT (op0)) == ADDR_EXPR
- && DECL_P (TREE_OPERAND (OBJ_TYPE_REF_OBJECT (op0), 0)))
- {
- tree t;
-
- /* ??? Caution: Broken ADDR_EXPR semantics means that
- looking at the type of the operand of the addr_expr
- can yield an array type. See silly exception in
- check_pointer_types_r. */
-
- t = TREE_TYPE (TREE_TYPE (OBJ_TYPE_REF_OBJECT (op0)));
- t = lang_hooks.fold_obj_type_ref (op0, t);
- if (t)
- return fold_build3 (code, type, t, op1, op2);
- }
return NULL_TREE;
case BIT_FIELD_REF:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0b27651..d5c50de 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-02-28 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR middle-end/26022
+ * g++.dg/opt/return-slot1.C: New test.
+
2006-02-28 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/26136
diff --git a/gcc/testsuite/g++.dg/opt/return-slot1.C b/gcc/testsuite/g++.dg/opt/return-slot1.C
new file mode 100644
index 0000000..fcc6cea
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/return-slot1.C
@@ -0,0 +1,14 @@
+// { dg-do compile }
+// { dg-options "-O2" }
+
+struct A
+{
+ A();
+ virtual A foo() const;
+};
+
+void bar()
+{
+ const A& a=A();
+ a.foo();
+}
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index ec70c36..309a282 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2350,6 +2350,40 @@ fold_stmt (tree *stmt_p)
callee = get_callee_fndecl (rhs);
if (callee && DECL_BUILT_IN (callee))
result = ccp_fold_builtin (stmt, rhs);
+ else
+ {
+ /* Check for resolvable OBJ_TYPE_REF. The only sorts we can resolve
+ here are when we've propagated the address of a decl into the
+ object slot. */
+ /* ??? Should perhaps do this in fold proper. However, doing it
+ there requires that we create a new CALL_EXPR, and that requires
+ copying EH region info to the new node. Easier to just do it
+ here where we can just smash the call operand. Also
+ CALL_EXPR_RETURN_SLOT_OPT needs to be handled correctly and
+ copied, fold_ternary does not have not information. */
+ callee = TREE_OPERAND (rhs, 0);
+ if (TREE_CODE (callee) == OBJ_TYPE_REF
+ && lang_hooks.fold_obj_type_ref
+ && TREE_CODE (OBJ_TYPE_REF_OBJECT (callee)) == ADDR_EXPR
+ && DECL_P (TREE_OPERAND
+ (OBJ_TYPE_REF_OBJECT (callee), 0)))
+ {
+ tree t;
+
+ /* ??? Caution: Broken ADDR_EXPR semantics means that
+ looking at the type of the operand of the addr_expr
+ can yield an array type. See silly exception in
+ check_pointer_types_r. */
+
+ t = TREE_TYPE (TREE_TYPE (OBJ_TYPE_REF_OBJECT (callee)));
+ t = lang_hooks.fold_obj_type_ref (callee, t);
+ if (t)
+ {
+ TREE_OPERAND (rhs, 0) = t;
+ changed = true;
+ }
+ }
+ }
}
/* If we couldn't fold the RHS, hand over to the generic fold routines. */