[PATCH] c++: -Wuninitialized for mem-inits and empty classes [PR19808]

Jason Merrill jason@redhat.com
Tue Nov 23 19:42:48 GMT 2021


On 11/19/21 16:57, Marek Polacek wrote:
> This fixes a bogus -Wuninitialized warning: there's nothing to initialize
> in empty classes, so don't add them into our uninitialized set.
> 
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

OK.

> 	PR c++/19808
> 
> gcc/cp/ChangeLog:
> 
> 	* init.c (emit_mem_initializers): Don't add is_really_empty_class
> 	members into uninitialized.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/warn/Wuninitialized-28.C: Make a class nonempty.
> 	* g++.dg/warn/Wuninitialized-29.C: Likewise.
> 	* g++.dg/warn/Wuninitialized-31.C: New test.
> ---
>   gcc/cp/init.c                                 |  3 +-
>   gcc/testsuite/g++.dg/warn/Wuninitialized-28.C |  1 +
>   gcc/testsuite/g++.dg/warn/Wuninitialized-29.C |  1 +
>   gcc/testsuite/g++.dg/warn/Wuninitialized-31.C | 73 +++++++++++++++++++
>   4 files changed, 77 insertions(+), 1 deletion(-)
>   create mode 100644 gcc/testsuite/g++.dg/warn/Wuninitialized-31.C
> 
> diff --git a/gcc/cp/init.c b/gcc/cp/init.c
> index 975f2eda29d..2a4512e462a 100644
> --- a/gcc/cp/init.c
> +++ b/gcc/cp/init.c
> @@ -1470,7 +1470,8 @@ emit_mem_initializers (tree mem_inits)
>       for (tree f = next_initializable_field (TYPE_FIELDS (current_class_type));
>   	 f != NULL_TREE;
>   	 f = next_initializable_field (DECL_CHAIN (f)))
> -      if (!DECL_ARTIFICIAL (f))
> +      if (!DECL_ARTIFICIAL (f)
> +	  && !is_really_empty_class (TREE_TYPE (f), /*ignore_vptr*/false))
>   	uninitialized.add (f);
>   
>     if (mem_inits
> diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-28.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-28.C
> index 7dbbf8719ec..816249c2b9c 100644
> --- a/gcc/testsuite/g++.dg/warn/Wuninitialized-28.C
> +++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-28.C
> @@ -47,6 +47,7 @@ struct F {
>   };
>   
>   struct bar {
> +  int a;
>     bar() {}
>     bar(bar&) {}
>   };
> diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-29.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-29.C
> index bc742997441..da81abf07c9 100644
> --- a/gcc/testsuite/g++.dg/warn/Wuninitialized-29.C
> +++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-29.C
> @@ -47,6 +47,7 @@ struct F {
>   };
>   
>   struct bar {
> +  int a;
>     bar() {}
>     bar(bar&) {}
>   };
> diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-31.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-31.C
> new file mode 100644
> index 00000000000..e22b150db46
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-31.C
> @@ -0,0 +1,73 @@
> +// PR c++/19808
> +// { dg-do compile }
> +// { dg-options "-Wuninitialized" }
> +
> +class AllocatorWithCleanup {
> +public:
> +  int *allocate(int);
> +};
> +class SecBlock {
> +  SecBlock() : m_ptr(m_alloc.allocate(0)) {} // { dg-bogus "uninitialized" }
> +  AllocatorWithCleanup m_alloc;
> +  int *m_ptr;
> +};
> +
> +struct A {
> +  int *allocate(int);
> +};
> +
> +struct B {
> +  int : 0;
> +  int *allocate(int);
> +};
> +
> +struct C : B {
> +};
> +
> +struct D {
> +  char arr[0];
> +  int *allocate(int);
> +};
> +
> +struct E { };
> +
> +struct F {
> +  E arr[10];
> +  int *allocate(int);
> +};
> +
> +struct G {
> +  E e;
> +  int *allocate(int);
> +};
> +
> +struct H {
> +  virtual void foo ();
> +  int *allocate(int);
> +};
> +
> +template<typename T>
> +struct X {
> +  X() : m_ptr(t.allocate(0)) {} // { dg-bogus "uninitialized" }
> +  T t;
> +  int *m_ptr;
> +};
> +
> +struct V {
> +  int a;
> +  int *allocate(int);
> +};
> +
> +struct Z {
> +  Z() : m_ptr(v.allocate(0)) {} // { dg-warning "uninitialized" }
> +  V v;
> +  int *m_ptr;
> +};
> +
> +X<A> x1;
> +X<B> x2;
> +X<C> x3;
> +X<D> x4;
> +X<F> x5;
> +X<G> x6;
> +X<H> x7;
> 
> base-commit: fc6c6f64ecff376902e7e1ef295f2d8518407ab5
> 



More information about the Gcc-patches mailing list