This adds a flag to CONSTRUCTOR nodes indicating that for
clobbers this marks the end-of-life of storage as opposed to
just ending the lifetime of the object that occupied it.
The dangling pointer diagnostics uses CLOBBERs but is confused
by those emitted by the C++ frontend for example which emits
them for the second purpose at the start of CTORs.  The issue
is also appearant for aarch64 in PR104092.

Distinguishing the two cases is also necessary for the PR90348 fix.

Bootstrapped and tested on x86_64-unknown-linux-gnu.  I verified
the bogus diagnostic in PR104092 is gone with a cross.

OK for trunk?

Thanks,
Richard.

2022-02-02  Richard Biener  <rguent...@suse.de>

        PR middle-end/90348
        PR middle-end/104092
        * tree-core.h: Document protected_flag use on CONSTRUCTOR nodes.
        * tree.h (CLOBBER_MARKS_EOL): Add.
        * tree-pretty-print.cc (dump_generic_node): Mark EOL CLOBBERs.
        * gimplify.c (gimplify_bind_expr): Mark storage end-of-life clobbers
        with CLOBBER_MARKS_EOL.
        (gimplify_target_expr): Likewise.
        * tree-inline.cc (expand_call_inline): Likewise.
        * tree-ssa-ccp.cc (insert_clobber_before_stack_restore): Likewise.
        * gimple-ssa-warn-access.cc (pass_waccess::check_stmt): Only treat
        CLOBBER_MARKS_EOL clobbers as ending lifetime of storage.

        * gcc.dg/pr87052.c: Adjust.
---
 gcc/gimple-ssa-warn-access.cc  | 4 +++-
 gcc/gimplify.cc                | 2 ++
 gcc/testsuite/gcc.dg/pr87052.c | 2 +-
 gcc/tree-core.h                | 3 +++
 gcc/tree-inline.cc             | 2 ++
 gcc/tree-pretty-print.cc       | 6 +++++-
 gcc/tree-ssa-ccp.cc            | 1 +
 gcc/tree.h                     | 3 +++
 8 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
