On Fri, Nov 8, 2019 at 1:41 PM Martin Jambor <mjam...@suse.cz> wrote: > > Hi, > > this patch is an attempt to implement my idea from a previous thread > about moving -Wmaybe-uninitialized to -Wextra: > > https://gcc.gnu.org/ml/gcc-patches/2019-02/msg00220.html > > Specifically, it attempts to split -Wmaybe-uninitialized into those that > are about SRA DECLs and those which are not, and move to -Wextra only > the former ones. The main idea is that false -Wmaybe-uninitialized > warings about values that are scalar in user's code are easy to silence > by initializing them to zero or something, as opposed to bits of > aggregates such as a value in std::optional which are not. Therefore, > the warnings about user-scalars can remain in -Wall but warnings about > SRAed pieces should be moved to -Wextra. > > The patch is a bit bigger because of documentation (which I'll be happy > to improve based on your suggestions) and testsuite churn, but the main > bit is the following added test in warn_uninit function: > > if (wc == OPT_Wmaybe_uninitialized > && SSA_NAME_VAR (t) > && DECL_ARTIFICIAL (SSA_NAME_VAR (t)) > && DECL_HAS_DEBUG_EXPR_P (SSA_NAME_VAR (t))) > { > if (warn_maybe_uninitialized_aggregates) > wc = OPT_Wmaybe_uninitialized_aggregates; > else > return; > }
I wonder if this works in practice since the whole point of SRA is to have things copy propagated out (so the 't' with the SSA_NAME_VAR doesn't prevail or gets commoned with sth else). Or is this about the default defs SRA creates itself to actually emit uninit warnings? > The reason why I also test DECL_HAS_DEBUG_EXPR_P is > gfortran.dg/pr39666-2.f90 - without it the test silences a warning about > a decl representing the return value which is an artificial scalar > variable (probably all the way from the front-end). We can of course > not care about not warning for it but then I don't know how to call and > document the new option :-) Generally, if someone can think of a better > test to identify SRA DECLs, I'll be happy to change that. We might put > a bit to identify SRA decls in the decl tree, but I tend to think that > is not a good use of the few remaining bits there. > > What do you think, is something along these lines a good idea? > > Thanks, > > Martin > > > > 2019-11-08 Martin Jambor <mjam...@suse.cz> > > * common.opt (Wmaybe-uninitialized-aggregates): New. > * tree-ssa-uninit.c (gate_warn_uninitialized): Also run if > warn_maybe_uninitialized_aggregates is set. > (warn_uninit): Warn for artificial DECLs only if > warn_maybe_uninitialized_aggregates is set. > * doc/invoke.texi (Warning Options): Add > -Wmaybe-uninitialized-aggregates to the list. > (-Wextra): Likewise. > (-Wmaybe-uninitialized): Document that it only works on scalars. > (-Wmaybe-uninitialized-aggregates): Document. > > testsuite/ > * gcc.dg/pr45083.c: Add Wmaybe-uninitialized-aggregates to options. > * gcc.dg/ubsan/pr81981.c: Likewise. > * gfortran.dg/pr25923.f90: Likewise. > * g++.dg/warn/pr80635.C: New. > --- > gcc/common.opt | 4 +++ > gcc/doc/invoke.texi | 18 +++++++++-- > gcc/testsuite/g++.dg/warn/pr80635.C | 45 +++++++++++++++++++++++++++ > gcc/testsuite/gcc.dg/pr45083.c | 2 +- > gcc/testsuite/gcc.dg/ubsan/pr81981.c | 2 +- > gcc/testsuite/gfortran.dg/pr25923.f90 | 2 +- > gcc/tree-ssa-uninit.c | 14 ++++++++- > 7 files changed, 81 insertions(+), 6 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/warn/pr80635.C > > diff --git a/gcc/common.opt b/gcc/common.opt > index cc279f411d7..03769299df8 100644 > --- a/gcc/common.opt > +++ b/gcc/common.opt > @@ -783,6 +783,10 @@ Wmaybe-uninitialized > Common Var(warn_maybe_uninitialized) Warning EnabledBy(Wuninitialized) > Warn about maybe uninitialized automatic variables. > > +Wmaybe-uninitialized-aggregates > +Common Var(warn_maybe_uninitialized_aggregates) Warning EnabledBy(Wextra) > +Warn about maybe uninitialized automatic parts of aggregates. > + > Wunreachable-code > Common Ignore Warning > Does nothing. Preserved for backward compatibility. > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > index faa7fa95a0e..dbc3219b770 100644 > --- a/gcc/doc/invoke.texi > +++ b/gcc/doc/invoke.texi > @@ -328,7 +328,8 @@ Objective-C and Objective-C++ Dialects}. > -Wzero-length-bounds @gol > -Winvalid-pch -Wlarger-than=@var{byte-size} @gol > -Wlogical-op -Wlogical-not-parentheses -Wlong-long @gol > --Wmain -Wmaybe-uninitialized -Wmemset-elt-size -Wmemset-transposed-args > @gol > +-Wmain -Wmaybe-uninitialized -Wmaybe-uninitialized-aggregates @gol > +-Wmemset-elt-size -Wmemset-transposed-args @gol > -Wmisleading-indentation -Wmissing-attributes -Wmissing-braces @gol > -Wmissing-field-initializers -Wmissing-format-attribute @gol > -Wmissing-include-dirs -Wmissing-noreturn -Wmissing-profile @gol > @@ -4498,6 +4499,7 @@ name is still supported, but the newer name is more > descriptive.) > -Wempty-body @gol > -Wignored-qualifiers @gol > -Wimplicit-fallthrough=3 @gol > +-Wmaybe-uninitialized-aggregates @gol > -Wmissing-field-initializers @gol > -Wmissing-parameter-type @r{(C only)} @gol > -Wold-style-declaration @r{(C only)} @gol > @@ -5690,10 +5692,22 @@ in fact be called at the place that would cause a > problem. > > Some spurious warnings can be avoided if you declare all the functions > you use that never return as @code{noreturn}. @xref{Function > -Attributes}. > +Attributes}. This option only warns about scalar variables, use > +@option{-Wmaybe-uninitialized-aggregates} to enable the warnings on parts of > +aggregates which the compiler can track. > > This warning is enabled by @option{-Wall} or @option{-Wextra}. > > +@item -Wmaybe-uninitialized-aggregates > +@opindex Wmaybe-uninitialized-aggregates > +@opindex Wmaybe-uninitialized-aggregates > + > +This option enables the same warning like @option{-Wmaybe-uninitialized} but > +for parts of aggregates (i.g.@: structures, arrays or unions) that GCC > +optimizers can track. These warnings are only possible in optimizing > +compilation, because otherwise GCC does not keep track of the state of > +variables. This warning is enabled by @option{-Wextra}. > + > @item -Wunknown-pragmas > @opindex Wunknown-pragmas > @opindex Wno-unknown-pragmas > diff --git a/gcc/testsuite/g++.dg/warn/pr80635.C > b/gcc/testsuite/g++.dg/warn/pr80635.C > new file mode 100644 > index 00000000000..eaf6b34a29d > --- /dev/null > +++ b/gcc/testsuite/g++.dg/warn/pr80635.C > @@ -0,0 +1,45 @@ > +// PR C++/80635 > +// { dg-options "-std=c++11 -Wuninitialized -O" } > + > +void* operator new (__SIZE_TYPE__, void *p) { return p; } > + > +int f (); > +int x; > + > +struct A { > + int i; > + A (): i (f ()) { } // { dg-bogus "uninitialized" } > + ~A () { x = i; } > +}; > + > +struct B { > + B (); > + ~B (); > +}; > + > + > +template <class T> > +struct C { > + C (): t (), b () { } > + ~C () { if (b) t.~T (); } > + > + void f () { > + new (&t) T (); > + b = true; > + } > + > + union { > + T t; > + char x[sizeof (T)]; > + }; > + bool b; > +}; > + > +void g () > +{ > + C<A> c1; > + C<B> c2; > + > + c1.f (); > + c2.f (); > +} > diff --git a/gcc/testsuite/gcc.dg/pr45083.c b/gcc/testsuite/gcc.dg/pr45083.c > index c9a4dbfe191..bce7d0bd7a6 100644 > --- a/gcc/testsuite/gcc.dg/pr45083.c > +++ b/gcc/testsuite/gcc.dg/pr45083.c > @@ -1,6 +1,6 @@ > /* PR tree-optimization/45083 */ > /* { dg-do compile } */ > -/* { dg-options "-O2 -Wuninitialized" } */ > +/* { dg-options "-O2 -Wuninitialized -Wmaybe-uninitialized-aggregates" } */ > > struct S { char *a; unsigned b; unsigned c; }; > extern int foo (const char *); > diff --git a/gcc/testsuite/gcc.dg/ubsan/pr81981.c > b/gcc/testsuite/gcc.dg/ubsan/pr81981.c > index b2636d4c934..6a381f6b180 100644 > --- a/gcc/testsuite/gcc.dg/ubsan/pr81981.c > +++ b/gcc/testsuite/gcc.dg/ubsan/pr81981.c > @@ -1,6 +1,6 @@ > /* PR sanitizer/81981 */ > /* { dg-do compile } */ > -/* { dg-options "-O2 -Wmaybe-uninitialized -fsanitize=undefined > -ffat-lto-objects" } */ > +/* { dg-options "-O2 -Wmaybe-uninitialized -Wmaybe-uninitialized-aggregates > -fsanitize=undefined -ffat-lto-objects" } */ > > int v; > > diff --git a/gcc/testsuite/gfortran.dg/pr25923.f90 > b/gcc/testsuite/gfortran.dg/pr25923.f90 > index 3283ba21f32..2ddc3b92485 100644 > --- a/gcc/testsuite/gfortran.dg/pr25923.f90 > +++ b/gcc/testsuite/gfortran.dg/pr25923.f90 > @@ -1,5 +1,5 @@ > ! { dg-do compile } > -! { dg-options "-O -Wuninitialized" } > +! { dg-options "-O -Wuninitialized -Wmaybe-uninitialized-aggregates" } > > module foo > implicit none > diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c > index fe8f8f0bc28..362af73e5d2 100644 > --- a/gcc/tree-ssa-uninit.c > +++ b/gcc/tree-ssa-uninit.c > @@ -134,6 +134,16 @@ warn_uninit (enum opt_code wc, tree t, tree expr, tree > var, > return; > if (!has_undefined_value_p (t)) > return; > + if (wc == OPT_Wmaybe_uninitialized > + && SSA_NAME_VAR (t) > + && DECL_ARTIFICIAL (SSA_NAME_VAR (t)) > + && DECL_HAS_DEBUG_EXPR_P (SSA_NAME_VAR (t))) > + { > + if (warn_maybe_uninitialized_aggregates) > + wc = OPT_Wmaybe_uninitialized_aggregates; > + else > + return; > + } > > /* Anonymous SSA_NAMEs shouldn't be uninitialized, but > ssa_undefined_value_p > can return true if the def stmt of anonymous SSA_NAME is COMPLEX_EXPR > @@ -2622,7 +2632,9 @@ warn_uninitialized_phi (gphi *phi, vec<gphi *> > *worklist, > static bool > gate_warn_uninitialized (void) > { > - return warn_uninitialized || warn_maybe_uninitialized; > + return (warn_uninitialized > + || warn_maybe_uninitialized > + || warn_maybe_uninitialized_aggregates); > } > > namespace { > -- > 2.23.0 >