GCC 12 has gained two features for dealing with uninitialized variables:

(a) a new -Wanalyzer-use-of-uninitialized-value warning within -fanalyzer
for interprocedural path-sensitive detection of ununit uses, and

(b) a new -ftrivial-auto-var-init option for mitigating some uses of
uninit variables

It turns out that using (b) was thwarting (a), as it led to -fanalyzer
seeing calls to IFN_DEFERRED_INIT, which -fanalyzer wasn't
special-casing, thus treating it as initializing the variables in
question, and thus silencing -Wanalyzer-use-of-uninitialized-value on
them.

invoke.texi says:

"GCC still considers an automatic variable that doesn't have an explicit
initializer as uninitialized, @option{-Wuninitialized} will still report
warning messages on such automatic variables."

and thus -Wanalyzer-use-of-uninitialized-value ought to as well.

This patch adds special-case handling to -fanalyzer for
IFN_DEFERRED_INIT,  so that -fanalyzer will warn on uninit uses of
variables that are mitigated by -ftrivial-auto-var-init.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.

Not strictly a regression, but as this affects two new GCC 12 features
it seems appropriate to fix in stage 4.

Pushed to trunk as r12-6997-g9b4eee5fd158c4ee75d1f1000debbf5082fb9b56.

gcc/analyzer/ChangeLog:
        PR analyzer/104270
        * region-model.cc (region_model::on_call_pre): Handle
        IFN_DEFERRED_INIT.

gcc/testsuite/ChangeLog:
        PR analyzer/104270
        * gcc.dg/analyzer/uninit-trivial-auto-var-init-pattern.c: New
        test.
        * gcc.dg/analyzer/uninit-trivial-auto-var-init-uninitialized.c:
        New test.
        * gcc.dg/analyzer/uninit-trivial-auto-var-init-zero.c: New test.

Signed-off-by: David Malcolm <dmalc...@redhat.com>
---
 gcc/analyzer/region-model.cc                           | 10 ++++++++++
 .../analyzer/uninit-trivial-auto-var-init-pattern.c    |  7 +++++++
 .../uninit-trivial-auto-var-init-uninitialized.c       |  7 +++++++
 .../analyzer/uninit-trivial-auto-var-init-zero.c       |  7 +++++++
 4 files changed, 31 insertions(+)
 create mode 100644 
gcc/testsuite/gcc.dg/analyzer/uninit-trivial-auto-var-init-pattern.c
 create mode 100644 
gcc/testsuite/gcc.dg/analyzer/uninit-trivial-auto-var-init-uninitialized.c
 create mode 100644 
gcc/testsuite/gcc.dg/analyzer/uninit-trivial-auto-var-init-zero.c

diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 6810cf508d9..4c312b053f8 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -1109,6 +1109,16 @@ region_model::on_call_pre (const gcall *call, 
region_model_context *ctxt,
 
   bool unknown_side_effects = false;
 
+  /* Special-case for IFN_DEFERRED_INIT.
+     We want to report uninitialized variables with -fanalyzer (treating
+     -ftrivial-auto-var-init= as purely a mitigation feature).
+     Handle IFN_DEFERRED_INIT by treating it as no-op: don't touch the
+     lhs of the call, so that it is still uninitialized from the point of
+     view of the analyzer.  */
+  if (gimple_call_internal_p (call)
+      && gimple_call_internal_fn (call) == IFN_DEFERRED_INIT)
+    return false;
+
   /* Some of the cases below update the lhs of the call based on the
      return value, but not all.  Provide a default value, which may
      get overwritten below.  */
diff --git 
a/gcc/testsuite/gcc.dg/analyzer/uninit-trivial-auto-var-init-pattern.c 
b/gcc/testsuite/gcc.dg/analyzer/uninit-trivial-auto-var-init-pattern.c
new file mode 100644
index 00000000000..0b78dc65267
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/uninit-trivial-auto-var-init-pattern.c
@@ -0,0 +1,7 @@
+/* { dg-additional-options "-ftrivial-auto-var-init=pattern" } */
+
+int test_1 (void)
+{
+  int i; /* { dg-message "region created on stack here" } */
+  return i; /* { dg-warning "use of uninitialized value 'i'" } */
+}
diff --git 
a/gcc/testsuite/gcc.dg/analyzer/uninit-trivial-auto-var-init-uninitialized.c 
b/gcc/testsuite/gcc.dg/analyzer/uninit-trivial-auto-var-init-uninitialized.c
new file mode 100644
index 00000000000..124d3a327b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/uninit-trivial-auto-var-init-uninitialized.c
@@ -0,0 +1,7 @@
+/* { dg-additional-options "-ftrivial-auto-var-init=uninitialized" } */
+
+int test_1 (void)
+{
+  int i; /* { dg-message "region created on stack here" } */
+  return i; /* { dg-warning "use of uninitialized value 'i'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-trivial-auto-var-init-zero.c 
b/gcc/testsuite/gcc.dg/analyzer/uninit-trivial-auto-var-init-zero.c
new file mode 100644
index 00000000000..ef7dc674867
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/uninit-trivial-auto-var-init-zero.c
@@ -0,0 +1,7 @@
+/* { dg-additional-options "-ftrivial-auto-var-init=zero" } */
+
+int test_1 (void)
+{
+  int i; /* { dg-message "region created on stack here" } */
+  return i; /* { dg-warning "use of uninitialized value 'i'" } */
+}
-- 
2.26.3

Reply via email to