From 3e25010b8399225287a96d5b53a277690a8185f3 Mon Sep 17 00:00:00 2001 From: jason Date: Mon, 12 Apr 2010 19:58:27 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158239 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 11 +++++ gcc/cp/cp-tree.h | 3 +- gcc/cp/init.c | 104 +++++++++++++++++------------------------------- gcc/testsuite/ChangeLog | 5 +++ 4 files changed, 54 insertions(+), 69 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e56c77c35a5..c32e19fcb73 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2010-04-12 Fabien Chene + + 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 PR c++/43611 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 941c49acb54..91f2a9e9883 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 1fb5eb0d069..c1f1cbf4a38 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 int diagnose_uninitialized_cst_or_ref_member_1 (tree, tree, bool, bool); +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 @@ -506,7 +506,6 @@ perform_member_init (tree member, tree init) { if (init == NULL_TREE) { - tree core_type; /* member traversal: note it leaves init NULL */ if (TREE_CODE (type) == REFERENCE_TYPE) permerror (DECL_SOURCE_LOCATION (current_function_decl), @@ -516,14 +515,6 @@ perform_member_init (tree member, tree init) permerror (DECL_SOURCE_LOCATION (current_function_decl), "uninitialized member %qD with % type %qT", member, type); - - core_type = strip_array_types (type); - if (CLASS_TYPE_P (core_type) - && (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, - /*complain=*/true); } else if (TREE_CODE (init) == TREE_LIST) /* There was an explicit member initialization. Do some work @@ -1667,14 +1658,7 @@ constant_value_1 (tree decl, bool integral_p) init = DECL_INITIAL (decl); } if (init == error_mark_node) - { - if (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)) - /* Treat the error as a constant to avoid cascading errors on - excessively recursive template instantiation (c++/9335). */ - return init; - else - return decl; - } + return decl; /* Initializers in templates are generally expanded during instantiation, so before that for const int i(2) INIT is a TREE_LIST with the actual initializer as @@ -1772,18 +1756,13 @@ 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. Returns - the error count. */ + new expression without a new-initializer and a declaration */ -static int +static void diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, - bool using_new, bool complain) + bool using_new) { tree field; - int error_count = 0; - - if (type_has_user_provided_constructor (type)) - return 0; for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) { @@ -1796,46 +1775,36 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, if (TREE_CODE (field_type) == REFERENCE_TYPE) { - ++ 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 (using_new) + error ("uninitialized reference member in %q#T using %", + 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)) { - ++ 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 (using_new) + error ("uninitialized const member in %q#T using %", + 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)) - error_count - += diagnose_uninitialized_cst_or_ref_member_1 (field_type, origin, - using_new, complain); + diagnose_uninitialized_cst_or_ref_member_1 (field_type, + origin, using_new); } - return error_count; } -int -diagnose_uninitialized_cst_or_ref_member (tree type, bool using_new, bool complain) +void +diagnose_uninitialized_cst_or_ref_member (tree type, bool using_new) { - return diagnose_uninitialized_cst_or_ref_member_1 (type, type, using_new, complain); + diagnose_uninitialized_cst_or_ref_member_1 (type, type, using_new); } /* Generate code for a new-expression, including calling the "operator @@ -1924,13 +1893,13 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || *init != NULL); - if (*init == NULL) + if (*init == NULL && !type_has_user_provided_constructor (elt_type)) { - bool maybe_uninitialized_error = false; + 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)) - maybe_uninitialized_error = true; + uninitialized_error = true; /* A new-expression that creates an object of type T initializes that object as follows: @@ -1945,13 +1914,15 @@ 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)) - maybe_uninitialized_error = true; + uninitialized_error = true; - if (maybe_uninitialized_error - && diagnose_uninitialized_cst_or_ref_member (elt_type, - /*using_new=*/true, - complain & tf_error)) - return error_mark_node; + 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 @@ -2200,7 +2171,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, /* But we want to operate on a non-const version to start with, since we'll be modifying the elements. */ non_const_pointer_type = build_pointer_type - (cp_build_qualified_type (type, cp_type_quals (type) & ~TYPE_QUAL_CONST)); + (cp_build_qualified_type (type, TYPE_QUALS (type) & ~TYPE_QUAL_CONST)); data_addr = fold_convert (non_const_pointer_type, data_addr); /* Any further uses of alloc_node will want this type, too. */ @@ -2476,7 +2447,6 @@ build_new (VEC(tree,gc) **placement, tree type, tree nelts, else return error_mark_node; } - nelts = mark_rvalue_use (nelts); nelts = cp_save_expr (cp_convert (sizetype, nelts)); } @@ -3132,8 +3102,6 @@ build_delete (tree type, tree addr, special_function_kind auto_delete, type = TYPE_MAIN_VARIANT (type); - addr = mark_rvalue_use (addr); - if (TREE_CODE (type) == POINTER_TYPE) { bool complete_p = true; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f6fb943000e..4b79ce0a0cf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-04-12 Fabien Chene + + PR c++/25811 + * g++.dg/init/pr25811.C: New test. + 2010-04-12 Rainer Orth * g++.dg/warn/miss-format-1.C: Removed *-*-solaris2.7 from -- 2.11.0