index ad5e2f4458e..4890737587c 100644
--- a/gcc/gimple-ssa-warn-access.cc
+++ b/gcc/gimple-ssa-warn-access.cc
@@ -4330,7 +4330,9 @@ is_auto_decl (tree x)
 void
 pass_waccess::check_stmt (gimple *stmt)
 {
-  if (m_check_dangling_p && gimple_clobber_p (stmt))
+  if (m_check_dangling_p
+      && gimple_clobber_p (stmt)
+      && CLOBBER_MARKS_EOL (gimple_assign_rhs1 (stmt)))
     {
       /* Ignore clobber statemts in blocks with exceptional edges.  */
       basic_block bb = gimple_bb (stmt);
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index cd4b61362b4..253f2c9af64 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -1476,6 +1476,7 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
              && flag_stack_reuse != SR_NONE)
            {
              tree clobber = build_clobber (TREE_TYPE (t));
+             CLOBBER_MARKS_EOL (clobber) = 1;
              gimple *clobber_stmt;
              clobber_stmt = gimple_build_assign (t, clobber);
              gimple_set_location (clobber_stmt, end_locus);
@@ -6982,6 +6983,7 @@ gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p)
          if (flag_stack_reuse == SR_ALL)
            {
              tree clobber = build_clobber (TREE_TYPE (temp));
+             CLOBBER_MARKS_EOL (clobber) = 1;
              clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
              gimple_push_cleanup (temp, clobber, false, pre_p, true);
            }
diff --git a/gcc/testsuite/gcc.dg/pr87052.c b/gcc/testsuite/gcc.dg/pr87052.c
index 2affc480f4e..18e092c4674 100644
--- a/gcc/testsuite/gcc.dg/pr87052.c
+++ b/gcc/testsuite/gcc.dg/pr87052.c
@@ -38,4 +38,4 @@ void test (void)
    { dg-final { scan-tree-dump-times "c = \"\";"  1 "gimple" } }
    { dg-final { scan-tree-dump-times "d = { *};"  1 "gimple" } }
    { dg-final { scan-tree-dump-times "e = "  1 "gimple" } }
-   { dg-final { scan-tree-dump-times "e = {CLOBBER}"  1 "gimple" } }  */
+   { dg-final { scan-tree-dump-times "e = {CLOBBER\\(eol\\)}"  1 "gimple" } }  
*/
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index e83669f20d8..924a6a2b2cf 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -1281,6 +1281,9 @@ struct GTY(()) tree_base {
        ASM_INLINE_P in
           ASM_EXPR
 
+       CLOBBER_MARKS_EOL in
+          CONSTRUCTOR
+
    side_effects_flag:
 
        TREE_SIDE_EFFECTS in
diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
index 497aa667eb9..47e895dad68 100644
--- a/gcc/tree-inline.cc
+++ b/gcc/tree-inline.cc
@@ -5139,6 +5139,7 @@ expand_call_inline (basic_block bb, gimple *stmt, 
copy_body_data *id,
              && !(id->debug_map && id->debug_map->get (p)))
            {
              tree clobber = build_clobber (TREE_TYPE (*varp));
+             CLOBBER_MARKS_EOL (clobber) = 1;
              gimple *clobber_stmt;
              clobber_stmt = gimple_build_assign (*varp, clobber);
              gimple_set_location (clobber_stmt, gimple_location (stmt));
@@ -5208,6 +5209,7 @@ expand_call_inline (basic_block bb, gimple *stmt, 
copy_body_data *id,
          && !stmt_ends_bb_p (stmt))
        {
          tree clobber = build_clobber (TREE_TYPE (id->retvar));
+         CLOBBER_MARKS_EOL (clobber) = 1;
          gimple *clobber_stmt;
          clobber_stmt = gimple_build_assign (id->retvar, clobber);
          gimple_set_location (clobber_stmt, gimple_location (old_stmt));
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index 6130c307e9a..dad46eb3adb 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -2500,7 +2500,11 @@ dump_generic_node (pretty_printer *pp, tree node, int 
spc, dump_flags_t flags,
          }
        pp_left_brace (pp);
        if (TREE_CLOBBER_P (node))
-         pp_string (pp, "CLOBBER");
+         {
+           pp_string (pp, "CLOBBER");
+           if (CLOBBER_MARKS_EOL (node))
+             pp_string (pp, "(eol)");
+         }
        else if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
                 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
          is_struct_init = true;
diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc
index 48683f04d49..71ac6a2ab34 100644
--- a/gcc/tree-ssa-ccp.cc
+++ b/gcc/tree-ssa-ccp.cc
@@ -2506,6 +2506,7 @@ insert_clobber_before_stack_restore (tree saved_val, tree 
var,
     if (gimple_call_builtin_p (stmt, BUILT_IN_STACK_RESTORE))
       {
        clobber = build_clobber (TREE_TYPE (var));
+       CLOBBER_MARKS_EOL (clobber) = 1;
        clobber_stmt = gimple_build_assign (var, clobber);
 
        i = gsi_for_stmt (stmt);
diff --git a/gcc/tree.h b/gcc/tree.h
index e2157d66d6c..ba9da13a165 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1154,6 +1154,9 @@ extern void omp_clause_range_check_failed (const_tree, 
const char *, int,
    such clobber instructions.  */
 #define TREE_CLOBBER_P(NODE) \
   (TREE_CODE (NODE) == CONSTRUCTOR && TREE_THIS_VOLATILE (NODE))
+/* True if NODE marks the end-of-life of storage.  */
+#define CLOBBER_MARKS_EOL(NODE) \
+  (CONSTRUCTOR_CHECK (NODE)->base.protected_flag)
 
 /* Define fields and accessors for some nodes that represent expressions.  */
 
-- 
2.34.1

Reply via email to