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
This commit is contained in:
Jason Merrill 2008-12-02 18:52:02 -05:00 committed by Jason Merrill
parent 1ba62f90e1
commit 3f6079ddc5
7 changed files with 119 additions and 20 deletions

View File

@ -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

View File

@ -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;

View File

@ -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. */

View File

@ -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])
if (init == ridpointers[(int)RID_DEFAULT])
{
/* 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 (!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);

View File

@ -1,3 +1,11 @@
2008-12-02 Jason Merrill <jason@redhat.com>
PR c++/35782, c++/37860
* g++.dg/cpp0x/initlist9.C: New test.
PR c++/37234
* g++.dg/cpp0x/defaulted5.C: New test.
2008-12-02 Jack Howarth <howarth@bromo.med.uc.edu>
* gcc.misc-tests/linkage.exp: Correct file type check for Darwin.

View File

@ -0,0 +1,20 @@
// PR c++/37234
// { dg-do link }
// { dg-options "-std=c++0x" }
template <typename T>
class foo {
public:
foo() =default;
~foo();
};
template <typename T>
foo<T>::~foo() =default;
int main() {
foo<int> fi;
return 0;
}

View File

@ -0,0 +1,29 @@
// PR c++/37860
// { dg-options "-std=c++0x" }
struct b
{
bool t;
b() = default;
~b() = default;
b& operator=(const b&) = delete;
b(const b&) = delete;
b(bool _t): t (_t) { }
};
int main()
{
// copy list initialization
b tst1 = { false };
// copy initialization.
b tst2 = false; // { dg-error "deleted" }
// direct list initialization
b tst3 { false };
// default initialization
b tst4;
}