===================================================================
@@ -461,6 +461,10 @@ Wmain
C ObjC C++ ObjC++ Var(warn_main) Init(-1) Warning
Warn about suspicious declarations of \"main\"
+Wmeminit
+C++ Var(warn_meminit) Warning
+Warn about POD members which are not initialized in a constructor initialization list
+
Wmissing-braces
C ObjC C++ ObjC++ Var(warn_missing_braces) Warning
Warn about possibly missing braces around initializers
===================================================================
@@ -550,7 +550,14 @@ c_common_handle_option (size_t scode, co
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:
===================================================================
@@ -485,6 +485,42 @@ build_value_init_noctor (tree type, tsub
return build_zero_init (type, NULL_TREE, /*static_storage_p=*/false);
}
+/* Warn if default initialization of MEMBER of type TYPE in constructor
+ * CONS will leave some parts uninitialized. */
+
+static void
+warn_meminit_leaves_uninitialized (tree member, tree type, tree cons)
+{
+ tree field = default_init_uninitialized_part (type);
+ if (!field)
+ return;
+
+ if (DECL_P (field))
+ warning_at (DECL_SOURCE_LOCATION (cons), OPT_Wmeminit,
+ "no member initializer for %qD so %q+#D is uninitialized",
+ member, field);
+ else
+ warning_at (DECL_SOURCE_LOCATION (cons), OPT_Wmeminit,
+ "no member initializer for %qD so it is uninitialized",
+ member);
+}
+
+/* Warn if defaulted constructor CONS for TYPE with no mem-initializer-list
+ will leave uninitialized data. */
+
+void
+warn_missing_meminits (tree type, tree cons)
+{
+ tree mem_inits = sort_mem_initializers (type, NULL_TREE);
+ while (mem_inits)
+ {
+ tree member = TREE_PURPOSE (mem_inits);
+ /* TODO do not warn if brace-or-equal-initializer */
+ warn_meminit_leaves_uninitialized (member, TREE_TYPE (member), cons);
+ mem_inits = TREE_CHAIN (mem_inits);
+ }
+}
+
/* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
arguments. If TREE_LIST is void_type_node, an empty initializer
list was given; if NULL_TREE no initializer was given. */
@@ -518,12 +554,10 @@ perform_member_init (tree member, tree i
}
}
- /* 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 be left
+ uninitialized. */
+ if (warn_meminit && init == NULL_TREE)
+ warn_meminit_leaves_uninitialized (member, type, current_function_decl);
/* Get an lvalue for the data member. */
decl = build_class_member_access_expr (current_class_ref, member,
===================================================================
@@ -1655,6 +1655,10 @@ defaulted_late_check (tree fn)
if (DECL_DELETED_FN (implicit_fn))
DECL_DELETED_FN (fn) = 1;
+
+ if (warn_meminit && (kind == sfk_constructor || kind == sfk_copy_constructor
+ || kind == sfk_move_constructor))
+ warn_missing_meminits (current_class_type, fn);
}
/* Returns true iff FN can be explicitly defaulted, and gives any
===================================================================
@@ -4915,6 +4915,7 @@ extern bool user_provided_p (tree);
extern bool type_has_user_provided_constructor (tree);
extern bool type_has_user_provided_default_constructor (tree);
extern tree default_init_uninitialized_part (tree);
+extern void warn_missing_meminits (tree, tree);
extern bool trivial_default_constructor_is_constexpr (tree);
extern bool type_has_constexpr_default_constructor (tree);
extern bool type_has_virtual_destructor (tree);