OSDN Git Service

2011-01-25 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-structalias.c
index a49f14b..cf1e817 100644 (file)
@@ -4435,12 +4435,14 @@ find_func_aliases (gimple origt)
        do_structure_copy (lhsop, rhsop);
       else
        {
+         enum tree_code code = gimple_assign_rhs_code (t);
+
          get_constraint_for (lhsop, &lhsc);
 
-         if (gimple_assign_rhs_code (t) == POINTER_PLUS_EXPR)
+         if (code == POINTER_PLUS_EXPR)
            get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
                                           gimple_assign_rhs2 (t), &rhsc);
-         else if (gimple_assign_rhs_code (t) == BIT_AND_EXPR
+         else if (code == BIT_AND_EXPR
                   && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST)
            {
              /* Aligning a pointer via a BIT_AND_EXPR is offsetting
@@ -4448,11 +4450,15 @@ find_func_aliases (gimple origt)
              get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
                                             NULL_TREE, &rhsc);
            }
-         else if ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (t))
+         else if ((CONVERT_EXPR_CODE_P (code)
                    && !(POINTER_TYPE_P (gimple_expr_type (t))
                         && !POINTER_TYPE_P (TREE_TYPE (rhsop))))
                   || gimple_assign_single_p (t))
            get_constraint_for_rhs (rhsop, &rhsc);
+         else if (truth_value_p (code))
+           /* Truth value results are not pointer (parts).  Or at least
+              very very unreasonable obfuscation of a part.  */
+           ;
          else
            {
              /* All other operations are merges.  */
@@ -6827,11 +6833,34 @@ ipa_pta_execute (void)
       push_cfun (func);
       current_function_decl = node->decl;
 
-      /* For externally visible functions use local constraints for
-        their arguments.  For local functions we see all callers
-        and thus do not need initial constraints for parameters.  */
       if (node->local.externally_visible)
-       intra_create_variable_infos ();
+       {
+         /* For externally visible functions use local constraints for
+            their arguments.  For local functions we see all callers
+            and thus do not need initial constraints for parameters.  */
+         intra_create_variable_infos ();
+
+         /* We also need to make function return values escape.  Nothing
+            escapes by returning from main though.  */
+         if (!MAIN_NAME_P (DECL_NAME (node->decl)))
+           {
+             varinfo_t fi, rvi;
+             fi = lookup_vi_for_tree (node->decl);
+             rvi = first_vi_for_offset (fi, fi_result);
+             if (rvi && rvi->offset == fi_result)
+               {
+                 struct constraint_expr includes;
+                 struct constraint_expr var;
+                 includes.var = escaped_id;
+                 includes.offset = 0;
+                 includes.type = SCALAR;
+                 var.var = rvi->id;
+                 var.offset = 0;
+                 var.type = SCALAR;
+                 process_constraint (new_constraint (includes, var));
+               }
+           }
+       }
 
       /* Build constriants for the function body.  */
       FOR_EACH_BB_FN (bb, func)