aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2008-12-02 18:52:02 -0500
committerJason Merrill <jason@gcc.gnu.org>2008-12-02 18:52:02 -0500
commit3f6079ddc5aae102d082591ec23f84925e6f8e8f (patch)
tree262be80ee636ba4bc960b1d2b5e08a3f8df6719d /gcc/cp
parent1ba62f90e187e93b37d2bc88a818caa42ad51619 (diff)
downloadgcc-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/ChangeLog14
-rw-r--r--gcc/cp/call.c20
-rw-r--r--gcc/cp/cp-tree.h6
-rw-r--r--gcc/cp/decl.c42
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);