Avoid -Wdangling-pointer for by-transparent-reference arguments [PR104436].
authorMartin Sebor <msebor@redhat.com>
Tue, 15 Mar 2022 00:23:08 +0000 (18:23 -0600)
committerMartin Sebor <msebor@redhat.com>
Tue, 15 Mar 2022 00:26:05 +0000 (18:26 -0600)
This change avoids -Wdangling-pointer for by-value arguments transformed
into by-transparent-reference.

Resolves:
PR middle-end/104436 - spurious -Wdangling-pointer assigning local address to a class passed by value

gcc/ChangeLog:

PR middle-end/104436
* gimple-ssa-warn-access.cc (pass_waccess::check_dangling_stores):
Check for warning suppression.  Avoid by-value arguments transformed
into by-transparent-reference.

gcc/testsuite/ChangeLog:

PR middle-end/104436
* c-c++-common/Wdangling-pointer-8.c: New test.
* g++.dg/warn/Wdangling-pointer-5.C: New test.

gcc/gimple-ssa-warn-access.cc
gcc/testsuite/c-c++-common/Wdangling-pointer-8.c [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wdangling-pointer-5.C [new file with mode: 0644]

index 75297ed..879dbcc 100644 (file)
@@ -4511,6 +4511,9 @@ pass_waccess::check_dangling_stores (basic_block bb,
       if (!stmt)
        break;
 
+      if (warning_suppressed_p (stmt, OPT_Wdangling_pointer_))
+       continue;
+
       if (is_gimple_call (stmt)
          && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
        /* Avoid looking before nonconst, nonpure calls since those might
@@ -4536,10 +4539,16 @@ pass_waccess::check_dangling_stores (basic_block bb,
        }
       else if (TREE_CODE (lhs_ref.ref) == SSA_NAME)
        {
-         /* Avoid looking at or before stores into unknown objects.  */
          gimple *def_stmt = SSA_NAME_DEF_STMT (lhs_ref.ref);
          if (!gimple_nop_p (def_stmt))
+           /* Avoid looking at or before stores into unknown objects.  */
            return;
+
+         tree var = SSA_NAME_VAR (lhs_ref.ref);
+         if (TREE_CODE (var) == PARM_DECL && DECL_BY_REFERENCE (var))
+           /* Avoid by-value arguments transformed into by-reference.  */
+           continue;
+
        }
       else if (TREE_CODE (lhs_ref.ref) == MEM_REF)
        {
@@ -4572,6 +4581,8 @@ pass_waccess::check_dangling_stores (basic_block bb,
                      "storing the address of local variable %qD in %qE",
                      rhs_ref.ref, lhs))
        {
+         suppress_warning (stmt, OPT_Wdangling_pointer_);
+
          location_t loc = DECL_SOURCE_LOCATION (rhs_ref.ref);
          inform (loc, "%qD declared here", rhs_ref.ref);
 
diff --git a/gcc/testsuite/c-c++-common/Wdangling-pointer-8.c b/gcc/testsuite/c-c++-common/Wdangling-pointer-8.c
new file mode 100644 (file)
index 0000000..433727d
--- /dev/null
@@ -0,0 +1,20 @@
+/* Verify -Wdangling-pointer is issued only once.
+   { dg-do compile }
+   { dg-options "-O -Wall" } */
+
+void *p;
+
+void escape_global_warn_once (void)
+{
+  int x[5];
+
+  p = &x[3];        // { dg-regexp "\[^\n\r\]+: warning: \[^\n\r\]+ \\\[-Wdangling-pointer.?\\\]" "message" }
+}
+
+
+void escape_param_warn_once (void **p)
+{
+  int x[5];
+
+  *p = &x[3];       // { dg-regexp "\[^\n\r\]+: warning: \[^\n\r\]+ \\\[-Wdangling-pointer.?\\\]" "message" }
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-pointer-5.C b/gcc/testsuite/g++.dg/warn/Wdangling-pointer-5.C
new file mode 100644 (file)
index 0000000..b3d144a
--- /dev/null
@@ -0,0 +1,34 @@
+/* PR middle-end/104436 - spurious -Wdangling-pointer assigning local
+   address to a class passed by value
+   { dg-do compile }
+   { dg-options "-O1 -Wall" } */
+
+struct S
+{
+  S (void *p): p (p) { }
+  S (const S &s): p (s.p) { }
+
+  void *p;
+};
+
+
+void nowarn_assign_by_value (S s)
+{
+  int i;
+  S t (&i);
+  s = t;            // { dg-bogus "-Wdangling-pointer" }
+}
+
+void nowarn_assign_by_value_arg (S s)
+{
+  S t (&s);
+  s = t;            // { dg-bogus "-Wdangling-pointer" }
+}
+
+
+void warn_assign_local_by_reference (S &s)
+{
+  int i;
+  S t (&i);
+  s = t;            // { dg-warning "-Wdangling-pointer" }
+}