]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
warn-access: Fix up check_pointer_uses [PR104715]
authorJakub Jelinek <jakub@redhat.com>
Tue, 1 Mar 2022 20:05:31 +0000 (21:05 +0100)
committerJakub Jelinek <jakub@redhat.com>
Tue, 1 Mar 2022 20:05:31 +0000 (21:05 +0100)
The following testcase emits bogus -Wdangling-pointer warnings.
The bug is that when it sees that ptr immediate use is a call that
returns one of its arguments, it will assume that the return value
is based on ptr, but that is the case only if ptr is passed to the
argument that is actually returned (so e.g. for memcpy the first argument,
etc.).  When the builtins guarantee e.g. that the result is based on the
first argument (either ERF_RETURNS_ARG 0 in which case it will always
just returns the first argument as is, or when it is something like
strstr or strpbrk or mempcpy that it returns some pointer based on the
first argument), it means the result is not based on second or following
argument if any.  The second hunk fixes this.

The first hunk just removes an unnecessary TREE_CODE check, the code only
pushes SSA_NAMEs into the pointers vector and if it didn't, it uses
      FOR_EACH_IMM_USE_FAST (use_p, iter, ptr)
a few lines below this, which of course requires that ptr is a SSA_NAME.
Tree checking on SSA_NAME_VERSION will already ensure that if it wasn't
a SSA_NAME, we'd ICE.

2022-03-01  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/104715
* gimple-ssa-warn-access.cc (pass_waccess::check_pointer_uses): Don't
unnecessarily test if ptr is a SSA_NAME, it has to be.  Only push lhs
of a call if gimple_call_return_arg is equal to ptr, not just when it
is non-NULL.

* c-c++-common/Wdangling-pointer-7.c: New test.

gcc/gimple-ssa-warn-access.cc
gcc/testsuite/c-c++-common/Wdangling-pointer-7.c [new file with mode: 0644]

index d015c73dfc67a4c0a070731c888b93800084ace3..b7cdad517b307d24c0b53cca14377bbd1af67aa3 100644 (file)
@@ -4169,8 +4169,7 @@ pass_waccess::check_pointer_uses (gimple *stmt, tree ptr,
   for (unsigned i = 0; i != pointers.length (); ++i)
     {
       tree ptr = pointers[i];
-      if (TREE_CODE (ptr) == SSA_NAME
-         && !bitmap_set_bit (visited, SSA_NAME_VERSION (ptr)))
+      if (!bitmap_set_bit (visited, SSA_NAME_VERSION (ptr)))
        /* Avoid revisiting the same pointer.  */
        continue;
 
@@ -4267,7 +4266,7 @@ pass_waccess::check_pointer_uses (gimple *stmt, tree ptr,
 
          if (gcall *call = dyn_cast <gcall *>(use_stmt))
            {
-             if (gimple_call_return_arg (call))
+             if (gimple_call_return_arg (call) == ptr)
                if (tree lhs = gimple_call_lhs (call))
                  if (TREE_CODE (lhs) == SSA_NAME)
                    pointers.safe_push (lhs);
diff --git a/gcc/testsuite/c-c++-common/Wdangling-pointer-7.c b/gcc/testsuite/c-c++-common/Wdangling-pointer-7.c
new file mode 100644 (file)
index 0000000..8423d3b
--- /dev/null
@@ -0,0 +1,36 @@
+/* PR tree-optimization/104715 */
+/* { dg-do compile } */
+/* { dg-options "-Wdangling-pointer" } */
+
+char *
+foo (char *p)
+{
+  {
+    char q[61] = "012345678901234567890123456789012345678901234567890123456789";
+    char *r = q;
+    p = __builtin_strcat (p, r);
+  }
+  return p;    /* { dg-bogus "using dangling pointer" } */
+}
+
+char *
+bar (char *p)
+{
+  {
+    char q[] = "0123456789";
+    char *r = q;
+    p = __builtin_strstr (p, r);
+  }
+  return p;    /* { dg-bogus "using dangling pointer" } */
+}
+
+char *
+baz (char *p)
+{
+  {
+    char q[] = "0123456789";
+    char *r = q;
+    p = __builtin_strpbrk (p, r);
+  }
+  return p;    /* { dg-bogus "using dangling pointer" } */
+}