OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-structalias.c
index 08d480a..f8532f5 100644 (file)
@@ -303,6 +303,7 @@ static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT);
 static varinfo_t first_or_preceding_vi_for_offset (varinfo_t,
                                                   unsigned HOST_WIDE_INT);
 static varinfo_t lookup_vi_for_tree (tree);
+static inline bool type_can_have_subvars (const_tree);
 
 /* Pool of variable info structures.  */
 static alloc_pool variable_info_pool;
@@ -3275,7 +3276,8 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p,
                return;
 
              cs = *VEC_last (ce_s, *results);
-             if (cs.type == DEREF)
+             if (cs.type == DEREF
+                 && type_can_have_subvars (TREE_TYPE (t)))
                {
                  /* For dereferences this means we have to defer it
                     to solving time.  */
@@ -3733,29 +3735,43 @@ handle_rhs_call (gimple stmt, VEC(ce_s, heap) **results)
       /* As we compute ESCAPED context-insensitive we do not gain
          any precision with just EAF_NOCLOBBER but not EAF_NOESCAPE
         set.  The argument would still get clobbered through the
-        escape solution.
-        ???  We might get away with less (and more precise) constraints
-        if using a temporary for transitively closing things.  */
+        escape solution.  */
       if ((flags & EAF_NOCLOBBER)
           && (flags & EAF_NOESCAPE))
        {
          varinfo_t uses = get_call_use_vi (stmt);
          if (!(flags & EAF_DIRECT))
-           make_transitive_closure_constraints (uses);
-         make_constraint_to (uses->id, arg);
+           {
+             varinfo_t tem = new_var_info (NULL_TREE, "callarg");
+             make_constraint_to (tem->id, arg);
+             make_transitive_closure_constraints (tem);
+             make_copy_constraint (uses, tem->id);
+           }
+         else
+           make_constraint_to (uses->id, arg);
          returns_uses = true;
        }
       else if (flags & EAF_NOESCAPE)
        {
+         struct constraint_expr lhs, rhs;
          varinfo_t uses = get_call_use_vi (stmt);
          varinfo_t clobbers = get_call_clobber_vi (stmt);
+         varinfo_t tem = new_var_info (NULL_TREE, "callarg");
+         make_constraint_to (tem->id, arg);
          if (!(flags & EAF_DIRECT))
-           {
-             make_transitive_closure_constraints (uses);
-             make_transitive_closure_constraints (clobbers);
-           }
-         make_constraint_to (uses->id, arg);
-         make_constraint_to (clobbers->id, arg);
+           make_transitive_closure_constraints (tem);
+         make_copy_constraint (uses, tem->id);
+         make_copy_constraint (clobbers, tem->id);
+         /* Add *tem = nonlocal, do not add *tem = callused as
+            EAF_NOESCAPE parameters do not escape to other parameters
+            and all other uses appear in NONLOCAL as well.  */
+         lhs.type = DEREF;
+         lhs.var = tem->id;
+         lhs.offset = 0;
+         rhs.type = SCALAR;
+         rhs.var = nonlocal_id;
+         rhs.offset = 0;
+         process_constraint (new_constraint (lhs, rhs));
          returns_uses = true;
        }
       else
@@ -3857,9 +3873,11 @@ handle_lhs_call (gimple stmt, tree lhs, int flags, VEC(ce_s, heap) *rhsc,
       tmpc.offset = 0;
       tmpc.type = ADDRESSOF;
       VEC_safe_push (ce_s, heap, rhsc, &tmpc);
+      process_all_all_constraints (lhsc, rhsc);
+      VEC_free (ce_s, heap, rhsc);
     }
-
-  process_all_all_constraints (lhsc, rhsc);
+  else
+    process_all_all_constraints (lhsc, rhsc);
 
   VEC_free (ce_s, heap, lhsc);
 }
@@ -4022,6 +4040,7 @@ find_func_aliases_for_builtin_call (gimple t)
       case BUILT_IN_MEMMOVE_CHK:
       case BUILT_IN_MEMPCPY_CHK:
       case BUILT_IN_STPCPY_CHK:
+      case BUILT_IN_STPNCPY_CHK:
       case BUILT_IN_STRCAT_CHK:
       case BUILT_IN_STRNCAT_CHK:
       case BUILT_IN_TM_MEMCPY:
@@ -4039,7 +4058,8 @@ find_func_aliases_for_builtin_call (gimple t)
                  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY
                  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY
                  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY_CHK
-                 || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY_CHK)
+                 || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY_CHK
+                 || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY_CHK)
                get_constraint_for_ptr_offset (dest, NULL_TREE, &rhsc);
              else
                get_constraint_for (dest, &rhsc);
@@ -4757,6 +4777,7 @@ find_func_clobbers (gimple origt)
          case BUILT_IN_MEMMOVE_CHK:
          case BUILT_IN_MEMPCPY_CHK:
          case BUILT_IN_STPCPY_CHK:
+         case BUILT_IN_STPNCPY_CHK:
          case BUILT_IN_STRCAT_CHK:
          case BUILT_IN_STRNCAT_CHK:
            {
@@ -5040,6 +5061,15 @@ sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack)
   VEC_qsort (fieldoff_s, fieldstack, fieldoff_compare);
 }
 
+/* Return true if T is a type that can have subvars.  */
+
+static inline bool
+type_can_have_subvars (const_tree t)
+{
+  /* Aggregates without overlapping fields can have subvars.  */
+  return TREE_CODE (t) == RECORD_TYPE;
+}
+
 /* Return true if V is a tree that we can have subvars for.
    Normally, this is any aggregate type.  Also complex
    types which are not gimple registers can have subvars.  */
@@ -5055,11 +5085,7 @@ var_can_have_subvars (const_tree v)
   if (!DECL_P (v))
     return false;
 
-  /* Aggregates without overlapping fields can have subvars.  */
-  if (TREE_CODE (TREE_TYPE (v)) == RECORD_TYPE)
-    return true;
-
-  return false;
+  return type_can_have_subvars (TREE_TYPE (v));
 }
 
 /* Return true if T is a type that does contain pointers.  */
@@ -5654,7 +5680,8 @@ intra_create_variable_infos (void)
         Treat restrict qualified references the same.  */
       if (TYPE_RESTRICT (TREE_TYPE (t))
          && ((DECL_BY_REFERENCE (t) && POINTER_TYPE_P (TREE_TYPE (t)))
-             || TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE))
+             || TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
+         && !type_contains_placeholder_p (TREE_TYPE (TREE_TYPE (t))))
        {
          struct constraint_expr lhsc, rhsc;
          varinfo_t vi;