From 7af0148f465585c56c9d571b44f8231ecfc24179 Mon Sep 17 00:00:00 2001 From: jason Date: Fri, 7 May 2010 15:52:06 +0000 Subject: [PATCH] PR c++/43951 * init.c (diagnose_uninitialized_cst_or_ref_member_1): Returns the error count. Emit errors only if compain is true. (build_new_1): Do not return error_mark_node if diagnose_uninitialized_cst_or_ref_member_1 does not diagnose any errors. Delay the check for user-provided constructor. (perform_member_init): Adjust. * cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Change the prototype. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159158 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 12 +++++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/init.c | 83 ++++++++++++++++++++++++++++--------------------- gcc/testsuite/ChangeLog | 5 +++ 4 files changed, 65 insertions(+), 37 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 860f4e7476f..d41a95fcccd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2010-05-07 Fabien Chêne + + PR c++/43951 + * init.c (diagnose_uninitialized_cst_or_ref_member_1): Returns the + error count. Emit errors only if compain is true. + (build_new_1): Do not return error_mark_node if + diagnose_uninitialized_cst_or_ref_member_1 does not diagnose any + errors. Delay the check for user-provided constructor. + (perform_member_init): Adjust. + * cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Change the + prototype. + 2010-05-06 Magnus Fromreide Jason Merrill diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 22a7487cf29..05282894580 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4857,7 +4857,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); +extern int diagnose_uninitialized_cst_or_ref_member (tree, bool, 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 a2d9837f66b..e45d2b882b5 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -54,7 +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); +static int diagnose_uninitialized_cst_or_ref_member_1 (tree, tree, bool, bool); /* We are about to generate some complex initialization code. Conceptually, it is all a single expression. However, we may want @@ -522,7 +522,8 @@ perform_member_init (tree member, tree init) && (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type) || CLASSTYPE_REF_FIELDS_NEED_INIT (core_type))) diagnose_uninitialized_cst_or_ref_member (core_type, - /*using_new=*/false); + /*using_new=*/false, + /*complain=*/true); } else if (TREE_CODE (init) == TREE_LIST) /* There was an explicit member initialization. Do some work @@ -1771,16 +1772,18 @@ build_raw_new_expr (VEC(tree,gc) *placement, tree type, tree nelts, /* 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 */ + new expression without a new-initializer and a declaration. Returns + the error count. */ -static void +static int diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, - bool using_new) + bool using_new, bool complain) { tree field; + int error_count = 0; if (type_has_user_provided_constructor (type)) - return; + return 0; for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) { @@ -1793,36 +1796,46 @@ 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 % without new-initializer", origin); - else - error ("uninitialized reference member in %q#T", origin); - inform (DECL_SOURCE_LOCATION (field), - "%qD should be initialized", field); + ++ error_count; + if (complain) + { + if (using_new) + 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), + "%qD should be initialized", field); + } } if (CP_TYPE_CONST_P (field_type)) { - if (using_new) - 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), - "%qD should be initialized", field); + ++ error_count; + if (complain) + { + if (using_new) + 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), + "%qD should be initialized", field); + } } if (CLASS_TYPE_P (field_type)) - diagnose_uninitialized_cst_or_ref_member_1 (field_type, - origin, using_new); + error_count + += diagnose_uninitialized_cst_or_ref_member_1 (field_type, origin, + using_new, complain); } + return error_count; } -void -diagnose_uninitialized_cst_or_ref_member (tree type, bool using_new) +int +diagnose_uninitialized_cst_or_ref_member (tree type, bool using_new, bool complain) { - diagnose_uninitialized_cst_or_ref_member_1 (type, type, using_new); + return diagnose_uninitialized_cst_or_ref_member_1 (type, type, using_new, complain); } /* Generate code for a new-expression, including calling the "operator @@ -1911,13 +1924,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: @@ -1932,15 +1945,13 @@ 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 (complain & tf_error) - diagnose_uninitialized_cst_or_ref_member (elt_type, - /*using_new*/true); - return error_mark_node; - } + if (maybe_uninitialized_error + && diagnose_uninitialized_cst_or_ref_member (elt_type, + /*using_new=*/true, + complain & tf_error)) + return error_mark_node; } if (CP_TYPE_CONST_P (elt_type) && *init == NULL diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 297ae761ddd..08da4e6965d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-05-07 Fabien Chêne + + PR c++/43951 + * g++.dg/init/new29.C: New. + 2010-05-07 Daniel Franke PR fortran/40728 -- 2.11.0