===================================================================
@@ -461,6 +461,10 @@
C ObjC C++ ObjC++ Var(warn_main) Init(-1) Warning
Warn about suspicious declarations of \"main\"
+Wmeminit
+C++ Var(warn_meminit) Warning
+Warn about missing member initializers in constructors which leave data uninitialized
+
Wmissing-braces
C ObjC C++ ObjC++ Var(warn_missing_braces) Warning
Warn about possibly missing braces around initializers
===================================================================
@@ -550,7 +550,14 @@
case OPT_Weffc__:
warn_ecpp = value;
if (value)
- warn_nonvdtor = true;
+ {
+ /* Effective C++ rule 12 says to prefer using a mem-initializer
+ to assignment. */
+ warn_meminit = true;
+ /* Effective C++ rule 14 says to declare destructors virtual
+ in polymorphic classes. */
+ warn_nonvdtor = true;
+ }
break;
case OPT_ansi:
===================================================================
@@ -518,13 +518,27 @@
}
}
- /* Effective C++ rule 12 requires that all data members be
- initialized. */
- if (warn_ecpp && init == NULL_TREE && TREE_CODE (type) != ARRAY_TYPE)
- warning_at (DECL_SOURCE_LOCATION (current_function_decl), OPT_Weffc__,
- "%qD should be initialized in the member initialization list",
- member);
+ /* Warn if there is no initializer for a member which will leave data
+ uninitialized. */
+ if (warn_meminit && init == NULL_TREE)
+ {
+ tree field = default_init_uninitialized_part (type);
+ if (field)
+ {
+ if (DECL_P (field))
+ warning_at (DECL_SOURCE_LOCATION (current_function_decl),
+ OPT_Wmeminit,
+ "%qD is not initialized in the member initialization"
+ " list, so %q+#D is uninitialized", member, field);
+ else
+ warning_at (DECL_SOURCE_LOCATION (current_function_decl),
+ OPT_Wmeminit,
+ "%qD is not initialized in the member initialization"
+ " list", member);
+ }
+ }
+
/* Get an lvalue for the data member. */
decl = build_class_member_access_expr (current_class_ref, member,
/*access_path=*/NULL_TREE,
===================================================================
@@ -0,0 +1,72 @@
+// PR c++/2972
+// { dg-do compile }
+// { dg-options "-Wmeminit" }
+
+// Warn when a constructor (user-declared or implicitly-declared)
+// leaves members uninitialized.
+
+struct A
+{
+ int i;
+ A() : i() { } // { dg-bogus "uninitialized" }
+};
+
+struct B
+{
+ int i;
+ B() { } // { dg-warning "'B::i' is not initialized" }
+};
+
+struct C // { dg-bogus "uninitialized" }
+{
+ int i;
+};
+
+struct D
+{
+ C c;
+ D() : c() { } // { dg-bogus "uninitialized" }
+};
+
+struct E
+{
+ int i; // { dg-warning "'F::e' is not initialized" }
+};
+
+struct F
+{
+ E e;
+ F() { }
+};
+
+struct G
+{
+ int i; // { dg-warning "'H::g' is not initialized" }
+};
+
+struct H
+{
+ G g;
+ H(const H&) { }
+};
+
+struct I // { dg-warning "'I::i' is not initialized" }
+{
+ int i;
+};
+
+struct J : I
+{
+ J() { }
+};
+
+struct K // { dg-warning "'K::i' is not initialized" }
+{
+ int i;
+};
+
+struct L : K
+{
+ L(const L&) { }
+};
+
===================================================================
@@ -2371,6 +2371,22 @@
base class does not have a virtual destructor. This warning is enabled
by @option{-Wall}.
+@item -Wmeminit @r{(C++ and Objective-C++ only)}
+@opindex Wmeminit
+@opindex Wno-meminit
+Warn about missing member initializers in constructors which leave data
+uninitialized. A warning will still be given even if the member is
+initialized in the constructor body e.g.
+
+@smallexample
+struct A @{
+ int i;
+ A() @{ i = 0; @} // warning: 'A::i' is not initialized
+@};
+@end smallexample
+
+This warning is enabled if -Weffc++ is specified.
+
@item -Wnarrowing @r{(C++ and Objective-C++ only)}
@opindex Wnarrowing
@opindex Wno-narrowing