diff options
author | Jason Merrill <jason@redhat.com> | 2008-12-02 18:52:02 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2008-12-02 18:52:02 -0500 |
commit | 3f6079ddc5aae102d082591ec23f84925e6f8e8f (patch) | |
tree | 262be80ee636ba4bc960b1d2b5e08a3f8df6719d /gcc/cp | |
parent | 1ba62f90e187e93b37d2bc88a818caa42ad51619 (diff) | |
download | gcc-3f6079ddc5aae102d082591ec23f84925e6f8e8f.zip gcc-3f6079ddc5aae102d082591ec23f84925e6f8e8f.tar.gz gcc-3f6079ddc5aae102d082591ec23f84925e6f8e8f.tar.bz2 |
PR c++/35782, c++/37860
PR c++/35782, c++/37860
* call.c (build_user_type_conversion_1): Remember
list-initialization.
(convert_like_real): Likewise.
(build_over_call): Don't require the copy constructor
for copy-list-initialization.
* cp-tree.h (TARGET_EXPR_LIST_INIT_P): New macro.
PR c++/37234
* decl.c (cp_finish_decl): Handle =default and =delete for
templates, too.
From-SVN: r142379
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/cp/call.c | 20 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 6 | ||||
-rw-r--r-- | gcc/cp/decl.c | 42 |
4 files changed, 62 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 438b3e0..124dc3f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2008-12-02 Jason Merrill <jason@redhat.com> + + PR c++/35782, c++/37860 + * call.c (build_user_type_conversion_1): Remember + list-initialization. + (convert_like_real): Likewise. + (build_over_call): Don't require the copy constructor + for copy-list-initialization. + * cp-tree.h (TARGET_EXPR_LIST_INIT_P): New macro. + + PR c++/37234 + * decl.c (cp_finish_decl): Handle =default and =delete for + templates, too. + 2008-12-01 Jakub Jelinek <jakub@redhat.com> PR c++/38257 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index bbd6a22..273599e 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -2871,6 +2871,10 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) build_identity_conv (TREE_TYPE (expr), expr)); conv->cand = cand; + /* Remember that this was a list-initialization. */ + if (flags & LOOKUP_NO_NARROWING) + conv->check_narrowing = true; + /* Combine it with the second conversion sequence. */ cand->second_conv = merge_conversion_sequences (conv, cand->second_conv); @@ -4579,7 +4583,13 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, /* If this is a constructor or a function returning an aggr type, we need to build up a TARGET_EXPR. */ if (DECL_CONSTRUCTOR_P (convfn)) - expr = build_cplus_new (totype, expr); + { + expr = build_cplus_new (totype, expr); + + /* Remember that this was list-initialization. */ + if (convs->check_narrowing) + TARGET_EXPR_LIST_INIT_P (expr) = true; + } return expr; } @@ -5314,9 +5324,15 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) else arg = cp_build_indirect_ref (arg, 0, complain); + if (TREE_CODE (arg) == TARGET_EXPR + && TARGET_EXPR_LIST_INIT_P (arg)) + { + /* Copy-list-initialization doesn't require the copy constructor + to be defined. */ + } /* [class.copy]: the copy constructor is implicitly defined even if the implementation elided its use. */ - if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn))) + else if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn))) { mark_used (fn); already_used = true; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a03fe9b..7f33ff1 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -89,6 +89,7 @@ framework extensions, you must include this file before toplev.h, not after. DECL_INITIALIZED_P (in VAR_DECL) TYPENAME_IS_CLASS_P (in TYPENAME_TYPE) STMT_IS_FULL_EXPR_P (in _STMT) + TARGET_EXPR_LIST_INIT_P (in TARGET_EXPR) 2: IDENTIFIER_OPNAME_P (in IDENTIFIER_NODE) ICS_THIS_FLAG (in _CONV) DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL) @@ -3463,6 +3464,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define TARGET_EXPR_IMPLICIT_P(NODE) \ TREE_LANG_FLAG_0 (TARGET_EXPR_CHECK (NODE)) +/* True if this TARGET_EXPR is the result of list-initialization of a + temporary. */ +#define TARGET_EXPR_LIST_INIT_P(NODE) \ + TREE_LANG_FLAG_1 (TARGET_EXPR_CHECK (NODE)) + /* An enumeration of the kind of tags that C++ accepts. */ enum tag_types { none_type = 0, /* Not a tag type. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 997c580..d045935 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5504,6 +5504,25 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, } } + if (init && TREE_CODE (decl) == FUNCTION_DECL) + { + if (init == ridpointers[(int)RID_DELETE]) + { + /* FIXME check this is 1st decl. */ + DECL_DELETED_FN (decl) = 1; + DECL_DECLARED_INLINE_P (decl) = 1; + DECL_INITIAL (decl) = error_mark_node; + init = NULL_TREE; + } + else if (init == ridpointers[(int)RID_DEFAULT]) + { + if (!defaultable_fn_p (decl)) + error ("%qD cannot be defaulted", decl); + else + DECL_DEFAULTED_FN (decl) = 1; + } + } + if (processing_template_decl) { bool type_dependent_p; @@ -5765,25 +5784,12 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, { if (init) { - if (init == ridpointers[(int)RID_DELETE]) - { - /* fixme check this is 1st decl */ - DECL_DELETED_FN (decl) = 1; - DECL_DECLARED_INLINE_P (decl) = 1; - DECL_INITIAL (decl) = error_mark_node; - } - else if (init == ridpointers[(int)RID_DEFAULT]) + if (init == ridpointers[(int)RID_DEFAULT]) { - if (!defaultable_fn_p (decl)) - error ("%qD cannot be defaulted", decl); - else - { - /* An out-of-class default definition is defined at - the point where it is explicitly defaulted. */ - DECL_DEFAULTED_FN (decl) = 1; - if (DECL_INITIAL (decl) == error_mark_node) - synthesize_method (decl); - } + /* An out-of-class default definition is defined at + the point where it is explicitly defaulted. */ + if (DECL_INITIAL (decl) == error_mark_node) + synthesize_method (decl); } else error ("function %q#D is initialized like a variable", decl); |