===================================================================
@@ -0,0 +1,13 @@
+// PR c++/48737
+// { dg-options "-std=c++0x" }
+
+template<class T>
+T&& create();
+
+template<class T, class... Args>
+decltype(T{create<Args>()...}, char()) f(int);
+
+template<class, class...>
+char (&f(...))[2];
+
+static_assert(sizeof(f<int[1], int, int>(0)) != 1, "Error");
===================================================================
@@ -0,0 +1,23 @@
+// PR c++/48744
+// { dg-options "-std=c++0x" }
+
+template<class T>
+struct add_rval_ref {
+ typedef T&& type;
+};
+
+template<>
+struct add_rval_ref<void> {
+ typedef void type;
+};
+
+template<class T>
+typename add_rval_ref<T>::type create();
+
+template<class T, class Arg>
+decltype(T{create<Arg>()}, char()) f(int);
+
+template<class, class>
+char (&f(...))[2];
+
+static_assert(sizeof(f<int, void>(0)) != 1, "Error");
===================================================================
@@ -6715,7 +6715,7 @@ cp_build_modify_expr (tree lhs, enum tree_code mod
}
if (check_array_initializer (lhs, lhstype, newrhs))
return error_mark_node;
- newrhs = digest_init (lhstype, newrhs);
+ newrhs = digest_init (lhstype, newrhs, complain);
}
else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
===================================================================
@@ -1435,7 +1435,7 @@ expand_default_init (tree binfo, tree true_exp, tr
{
/* A brace-enclosed initializer for an aggregate. In C++0x this can
happen for direct-initialization, too. */
- init = digest_init (type, init);
+ init = digest_init (type, init, complain);
init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init);
TREE_SIDE_EFFECTS (init) = 1;
finish_expr_stmt (init);
@@ -2375,7 +2375,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type,
"verify length of initializer-list");
}
arraytype = build_cplus_array_type (type, domain);
- vecinit = digest_init (arraytype, vecinit);
+ vecinit = digest_init (arraytype, vecinit, complain);
}
else if (*init)
{
===================================================================
@@ -5203,7 +5203,7 @@ reshape_init_r (tree type, reshape_iter *d, bool f
{
++d->cur;
gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
- return reshape_init (type, init);
+ return reshape_init (type, init, tf_warning_or_error);
}
}
@@ -5238,7 +5238,7 @@ reshape_init_r (tree type, reshape_iter *d, bool f
revised CONSTRUCTOR node is returned. */
tree
-reshape_init (tree type, tree init)
+reshape_init (tree type, tree init, tsubst_flags_t complain)
{
VEC(constructor_elt, gc) *v;
reshape_iter d;
@@ -5264,7 +5264,12 @@ tree
/* Make sure all the element of the constructor were used. Otherwise,
issue an error about exceeding initializers. */
if (d.cur != d.end)
- error ("too many initializers for %qT", type);
+ {
+ if (complain & tf_error)
+ error ("too many initializers for %qT", type);
+ else
+ return error_mark_node;
+ }
return new_init;
}
@@ -5417,7 +5422,7 @@ check_initializer (tree decl, tree init, int flags
init = error_mark_node;
}
else
- init = reshape_init (type, init);
+ init = reshape_init (type, init, tf_warning_or_error);
}
/* If DECL has an array type without a specific bound, deduce the
===================================================================
@@ -797,7 +797,8 @@ check_narrowing (tree type, tree init)
NESTED is true iff we are being called for an element of a CONSTRUCTOR. */
static tree
-digest_init_r (tree type, tree init, bool nested, int flags)
+digest_init_r (tree type, tree init, bool nested, int flags,
+ tsubst_flags_t complain)
{
enum tree_code code = TREE_CODE (type);
@@ -878,7 +879,7 @@ static tree
check_narrowing (type, init);
init = convert_for_initialization (0, type, init, flags,
ICR_INIT, NULL_TREE, 0,
- tf_warning_or_error);
+ complain);
exp = &init;
/* Skip any conversions since we'll be outputting the underlying
@@ -932,20 +933,20 @@ static tree
return convert_for_initialization (NULL_TREE, type, init,
flags,
ICR_INIT, NULL_TREE, 0,
- tf_warning_or_error);
+ complain);
}
}
tree
-digest_init (tree type, tree init)
+digest_init (tree type, tree init, tsubst_flags_t complain)
{
- return digest_init_r (type, init, false, LOOKUP_IMPLICIT);
+ return digest_init_r (type, init, false, LOOKUP_IMPLICIT, complain);
}
tree
digest_init_flags (tree type, tree init, int flags)
{
- return digest_init_r (type, init, false, flags);
+ return digest_init_r (type, init, false, flags, tf_warning_or_error);
}
/* Set of flags used within process_init_constructor to describe the
@@ -1017,7 +1018,8 @@ process_init_constructor_array (tree type, tree in
else
ce->index = size_int (i);
gcc_assert (ce->value);
- ce->value = digest_init_r (TREE_TYPE (type), ce->value, true, LOOKUP_IMPLICIT);
+ ce->value = digest_init_r (TREE_TYPE (type), ce->value, true,
+ LOOKUP_IMPLICIT, tf_warning_or_error);
if (ce->value != error_mark_node)
gcc_assert (same_type_ignoring_top_level_qualifiers_p
@@ -1044,7 +1046,7 @@ process_init_constructor_array (tree type, tree in
tf_warning_or_error);
else
next = build_constructor (init_list_type_node, NULL);
- next = digest_init (TREE_TYPE (type), next);
+ next = digest_init (TREE_TYPE (type), next, tf_warning_or_error);
}
else if (!zero_init_p (TREE_TYPE (type)))
next = build_zero_init (TREE_TYPE (type),
@@ -1124,7 +1126,8 @@ process_init_constructor_record (tree type, tree i
}
gcc_assert (ce->value);
- next = digest_init_r (type, ce->value, true, LOOKUP_IMPLICIT);
+ next = digest_init_r (type, ce->value, true,
+ LOOKUP_IMPLICIT, tf_warning_or_error);
++idx;
}
else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
@@ -1144,7 +1147,8 @@ process_init_constructor_record (tree type, tree i
TARGET_EXPR_DIRECT_INIT_P (next) = true;
}
- next = digest_init_r (TREE_TYPE (field), next, true, LOOKUP_IMPLICIT);
+ next = digest_init_r (TREE_TYPE (field), next, true,
+ LOOKUP_IMPLICIT, tf_warning_or_error);
/* Warn when some struct elements are implicitly initialized. */
warning (OPT_Wmissing_field_initializers,
@@ -1254,7 +1258,8 @@ process_init_constructor_union (tree type, tree in
}
if (ce->value && ce->value != error_mark_node)
- ce->value = digest_init_r (TREE_TYPE (ce->index), ce->value, true, LOOKUP_IMPLICIT);
+ ce->value = digest_init_r (TREE_TYPE (ce->index), ce->value,
+ true, LOOKUP_IMPLICIT, tf_warning_or_error);
return picflag_from_initializer (ce->value);
}
===================================================================
@@ -2369,7 +2369,7 @@ finish_compound_literal (tree type, tree compound_
if (TREE_CODE (type) == ARRAY_TYPE
&& check_array_initializer (NULL_TREE, type, compound_literal))
return error_mark_node;
- compound_literal = reshape_init (type, compound_literal);
+ compound_literal = reshape_init (type, compound_literal, complain);
if (TREE_CODE (type) == ARRAY_TYPE
&& TYPE_DOMAIN (type) == NULL_TREE)
{
@@ -2378,7 +2378,7 @@ finish_compound_literal (tree type, tree compound_
if (type == error_mark_node)
return error_mark_node;
}
- compound_literal = digest_init (type, compound_literal);
+ compound_literal = digest_init (type, compound_literal, complain);
/* Put static/constant array temporaries in static variables, but always
represent class temporaries with TARGET_EXPR so we elide copies. */
if ((!at_function_scope_p () || CP_TYPE_CONST_P (type))
===================================================================
@@ -924,7 +924,7 @@ grokfield (const cp_declarator *declarator,
else if (!processing_template_decl)
{
if (TREE_CODE (init) == CONSTRUCTOR)
- init = digest_init (TREE_TYPE (value), init);
+ init = digest_init (TREE_TYPE (value), init, tf_warning_or_error);
init = maybe_constant_init (init);
if (init != error_mark_node && !TREE_CONSTANT (init))
===================================================================
@@ -5670,7 +5670,7 @@ convert_like_real (conversion *convs, tree expr, t
expr = build2 (COMPLEX_EXPR, totype, real, imag);
return fold_if_not_in_template (expr);
}
- return get_target_expr (digest_init (totype, expr));
+ return get_target_expr (digest_init (totype, expr, complain));
default:
break;
@@ -6032,7 +6032,7 @@ convert_default_arg (tree type, tree arg, tree fn,
arg = break_out_target_exprs (arg);
if (TREE_CODE (arg) == CONSTRUCTOR)
{
- arg = digest_init (type, arg);
+ arg = digest_init (type, arg, tf_warning_or_error);
arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT,
ICR_DEFAULT_ARGUMENT, fn, parmnum,
tf_warning_or_error);
===================================================================
@@ -4875,7 +4875,7 @@ extern tree cxx_comdat_group (tree);
extern bool cp_missing_noreturn_ok_p (tree);
extern void initialize_artificial_var (tree, VEC(constructor_elt,gc) *);
extern tree check_var_type (tree, tree);
-extern tree reshape_init (tree, tree);
+extern tree reshape_init (tree, tree, tsubst_flags_t);
extern tree next_initializable_field (tree);
extern bool defer_mark_used_calls;
@@ -5641,7 +5641,7 @@ extern int abstract_virtuals_error_sfinae (tree, t
extern tree store_init_value (tree, tree, int);
extern void check_narrowing (tree, tree);
-extern tree digest_init (tree, tree);
+extern tree digest_init (tree, tree, tsubst_flags_t);
extern tree digest_init_flags (tree, tree, int);
extern tree build_scoped_ref (tree, tree, tree *);
extern tree build_x_arrow (tree);