public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-8637] analyzer: fix uninit false positive with -ftrivial-auto-var-init= [PR106204]
@ 2022-07-27 21:55 David Malcolm
  0 siblings, 0 replies; only message in thread
From: David Malcolm @ 2022-07-27 21:55 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:09cb9c88ef8e2c0c89ada9cde2caf1a960db7a77

commit r12-8637-g09cb9c88ef8e2c0c89ada9cde2caf1a960db7a77
Author: David Malcolm <dmalcolm@redhat.com>
Date:   Wed Jul 27 17:38:55 2022 -0400

    analyzer: fix uninit false positive with -ftrivial-auto-var-init= [PR106204]
    
    (cherry picked from r13-1517-gb33dd7874523af)
    
    -fanalyzer handles -ftrivial-auto-var-init= by special-casing
    IFN_DEFERRED_INIT to be a no-op, so that e.g.:
    
      len_2 = .DEFERRED_INIT (4, 2, &"len"[0]);
    
    is treated as a no-op, so that len_2 is still uninitialized after the
    stmt.
    
    PR analyzer/106204 reports that -fanalyzer gives false positives from
    -Wanalyzer-use-of-uninitialized-value on locals that have their address
    taken, due to e.g.:
    
      _1 = .DEFERRED_INIT (4, 2, &"len"[0]);
      len = _1;
    
    where -fanalyzer leaves _1 uninitialized, and then complains about
    the assignment to "len".
    
    Fixed thusly by suppressing the warning when assigning from such SSA
    names.
    
    gcc/analyzer/ChangeLog:
            PR analyzer/106204
            * region-model.cc (within_short_circuited_stmt_p): Move extraction
            of assign_stmt to caller.
            (due_to_ifn_deferred_init_p): New.
            (region_model::check_for_poison): Move extraction of assign_stmt
            from within_short_circuited_stmt_p to here.  Share logic with
            call to due_to_ifn_deferred_init_p.
    
    gcc/testsuite/ChangeLog:
            PR analyzer/106204
            * gcc.dg/analyzer/torture/uninit-pr106204.c: New test.
            * gcc.dg/analyzer/uninit-pr106204.c: New test.
    
    Signed-off-by: David Malcolm <dmalcolm@redhat.com>

Diff:
---
 gcc/analyzer/region-model.cc                       | 69 ++++++++++++++++++----
 .../gcc.dg/analyzer/torture/uninit-pr106204.c      | 13 ++++
 gcc/testsuite/gcc.dg/analyzer/uninit-pr106204.c    | 17 ++++++
 3 files changed, 86 insertions(+), 13 deletions(-)

diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 816b4100f3a..23837a17346 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -895,17 +895,9 @@ region_model::get_gassign_result (const gassign *assign,
 
 static bool
 within_short_circuited_stmt_p (const region_model *model,
-			       region_model_context *ctxt)
+			       const gassign *assign_stmt)
 {
-  gcc_assert (ctxt);
-  const gimple *curr_stmt = ctxt->get_stmt ();
-  if (curr_stmt == NULL)
-    return false;
-
   /* We must have an assignment to a temporary of _Bool type.  */
-  const gassign *assign_stmt = dyn_cast <const gassign *> (curr_stmt);
-  if (!assign_stmt)
-    return false;
   tree lhs = gimple_assign_lhs (assign_stmt);
   if (TREE_TYPE (lhs) != boolean_type_node)
     return false;
@@ -958,6 +950,47 @@ within_short_circuited_stmt_p (const region_model *model,
   return true;
 }
 
+/* Workaround for discarding certain false positives from
+   -Wanalyzer-use-of-uninitialized-value
+   seen with -ftrivial-auto-var-init=.
+
+   -ftrivial-auto-var-init= will generate calls to IFN_DEFERRED_INIT.
+
+   If the address of the var is taken, gimplification will give us
+   something like:
+
+     _1 = .DEFERRED_INIT (4, 2, &"len"[0]);
+     len = _1;
+
+   The result of DEFERRED_INIT will be an uninit value; we don't
+   want to emit a false positive for "len = _1;"
+
+   Return true if ASSIGN_STMT is such a stmt.  */
+
+static bool
+due_to_ifn_deferred_init_p (const gassign *assign_stmt)
+
+{
+  /* We must have an assignment to a decl from an SSA name that's the
+     result of a IFN_DEFERRED_INIT call.  */
+  if (gimple_assign_rhs_code (assign_stmt) != SSA_NAME)
+    return false;
+  tree lhs = gimple_assign_lhs (assign_stmt);
+  if (TREE_CODE (lhs) != VAR_DECL)
+    return false;
+  tree rhs = gimple_assign_rhs1 (assign_stmt);
+  if (TREE_CODE (rhs) != SSA_NAME)
+    return false;
+  const gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
+  const gcall *call = dyn_cast <const gcall *> (def_stmt);
+  if (!call)
+    return false;
+  if (gimple_call_internal_p (call)
+      && gimple_call_internal_fn (call) == IFN_DEFERRED_INIT)
+    return true;
+  return false;
+}
+
 /* Check for SVAL being poisoned, adding a warning to CTXT.
    Return SVAL, or, if a warning is added, another value, to avoid
    repeatedly complaining about the same poisoned value in followup code.  */
@@ -981,10 +1014,20 @@ region_model::check_for_poison (const svalue *sval,
 	  && is_empty_type (sval->get_type ()))
 	return sval;
 
-      /* Special case to avoid certain false positives.  */
-      if (pkind == POISON_KIND_UNINIT
-	  && within_short_circuited_stmt_p (this, ctxt))
-	  return sval;
+      if (pkind == POISON_KIND_UNINIT)
+	if (const gimple *curr_stmt = ctxt->get_stmt ())
+	  if (const gassign *assign_stmt
+		= dyn_cast <const gassign *> (curr_stmt))
+	    {
+	      /* Special case to avoid certain false positives.  */
+	      if (within_short_circuited_stmt_p (this, assign_stmt))
+		return sval;
+
+	      /* Special case to avoid false positive on
+		 -ftrivial-auto-var-init=.  */
+	      if (due_to_ifn_deferred_init_p (assign_stmt))
+		return sval;
+	  }
 
       /* If we have an SSA name for a temporary, we don't want to print
 	 '<unknown>'.
diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr106204.c b/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr106204.c
new file mode 100644
index 00000000000..25edcf5eecc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr106204.c
@@ -0,0 +1,13 @@
+/* { dg-additional-options "-ftrivial-auto-var-init=zero" } */
+
+int foo(unsigned *len);
+int test_1()
+{
+ unsigned len; /* { dg-bogus "uninit" } */
+ int rc;
+
+ rc = foo(&len);
+ if (!rc)
+  rc = len;
+ return rc;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-pr106204.c b/gcc/testsuite/gcc.dg/analyzer/uninit-pr106204.c
new file mode 100644
index 00000000000..7d7cf7bfc7e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/uninit-pr106204.c
@@ -0,0 +1,17 @@
+/* { dg-additional-options "-ftrivial-auto-var-init=zero" } */
+
+int foo(unsigned *len);
+
+/* Modified version of reproducer that does use "len" before init.  */
+
+int test_2()
+{
+ unsigned len;
+ int rc;
+
+ rc = len; /* { dg-warning "use of uninitialized value 'len'" } */
+ rc = foo(&len);
+ if (!rc)
+  rc = len;
+ return rc;
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-07-27 21:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-27 21:55 [gcc r12-8637] analyzer: fix uninit false positive with -ftrivial-auto-var-init= [PR106204] David Malcolm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).