Index: testsuite/g++.dg/template/sfinae28.C =================================================================== --- testsuite/g++.dg/template/sfinae28.C (revision 0) +++ testsuite/g++.dg/template/sfinae28.C (revision 0) @@ -0,0 +1,13 @@ +// PR c++/48737 +// { dg-options "-std=c++0x" } + +template +T&& create(); + +template +decltype(T{create()...}, char()) f(int); + +template +char (&f(...))[2]; + +static_assert(sizeof(f(0)) != 1, "Error"); Index: testsuite/g++.dg/template/sfinae29.C =================================================================== --- testsuite/g++.dg/template/sfinae29.C (revision 0) +++ testsuite/g++.dg/template/sfinae29.C (revision 0) @@ -0,0 +1,23 @@ +// PR c++/48744 +// { dg-options "-std=c++0x" } + +template +struct add_rval_ref { + typedef T&& type; +}; + +template<> +struct add_rval_ref { + typedef void type; +}; + +template +typename add_rval_ref::type create(); + +template +decltype(T{create()}, char()) f(int); + +template +char (&f(...))[2]; + +static_assert(sizeof(f(0)) != 1, "Error"); Index: cp/typeck.c =================================================================== --- cp/typeck.c (revision 173549) +++ cp/typeck.c (working copy) @@ -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), Index: cp/init.c =================================================================== --- cp/init.c (revision 173549) +++ cp/init.c (working copy) @@ -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) { Index: cp/decl.c =================================================================== --- cp/decl.c (revision 173549) +++ cp/decl.c (working copy) @@ -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 Index: cp/typeck2.c =================================================================== --- cp/typeck2.c (revision 173549) +++ cp/typeck2.c (working copy) @@ -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); } Index: cp/semantics.c =================================================================== --- cp/semantics.c (revision 173549) +++ cp/semantics.c (working copy) @@ -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)) Index: cp/decl2.c =================================================================== --- cp/decl2.c (revision 173549) +++ cp/decl2.c (working copy) @@ -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)) Index: cp/call.c =================================================================== --- cp/call.c (revision 173549) +++ cp/call.c (working copy) @@ -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); Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 173549) +++ cp/cp-tree.h (working copy) @@ -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);