From: Fabien Chêne Date: Fri, 30 Apr 2010 04:23:00 +0000 (+0000) Subject: re PR c++/43890 (invalid uninitialized reference in class) X-Git-Tag: releases/gcc-4.6.0~7572 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=10ab8f62dbcd15439b2c1a8b6114e4fb4281731a;p=thirdparty%2Fgcc.git re PR c++/43890 (invalid uninitialized reference in class) PR c++/43890 * init.c (diagnose_uninitialized_cst_or_ref_member): check for user-provided constructor while recursing. From-SVN: r158918 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 03bf79b820a4..58815e9b86ae 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2010-04-29 Fabien Chêne + + PR c++/43890 + * init.c (diagnose_uninitialized_cst_or_ref_member): check for + user-provided constructor while recursing. + 2010-04-28 Manuel López-Ibáñez PR c++/9335 diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 5f0f665afe47..70e3d387e9e3 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1779,6 +1779,9 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, { tree field; + if (type_has_user_provided_constructor (type)) + return; + for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) { tree field_type; @@ -1791,8 +1794,8 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, if (TREE_CODE (field_type) == REFERENCE_TYPE) { if (using_new) - error ("uninitialized reference member in %q#T using %", - origin); + error ("uninitialized reference member in %q#T " + "using % without new-initializer", origin); else error ("uninitialized reference member in %q#T", origin); inform (DECL_SOURCE_LOCATION (field), @@ -1802,8 +1805,8 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, if (CP_TYPE_CONST_P (field_type)) { if (using_new) - error ("uninitialized const member in %q#T using %", - origin); + error ("uninitialized const member in %q#T " + "using % without new-initializer", origin); else error ("uninitialized const member in %q#T", origin); inform (DECL_SOURCE_LOCATION (field), @@ -1908,13 +1911,13 @@ 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)) + if (*init == NULL) { - bool uninitialized_error = false; + bool maybe_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; + maybe_uninitialized_error = true; /* A new-expression that creates an object of type T initializes that object as follows: @@ -1929,9 +1932,9 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, const-qualified type, the program is ill-formed; */ if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (elt_type)) - uninitialized_error = true; + maybe_uninitialized_error = true; - if (uninitialized_error) + if (maybe_uninitialized_error) { if (complain & tf_error) diagnose_uninitialized_cst_or_ref_member (elt_type, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7b9a134ba49b..9dfc098770fb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-04-29 Fabien Chêne + + PR c++/43890 + * init.c (diagnose_uninitialized_cst_or_ref_member): check for + user-provided constructor while recursing. + 2010-04-29 Janus Weil PR fortran/42274 diff --git a/gcc/testsuite/g++.dg/init/pr43890.C b/gcc/testsuite/g++.dg/init/pr43890.C new file mode 100644 index 000000000000..1b2807d0d981 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/pr43890.C @@ -0,0 +1,39 @@ +// PR c++/43890 +// { dg-do compile } + +class Outer +{ + public: + Outer() + : i(*this) + { + } + + class Inner + { + public: + Inner(Outer& o) + : o(o) + , i(0) + { + } + + private: + Outer& o; + int const i; + }; + + private: + Inner i; +}; + +class A { + Outer o; +}; + +int main() +{ + A *a = new A; + + return 0; +}