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