aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2021-11-19 14:22:10 -0500
committerMarek Polacek <polacek@redhat.com>2021-11-23 15:02:08 -0500
commit4b1d3d8d732bea86c7b2aba46c2a437461020824 (patch)
tree4c71c291334d11e645f9a42f24b90b7d572c36a1
parent7b7318faf7987ae17806a8c84fbaccaf255e7cbf (diff)
downloadgcc-4b1d3d8d732bea86c7b2aba46c2a437461020824.zip
gcc-4b1d3d8d732bea86c7b2aba46c2a437461020824.tar.gz
gcc-4b1d3d8d732bea86c7b2aba46c2a437461020824.tar.bz2
c++: -Wuninitialized for mem-inits and empty classes [PR19808]
This fixes a bogus -Wuninitialized warning: there's nothing to initialize in empty classes, so don't add them into our uninitialized set. 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.
-rw-r--r--gcc/cp/init.c3
-rw-r--r--gcc/testsuite/g++.dg/warn/Wuninitialized-28.C1
-rw-r--r--gcc/testsuite/g++.dg/warn/Wuninitialized-29.C1
-rw-r--r--gcc/testsuite/g++.dg/warn/Wuninitialized-31.C73
4 files changed, 77 insertions, 1 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 975f2ed..2a4512e 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 7dbbf87..816249c 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 bc74299..da81abf 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 0000000..e22b150
--- /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;