From patchwork Sun May 8 16:51:32 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 94593 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 62E831007D5 for ; Mon, 9 May 2011 02:52:37 +1000 (EST) Received: (qmail 10301 invoked by alias); 8 May 2011 16:52:35 -0000 Received: (qmail 10282 invoked by uid 22791); 8 May 2011 16:52:34 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, TW_WR X-Spam-Check-By: sourceware.org Received: from smtp206.alice.it (HELO smtp206.alice.it) (82.57.200.102) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 08 May 2011 16:52:19 +0000 Received: from [192.168.1.4] (79.17.190.45) by smtp206.alice.it (8.5.124.08) id 4D49918D0818D1E7; Sun, 8 May 2011 18:52:17 +0200 Message-ID: <4DC6CA14.60507@oracle.com> Date: Sun, 08 May 2011 18:51:32 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110414 SUSE/3.1.10 Thunderbird/3.1.10 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: Jason Merrill Subject: [C++ Patch] PRs 48737 & 48744 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, as far as I can see this is just another case where we want to pass down more consistently the complain argument in order to avoid hard errors in sfinae contexts. In particular, we don't want hard errors from reshape_init itself (in order to fix 48737) and we want digest_init_r to forward complain to convert_for_initialization (to fix 48744). This requires some small adjustments elsewhere, not too much, in particular, earlier, finish_compound_literal forwards its complain argument to reshape_init and digest_init. Tested x86_64-linux. Ok for mainline? Thanks, Paolo. ////////////////// /cp 2011-05-08 Paolo Carlini PR c++/48737 PR c++/48744 * decl.c (reshape_init): Take a complain parameter and do not call error if tf_error is not set. (check_initializer, reshape_init_r): Adjust. * typeck2.c (digest_init_r): Take a complain parameter and pass it to convert_for_initialization. (digest_init, digest_init_flags, process_init_constructor_array, process_init_constructor_record, process_init_constructor_union): Adjust. * init.c (expand_default_init, build_new_1): Likewise. * typeck.c (cp_build_modify_expr): Likewise. * decl2.c (grokfield): Likewise. * call.c (convert_like_real, convert_default_arg): Likewise. * semantics.c (finish_compound_literal): Pass complain to reshape_init and digest_init. * cp-tree.h: Adjust declarations. /testsuite 2011-05-08 Paolo Carlini PR c++/48737 PR c++/48744 * g++.dg/template/sfinae28.C: New. * g++.dg/template/sfinae29.C: Likewise. 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);