This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] c++/2972 warn when ctor-initializer leaves uninitialized data


This is a new version of my -Wmeminit patch, first posted to PR c++/2972.

Jason suggested combining the Wmeminit warning with the adjacent
Weffc++ one which I agree with.  The advice in the Effective C++ book
actually says not to leave members uninitialized, rather than saying
*all* members must have a mem-initializer (which is just annoying in
many cases if the type has a safe default constructor), and my patch
provides a better check for that by only warning when data is left
uninitialized.

Unfortunately this doesn't work very well in C++11 mode, as defaulted
constructors don't cause warnings when they should do e.g.

struct C
{
  int i;
  C() = default;
};

This doesn't produce the same warning as C() {} even though that's
what the defaulted constructor is equivalent to.

I'm posting it for comment and in case anyone else has time to work on it.

        * c-family/c.opt (Wmeminit): Add new option.
        * c-family/c-opts.c: Include it in Wecpp
        * cp/init.c: Implement Wmeminit.
        * doc/invoke.texi: document it.

        * testsuite/g++.dg/warn/Wmeminit.C: New.
Index: c-family/c.opt
===================================================================
--- c-family/c.opt	(revision 181096)
+++ c-family/c.opt	(working copy)
@@ -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
Index: c-family/c-opts.c
===================================================================
--- c-family/c-opts.c	(revision 181096)
+++ c-family/c-opts.c	(working copy)
@@ -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:
Index: cp/init.c
===================================================================
--- cp/init.c	(revision 181096)
+++ cp/init.c	(working copy)
@@ -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,
Index: testsuite/g++.dg/warn/Wmeminit.C
===================================================================
--- testsuite/g++.dg/warn/Wmeminit.C	(revision 0)
+++ testsuite/g++.dg/warn/Wmeminit.C	(revision 0)
@@ -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&) { }
+};
+
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 181096)
+++ doc/invoke.texi	(working copy)
@@ -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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]