diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-05-07 15:52:06 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-05-07 15:52:06 +0000 |
commit | fa60f42b454d2f8e591d9cf767ac00821dbf2ee2 (patch) | |
tree | 509ac9f873d8887b78813e37442448aa6d8215b2 /gcc/cp/init.c | |
parent | 264cbb51b0d5939683b8f5f628595e165a5a925f (diff) | |
download | gcc-fa60f42b454d2f8e591d9cf767ac00821dbf2ee2.tar.gz |
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
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r-- | gcc/cp/init.c | 83 |
1 files changed, 47 insertions, 36 deletions
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 %<new%> 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 %<new%> 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 %<new%> 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 %<new%> 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 |