https://gcc.gnu.org/g:b51998e2208b36fef6a1f68a18fdd6e562f910a4

commit r17-5394-gb51998e2208b36fef6a1f68a18fdd6e562f910a4
Author: Richard Biener <[email protected]>
Date:   Tue Oct 20 09:53:58 2026 +0200

    tree-optimization/128008 - missing PTA constraints for parameter field
    
    The following addresses an issue with the recursion prevention
    when generating fake pointed-to variables for restrict qualified
    parameters.  When we are not creating a fake pointed-to variable
    we have to put in a constraint from NONLOCAL as otherwise the
    points-to set of a restrict qualified variable/field will be empty.
    This also fixes the latent issue that pointed-to types with
    placeholders never got any constraints.
    
            PR tree-optimization/128008
            * gimple-ssa-pta-constraints.cc (create_variable_info_for_1):
            Upon detecting recursion to the same structure type add
            a constraint from nonlocal.
    
            * gcc.dg/torture/pr128008.c: New testcase.

Diff:
---
 gcc/gimple-ssa-pta-constraints.cc       | 86 ++++++++++++++++++---------------
 gcc/testsuite/gcc.dg/torture/pr128008.c | 20 ++++++++
 2 files changed, 67 insertions(+), 39 deletions(-)

diff --git a/gcc/gimple-ssa-pta-constraints.cc 
b/gcc/gimple-ssa-pta-constraints.cc
index 17b5989b06b8..822a8679e0db 100644
--- a/gcc/gimple-ssa-pta-constraints.cc
+++ b/gcc/gimple-ssa-pta-constraints.cc
@@ -3411,27 +3411,31 @@ create_variable_info_for_1 (tree decl, const char 
*name, bool add_id,
       if (POINTER_TYPE_P (decl_type)
          && (TYPE_RESTRICT (decl_type) || add_restrict))
        vi->only_restrict_pointers = 1;
-      if (vi->only_restrict_pointers
-         && !type_contains_placeholder_p (TREE_TYPE (decl_type))
-         && handle_param
-         && !bitmap_bit_p (handled_struct_type,
-                           TYPE_UID (TREE_TYPE (decl_type))))
+      if (handle_param
+         && vi->only_restrict_pointers)
        {
-         varinfo_t rvi;
-         tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
-         DECL_EXTERNAL (heapvar) = 1;
-         if (var_can_have_subvars (heapvar))
-           bitmap_set_bit (handled_struct_type,
-                           TYPE_UID (TREE_TYPE (decl_type)));
-         rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
-                                           true, handled_struct_type);
-         if (var_can_have_subvars (heapvar))
-           bitmap_clear_bit (handled_struct_type,
-                             TYPE_UID (TREE_TYPE (decl_type)));
-         rvi->is_restrict_var = 1;
-         insert_vi_for_tree (heapvar, rvi);
-         make_constraint_from (vi, rvi->id);
-         make_param_constraints (rvi);
+         if (!bitmap_bit_p (handled_struct_type,
+                            TYPE_UID (TREE_TYPE (decl_type)))
+             && !type_contains_placeholder_p (TREE_TYPE (decl_type)))
+           {
+             varinfo_t rvi;
+             tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
+             DECL_EXTERNAL (heapvar) = 1;
+             if (var_can_have_subvars (heapvar))
+               bitmap_set_bit (handled_struct_type,
+                               TYPE_UID (TREE_TYPE (decl_type)));
+             rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
+                                               true, handled_struct_type);
+             if (var_can_have_subvars (heapvar))
+               bitmap_clear_bit (handled_struct_type,
+                                 TYPE_UID (TREE_TYPE (decl_type)));
+             rvi->is_restrict_var = 1;
+             insert_vi_for_tree (heapvar, rvi);
+             make_constraint_from (vi, rvi->id);
+             make_param_constraints (rvi);
+           }
+         else
+           make_constraint_from (vi, nonlocal_id);
        }
       fieldstack.release ();
       return vi;
@@ -3471,26 +3475,30 @@ create_variable_info_for_1 (tree decl, const char 
*name, bool add_id,
       newvi->may_have_pointers = fo->may_have_pointers;
       newvi->only_restrict_pointers = fo->only_restrict_pointers;
       if (handle_param
-         && newvi->only_restrict_pointers
-         && !type_contains_placeholder_p (fo->restrict_pointed_type)
-         && !bitmap_bit_p (handled_struct_type,
-                           TYPE_UID (fo->restrict_pointed_type)))
+         && newvi->only_restrict_pointers)
        {
-         varinfo_t rvi;
-         tree heapvar = build_fake_var_decl (fo->restrict_pointed_type);
-         DECL_EXTERNAL (heapvar) = 1;
-         if (var_can_have_subvars (heapvar))
-           bitmap_set_bit (handled_struct_type,
-                           TYPE_UID (fo->restrict_pointed_type));
-         rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
-                                           true, handled_struct_type);
-         if (var_can_have_subvars (heapvar))
-           bitmap_clear_bit (handled_struct_type,
-                             TYPE_UID (fo->restrict_pointed_type));
-         rvi->is_restrict_var = 1;
-         insert_vi_for_tree (heapvar, rvi);
-         make_constraint_from (newvi, rvi->id);
-         make_param_constraints (rvi);
+         if (!bitmap_bit_p (handled_struct_type,
+                            TYPE_UID (fo->restrict_pointed_type))
+             && !type_contains_placeholder_p (fo->restrict_pointed_type))
+           {
+             varinfo_t rvi;
+             tree heapvar = build_fake_var_decl (fo->restrict_pointed_type);
+             DECL_EXTERNAL (heapvar) = 1;
+             if (var_can_have_subvars (heapvar))
+               bitmap_set_bit (handled_struct_type,
+                               TYPE_UID (fo->restrict_pointed_type));
+             rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
+                                               true, handled_struct_type);
+             if (var_can_have_subvars (heapvar))
+               bitmap_clear_bit (handled_struct_type,
+                                 TYPE_UID (fo->restrict_pointed_type));
+             rvi->is_restrict_var = 1;
+             insert_vi_for_tree (heapvar, rvi);
+             make_constraint_from (newvi, rvi->id);
+             make_param_constraints (rvi);
+           }
+         else
+           make_constraint_from (newvi, nonlocal_id);
        }
       if (i + 1 < fieldstack.length ())
        {
diff --git a/gcc/testsuite/gcc.dg/torture/pr128008.c 
b/gcc/testsuite/gcc.dg/torture/pr128008.c
new file mode 100644
index 000000000000..d01090ab9ad0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr128008.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+
+struct T { int v; struct T *restrict next; };
+
+__attribute__((noipa)) void
+f(struct T *restrict p)
+{
+  p->next->v = 7;
+}
+
+int main()
+{
+  struct T *q = __builtin_malloc(sizeof *q);
+  q->next = __builtin_malloc(sizeof *q);
+  q->next->v = 2;
+  f(q);
+  if (q->next->v != 7)
+    __builtin_abort();
+  return 0;
+}

Reply via email to