@@ -822,6 +822,8 @@ pp_points_to_solution (pretty_printer *buffer, const pt_solution *pt)
pp_string (buffer, "unit-escaped ");
if (pt->null)
pp_string (buffer, "null ");
+ if (pt->const_pool)
+ pp_string (buffer, "const-pool ");
if (pt->vars
&& !bitmap_empty_p (pt->vars))
{
@@ -838,7 +840,8 @@ pp_points_to_solution (pretty_printer *buffer, const pt_solution *pt)
if (pt->vars_contains_nonlocal
|| pt->vars_contains_escaped
|| pt->vars_contains_escaped_heap
- || pt->vars_contains_restrict)
+ || pt->vars_contains_restrict
+ || pt->vars_contains_interposable)
{
const char *comma = "";
pp_string (buffer, " (");
new file mode 100644
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop3" } */
+
+static int a, b;
+int foo (int n, int which)
+{
+ void *p = __builtin_malloc (n);
+ void *q = which ? &a : &b;
+ return p == q;
+}
+
+/* { dg-final { scan-tree-dump "return 0;" "forwprop3" } } */
@@ -484,9 +484,27 @@ ptrs_compare_unequal (tree ptr1, tree ptr2)
}
return !pt_solution_includes (&pi->pt, obj1);
}
-
- /* ??? We'd like to handle ptr1 != NULL and ptr1 != ptr2
- but those require pt.null to be conservatively correct. */
+ else if (TREE_CODE (ptr1) == SSA_NAME)
+ {
+ struct ptr_info_def *pi1 = SSA_NAME_PTR_INFO (ptr1);
+ if (!pi1
+ || pi1->pt.vars_contains_restrict
+ || pi1->pt.vars_contains_interposable)
+ return false;
+ if (integer_zerop (ptr2) && !pi1->pt.null)
+ return true;
+ if (TREE_CODE (ptr2) == SSA_NAME)
+ {
+ struct ptr_info_def *pi2 = SSA_NAME_PTR_INFO (ptr2);
+ if (!pi2
+ || pi2->pt.vars_contains_restrict
+ || pi2->pt.vars_contains_interposable)
+ return false;
+ if ((!pi1->pt.null || !pi2->pt.null)
+ && (!pi1->pt.const_pool || !pi2->pt.const_pool))
+ return !pt_solutions_intersect (&pi1->pt, &pi2->pt);
+ }
+ }
return false;
}
@@ -636,6 +654,9 @@ dump_points_to_solution (FILE *file, struct pt_solution *pt)
if (pt->null)
fprintf (file, ", points-to NULL");
+ if (pt->const_pool)
+ fprintf (file, ", points-to const-pool");
+
if (pt->vars)
{
fprintf (file, ", points-to vars: ");
@@ -643,7 +664,8 @@ dump_points_to_solution (FILE *file, struct pt_solution *pt)
if (pt->vars_contains_nonlocal
|| pt->vars_contains_escaped
|| pt->vars_contains_escaped_heap
- || pt->vars_contains_restrict)
+ || pt->vars_contains_restrict
+ || pt->vars_contains_interposable)
{
const char *comma = "";
fprintf (file, " (");
@@ -47,6 +47,11 @@ struct GTY(()) pt_solution
includes memory at address NULL. */
unsigned int null : 1;
+ /* Nonzero if the points-to set includes a readonly object like a
+ STRING_CST that does not have an underlying declaration but will
+ end up in the constant pool. */
+ unsigned int const_pool : 1;
+
/* Nonzero if the vars bitmap includes a variable included in 'nonlocal'. */
unsigned int vars_contains_nonlocal : 1;
/* Nonzero if the vars bitmap includes a variable included in 'escaped'. */
@@ -6799,8 +6799,7 @@ find_what_var_points_to (tree fndecl, varinfo_t orig_vi)
else if (vi->id == nonlocal_id)
pt->nonlocal = 1;
else if (vi->id == string_id)
- /* Nobody cares - STRING_CSTs are read-only entities. */
- ;
+ pt->const_pool = 1;
else if (vi->id == anything_id
|| vi->id == integer_id)
pt->anything = 1;
@@ -6956,6 +6955,7 @@ pt_solution_ior_into (struct pt_solution *dest, struct pt_solution *src)
dest->escaped |= src->escaped;
dest->ipa_escaped |= src->ipa_escaped;
dest->null |= src->null;
+ dest->const_pool |= src->const_pool ;
dest->vars_contains_nonlocal |= src->vars_contains_nonlocal;
dest->vars_contains_escaped |= src->vars_contains_escaped;
dest->vars_contains_escaped_heap |= src->vars_contains_escaped_heap;
@@ -8128,7 +8128,7 @@ make_pass_build_ealias (gcc::context *ctxt)
/* IPA PTA solutions for ESCAPED. */
struct pt_solution ipa_escaped_pt
- = { true, false, false, false, false,
+ = { true, false, false, false, false, false,
false, false, false, false, false, NULL };
/* Associate node with varinfo DATA. Worker for