From: David Malcolm <dmalcolm@redhat.com>
To: gcc-patches@gcc.gnu.org
Subject: [committed] analyzer: fix uninit false positive with -ftrivial-auto-var-init= [PR106204]
Date: Wed, 6 Jul 2022 07:35:02 -0400 [thread overview]
Message-ID: <20220706113502.3976860-1-dmalcolm@redhat.com> (raw)
-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.
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r13-1517-gb33dd7874523af.
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>
---
gcc/analyzer/region-model.cc | 69 +++++++++++++++----
.../gcc.dg/analyzer/torture/uninit-pr106204.c | 13 ++++
.../gcc.dg/analyzer/uninit-pr106204.c | 17 +++++
3 files changed, 86 insertions(+), 13 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr106204.c
create mode 100644 gcc/testsuite/gcc.dg/analyzer/uninit-pr106204.c
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 5d939327e01..8b7b4e1f697 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -896,17 +896,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;
@@ -959,6 +951,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. */
@@ -982,10 +1015,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;
+}
--
2.26.3
reply other threads:[~2022-07-06 11:35 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220706113502.3976860-1-dmalcolm@redhat.com \
--to=dmalcolm@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).