OSDN Git Service

2010-01-22 Steve Ellcey <sje@cup.hp.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-nrv.c
index c1e9d60..a825a7a 100644 (file)
@@ -44,7 +44,7 @@ along with GCC; see the file COPYING3.  If not see
    That copy can often be avoided by directly constructing the return value
    into the final destination mandated by the target's ABI.
 
-   This is basically a generic equivalent to the C++ front-end's 
+   This is basically a generic equivalent to the C++ front-end's
    Named Return Value optimization.  */
 
 struct nrv_data
@@ -104,7 +104,7 @@ finalize_nrv_r (tree *tp, int *walk_subtrees, void *data)
    ever encounter languages which prevent this kind of optimization,
    then we could either have the languages register the optimization or
    we could change the gating function to check the current language.  */
-   
+
 static unsigned int
 tree_nrv (void)
 {
@@ -129,6 +129,12 @@ tree_nrv (void)
   if (DECL_NAME (result))
     return 0;
 
+  /* If the result has its address taken then it might be modified
+     by means not detected in the following loop.  Bail out in this
+     case.  */
+  if (TREE_ADDRESSABLE (result))
+    return 0;
+
   /* Look through each block for assignments to the RESULT_DECL.  */
   FOR_EACH_BB (bb)
     {
@@ -178,13 +184,13 @@ tree_nrv (void)
                  || TREE_ADDRESSABLE (found)
                  || DECL_ALIGN (found) > DECL_ALIGN (result)
                  || !useless_type_conversion_p (result_type,
-                                               TREE_TYPE (found)))
+                                                TREE_TYPE (found)))
                return 0;
            }
          else if (gimple_has_lhs (stmt))
            {
              tree addr = get_base_address (gimple_get_lhs (stmt));
-              /* If there's any MODIFY of component of RESULT, 
+              /* If there's any MODIFY of component of RESULT,
                  then bail out.  */
              if (addr && addr == result)
                return 0;
@@ -218,7 +224,7 @@ tree_nrv (void)
       DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (found);
     }
 
-  TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (found);
+  TREE_ADDRESSABLE (result) |= TREE_ADDRESSABLE (found);
 
   /* Now walk through the function changing all references to VAR to be
      RESULT.  */
@@ -262,7 +268,7 @@ gate_pass_return_slot (void)
   return optimize > 0;
 }
 
-struct gimple_opt_pass pass_nrv = 
+struct gimple_opt_pass pass_nrv =
 {
  {
   GIMPLE_PASS,
@@ -349,7 +355,7 @@ execute_return_slot_opt (void)
   return 0;
 }
 
-struct gimple_opt_pass pass_return_slot = 
+struct gimple_opt_pass pass_return_slot =
 {
  {
   GIMPLE_PASS,