/* Definitions for C++ parsing and type checking.
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
extern void initialize_vtbl_ptrs (tree);
extern tree build_java_class_ref (tree);
extern tree integral_constant_value (tree);
+extern void diagnose_uninitialized_cst_or_ref_member (tree, bool);
/* in lex.c */
extern void cxx_dup_lang_specific_decl (tree);
/* Handle initialization things in C++.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
static tree build_dtor_call (tree, special_function_kind, int);
static tree build_field_list (tree, tree, int *);
static tree build_vtbl_address (tree);
+static void diagnose_uninitialized_cst_or_ref_member_1 (tree, tree, bool);
/* We are about to generate some complex initialization code.
Conceptually, it is all a single expression. However, we may want
return new_expr;
}
+/* Diagnose uninitialized const members or reference members of type
+ TYPE. USING_NEW is used to disambiguate the diagnostic between a
+ new expression without a new-initializer and a declaration */
+
+static void
+diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin,
+ bool using_new)
+{
+ tree field;
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ tree field_type;
+
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ field_type = strip_array_types (TREE_TYPE (field));
+
+ if (TREE_CODE (field_type) == REFERENCE_TYPE)
+ {
+ if (using_new)
+ error ("uninitialized reference member in %q#T using %<new%>",
+ origin);
+ else
+ error ("uninitialized reference member in %q#T", origin);
+ inform (DECL_SOURCE_LOCATION (field),
+ "%qD should be initialized", field);
+ }
+
+ if (CP_TYPE_CONST_P (field_type))
+ {
+ if (using_new)
+ error ("uninitialized const member in %q#T using %<new%>",
+ origin);
+ else
+ error ("uninitialized const member in %q#T", origin);
+ inform (DECL_SOURCE_LOCATION (field),
+ "%qD should be initialized", field);
+ }
+
+ if (CLASS_TYPE_P (field_type))
+ diagnose_uninitialized_cst_or_ref_member_1 (field_type,
+ origin, using_new);
+ }
+}
+
+void
+diagnose_uninitialized_cst_or_ref_member (tree type, bool using_new)
+{
+ diagnose_uninitialized_cst_or_ref_member_1 (type, type, using_new);
+}
+
/* Generate code for a new-expression, including calling the "operator
new" function, initializing the object, and, if an exception occurs
during construction, cleaning up. The arguments are as for
is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || *init != NULL);
+ if (*init == NULL && !type_has_user_provided_constructor (elt_type))
+ {
+ bool uninitialized_error = false;
+ /* A program that calls for default-initialization [...] of an
+ entity of reference type is ill-formed. */
+ if (CLASSTYPE_REF_FIELDS_NEED_INIT (elt_type))
+ uninitialized_error = true;
+
+ /* A new-expression that creates an object of type T initializes
+ that object as follows:
+ - If the new-initializer is omitted:
+ -- If T is a (possibly cv-qualified) non-POD class type
+ (or array thereof), the object is default-initialized (8.5).
+ [...]
+ -- Otherwise, the object created has indeterminate
+ value. If T is a const-qualified type, or a (possibly
+ cv-qualified) POD class type (or array thereof)
+ containing (directly or indirectly) a member of
+ const-qualified type, the program is ill-formed; */
+
+ if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (elt_type))
+ uninitialized_error = true;
+
+ if (uninitialized_error)
+ {
+ if (complain & tf_error)
+ diagnose_uninitialized_cst_or_ref_member (elt_type,
+ /*using_new*/true);
+ return error_mark_node;
+ }
+ }
+
if (CP_TYPE_CONST_P (elt_type) && *init == NULL
&& !type_has_user_provided_default_constructor (elt_type))
{
--- /dev/null
+// PR c++/25811
+// { dg-do compile }
+
+struct A1
+{
+ int const j; // { dg-message "should be initialized" }
+};
+
+struct A2
+{
+ int const volatile i; // { dg-message "should be initialized" }
+};
+
+struct A3
+{
+ int& ref; // { dg-message "should be initialized" }
+};
+
+struct A4
+{
+ int const& ref; // { dg-message "should be initialized" }
+};
+
+struct A5
+{
+ int& ref; // { dg-message "should be initialized" }
+ int const i; // { dg-message "should be initialized" }
+};
+
+template <class T> struct S1
+{
+ T const i; // { dg-message "should be initialized" }
+};
+
+template <class T> struct S2
+{
+ T const volatile i; // { dg-message "should be initialized" }
+};
+
+template <class T> struct S3
+{
+ T& ref; // { dg-message "should be initialized" }
+};
+
+template <class T> struct S4
+{
+ T const i; // { dg-message "should be initialized" }
+ T& ref; // { dg-message "should be initialized" }
+};
+
+struct X
+{
+ X () : c (0), r (c) {}
+ int const c;
+ int const& r;
+};
+
+struct Y11
+{
+ int const i; // { dg-message "should be initialized" }
+};
+
+struct Y1
+{
+ Y11 a[1];
+};
+
+struct Y22
+{
+ int& ref; // { dg-message "should be initialized" }
+};
+
+struct Y2
+{
+ Y22 a[1];
+};
+
+struct Z1
+{
+ int const i; // { dg-message "should be initialized" }
+};
+
+struct Z2
+{
+ int& ref; // { dg-message "should be initialized" }
+};
+
+struct Z3
+{
+ int const i; // { dg-message "should be initialized" }
+};
+
+struct Z4
+{
+ int& ref; // { dg-message "should be initialized" }
+};
+
+struct Z5
+{
+ int i;
+};
+
+struct Z
+{
+ Z1 z1;
+ Z2 z2;
+ Z3 z3;
+ Z4 z4;
+ Z5 z5;
+};
+
+union U
+{
+ int const i; // { dg-message "should be initialized" }
+};
+
+void f1 ()
+{
+ new A1; // { dg-error "uninitialized const member" }
+}
+
+void f2 ()
+{
+ new A2; // { dg-error "uninitialized const member" }
+}
+
+void f3 ()
+{
+ new A3; // { dg-error "uninitialized reference member" }
+}
+
+void f4 ()
+{
+ new A4; // { dg-error "uninitialized reference member" }
+}
+
+void f5 ()
+{
+ new A5; // { dg-error "uninitialized reference member|uninitialized const member" }
+}
+
+void f6 ()
+{
+ new S1<int>; // { dg-error "uninitialized const member" }
+}
+
+void f7 ()
+{
+ new S2<int>; // { dg-error "uninitialized const member" }
+}
+
+void f8 ()
+{
+ new S3<int>; // { dg-error "uninitialized reference member" }
+}
+
+void f9 ()
+{
+ new S4<int>; // { dg-error "uninitialized reference member|uninitialized const member" }
+}
+
+void f10 ()
+{
+ new X;
+}
+
+void f11 ()
+{
+ new A1[1]; // { dg-error "uninitialized const member" }
+}
+
+void f12 ()
+{
+ new A3[1]; // { dg-error "uninitialized reference member" }
+}
+
+void f13 ()
+{
+ new Y1; // { dg-error "uninitialized const member" }
+}
+
+void f14 ()
+{
+ new Y2; // { dg-error "uninitialized reference member" }
+}
+
+void f15 ()
+{
+ new Z; // { dg-error "uninitialized reference member|uninitialized const member" }
+}
+
+void f16 ()
+{
+ new U; // { dg-error "uninitialized const member" }
+}