re PR middle-end/26022 (ICE with references and virtual functions)
authorAndrew Pinski <pinskia@physics.uc.edu>
Wed, 1 Mar 2006 15:15:38 +0000 (15:15 +0000)
committerAndrew Pinski <pinskia@gcc.gnu.org>
Wed, 1 Mar 2006 15:15:38 +0000 (07:15 -0800)
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

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/return-slot1.C [new file with mode: 0644]
gcc/tree-ssa-ccp.c

index b141b3ede910bc5137f3bd9e5305d3849cfcba9a..b912f617a9865e61f3e89dc5031230e096beed6a 100644 (file)
@@ -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
index 81d5f9fa2512225c1eb461c7d11cf6b5fd5c1800..2e8996984e551c2992c9d07f3348a26ae281fd0a 100644 (file)
@@ -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:
index 0b27651048b63bcbfd9d76d4e2bd1075b25259da..d5c50deb8f6dd2b1e2d647c0c2f31fbc9137b03c 100644 (file)
@@ -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 (file)
index 0000000..fcc6cea
--- /dev/null
@@ -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();
+}
index ec70c36d6d37d743674a7db5c791790f6fde84c9..309a2827848989ecdc1f24702213790050fb897d 100644 (file)
@@ -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.  */