aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabien ChĂȘne <fabien.chene@gmail.com>2010-04-12 15:58:27 -0400
committerJason Merrill <jason@gcc.gnu.org>2010-04-12 15:58:27 -0400
commit9d809e8f576a99800ee09ab72cbcb1c2b3250c34 (patch)
tree36abb2bf7447b0e5206eeea7e8c01a8c6a31adb3
parentc7392d11305431de870a375c15fb34688d33f447 (diff)
downloadgcc-9d809e8f576a99800ee09ab72cbcb1c2b3250c34.zip
gcc-9d809e8f576a99800ee09ab72cbcb1c2b3250c34.tar.gz
gcc-9d809e8f576a99800ee09ab72cbcb1c2b3250c34.tar.bz2
re PR c++/25811 (No failure creating a POD containing a const member, using new without a new-initializer.)
PR c++/25811 * cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Declare. * init.c (build_new_1): Check for uninitialized const members and uninitialized reference members, when using new without new-initializer. Call diagnose_uninitialized_cst_or_ref_member. (diagnose_uninitialized_cst_or_ref_member): Define, call diagnose_uninitialized_cst_or_ref_member_1. (diagnose_uninitialized_cst_or_ref_member_1): New function. From-SVN: r158239
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/init.c88
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/init/pr25811.C195
5 files changed, 300 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e56c77c..c32e19f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+2010-04-12 Fabien Chene <fabien.chene@gmail.com>
+
+ PR c++/25811
+ * cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Declare.
+ * init.c (build_new_1): Check for uninitialized const members and
+ uninitialized reference members, when using new without
+ new-initializer. Call diagnose_uninitialized_cst_or_ref_member.
+ (diagnose_uninitialized_cst_or_ref_member): Define, call
+ diagnose_uninitialized_cst_or_ref_member_1.
+ (diagnose_uninitialized_cst_or_ref_member_1): New function.
+
2010-04-12 Richard Guenther <rguenther@suse.de>
PR c++/43611
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 941c49a..91f2a9e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1,6 +1,6 @@
/* 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)
@@ -4852,6 +4852,7 @@ extern tree create_temporary_var (tree);
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);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 1bd80ff..c1f1cbf 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1,6 +1,6 @@
/* 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)
@@ -54,6 +54,7 @@ static tree dfs_initialize_vtbl_ptrs (tree, void *);
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
@@ -1753,6 +1754,59 @@ build_raw_new_expr (VEC(tree,gc) *placement, tree type, tree nelts,
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
@@ -1839,6 +1893,38 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
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))
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f6fb943..4b79ce0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-04-12 Fabien Chene <fabien.chene@gmail.com>
+
+ PR c++/25811
+ * g++.dg/init/pr25811.C: New test.
+
2010-04-12 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* g++.dg/warn/miss-format-1.C: Removed *-*-solaris2.7 from
diff --git a/gcc/testsuite/g++.dg/init/pr25811.C b/gcc/testsuite/g++.dg/init/pr25811.C
new file mode 100644
index 0000000..c906a9b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/pr25811.C
@@ -0,0 +1,195 @@
+// 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" }
+}