Commit 2061820e by Jason Merrill Committed by Jason Merrill

DR 990

	DR 990
	* call.c (convert_like_real) [ck_user]: Handle value-initialization.
	(build_new_method_call_1): Likewise.
	* init.c (expand_default_init): Handle direct list-initialization
	of aggregates.

From-SVN: r175639
parent 902233e0
2011-06-29 Jason Merrill <jason@redhat.com>
DR 990
* call.c (convert_like_real) [ck_user]: Handle value-initialization.
(build_new_method_call_1): Likewise.
* init.c (expand_default_init): Handle direct list-initialization
of aggregates.
2011-06-27 Jakub Jelinek <jakub@redhat.com>
* cp-tree.h (union lang_tree_node): Use it in chain_next expression.
......
......@@ -5592,6 +5592,18 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
tree convfn = cand->fn;
unsigned i;
/* If we're initializing from {}, it's value-initialization. */
if (BRACE_ENCLOSED_INITIALIZER_P (expr)
&& CONSTRUCTOR_NELTS (expr) == 0
&& TYPE_HAS_DEFAULT_CONSTRUCTOR (totype))
{
expr = build_value_init (totype, complain);
expr = get_target_expr_sfinae (expr, complain);
if (expr != error_mark_node)
TARGET_EXPR_LIST_INIT_P (expr) = true;
return expr;
}
expr = mark_rvalue_use (expr);
/* When converting from an init list we consider explicit
......@@ -5634,7 +5646,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
{
int nelts = CONSTRUCTOR_NELTS (expr);
if (nelts == 0)
expr = build_value_init (totype, tf_warning_or_error);
expr = build_value_init (totype, complain);
else if (nelts == 1)
expr = CONSTRUCTOR_ELT (expr, 0)->value;
else
......@@ -7138,10 +7150,29 @@ build_new_method_call_1 (tree instance, tree fns, VEC(tree,gc) **args,
&& BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *args, 0))
&& CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *args, 0)))
{
tree init_list = VEC_index (tree, *args, 0);
gcc_assert (VEC_length (tree, *args) == 1
&& !(flags & LOOKUP_ONLYCONVERTING));
add_list_candidates (fns, first_mem_arg, VEC_index (tree, *args, 0),
/* If the initializer list has no elements and T is a class type with
a default constructor, the object is value-initialized. Handle
this here so we don't need to handle it wherever we use
build_special_member_call. */
if (CONSTRUCTOR_NELTS (init_list) == 0
&& TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)
&& !processing_template_decl)
{
tree ob, init = build_value_init (basetype, complain);
if (integer_zerop (instance_ptr))
return get_target_expr_sfinae (init, complain);
ob = build_fold_indirect_ref (instance_ptr);
init = build2 (INIT_EXPR, TREE_TYPE (ob), ob, init);
TREE_SIDE_EFFECTS (init) = true;
return init;
}
add_list_candidates (fns, first_mem_arg, init_list,
basetype, explicit_targs, template_only,
conversion_path, access_binfo, flags, &candidates);
}
......@@ -8365,7 +8396,7 @@ perform_implicit_conversion (tree type, tree expr, tsubst_flags_t complain)
permitted. If the conversion is valid, the converted expression is
returned. Otherwise, NULL_TREE is returned, except in the case
that TYPE is a class type; in that case, an error is issued. If
C_CAST_P is true, then this direction initialization is taking
C_CAST_P is true, then this direct-initialization is taking
place as part of a static_cast being attempted as part of a C-style
cast. */
......
......@@ -1443,6 +1443,17 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
tree rval;
VEC(tree,gc) *parms;
/* If we have direct-initialization from an initializer list, pull
it out of the TREE_LIST so the code below can see it. */
if (init && TREE_CODE (init) == TREE_LIST
&& BRACE_ENCLOSED_INITIALIZER_P (TREE_VALUE (init))
&& CONSTRUCTOR_IS_DIRECT_INIT (TREE_VALUE (init)))
{
gcc_checking_assert ((flags & LOOKUP_ONLYCONVERTING) == 0
&& TREE_CHAIN (init) == NULL_TREE);
init = TREE_VALUE (init);
}
if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
&& CP_AGGREGATE_TYPE_P (type))
{
......
2011-06-29 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/constexpr-initlist4.C: New.
* g++.dg/cpp0x/initlist-value.C: New.
2011-06-29 Richard Sandiford <richard.sandiford@linaro.org>
* gcc.dg/torture/pr49169.c: Restrict to ARM and MIPS targets.
......
// { dg-options -std=c++0x }
struct A { int i; };
struct B: A { constexpr B(): A{} {} };
struct B2: A { constexpr B2(): A{1} {} };
struct C { protected: int i; };
struct D: C { constexpr D(): C{} {} };
// Test for value-initialization via {}
// { dg-options -std=c++0x }
// { dg-do run }
// Empty base so A isn't an aggregate
struct B {};
struct A: B {
int i;
};
struct C: A {
C(): A{} {}
};
int f(A a) { return a.i; }
int main()
{
A a{};
C c;
if (a.i != 0
|| c.i != 0
|| A{}.i != 0
|| f({}) != 0)
return 1;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment