From patchwork Fri Apr 20 02:00:46 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 153906 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 63DCBB7014 for ; Fri, 20 Apr 2012 12:01:41 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1335492101; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Message-ID:Date:From:User-Agent:MIME-Version: To:CC:Subject:References:In-Reply-To:Content-Type:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=WmWB3nE7iUBv34hcPohq2qRRAV8=; b=Kgo/8QMo1LQB66hTauZl2cvvULxqDhaoUAJcsnvHecT3Y7ljSyv5QYbSF8go7c 4JkqFXw/HkcXzUCAEieKqMEN6lEe9R3Lg/76vvlyBjf70qJCPUhMGKXl6nZ7snMA yZGaPSuQWTUVxXiOebFgjO2guPy1cX3J5iSe5qmBL+slk= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=SFWH7GbUiGgB2q2l06DpQkg+RViRwISbgPK+cILC4ob/o6YnR9AN6QRzamLTxX Qu6B7cpwB5sGlI3pNRAj8bqoKvzVbZC51NyCygOtaLvOew4ghMcAp4HuaR72LOJY 1dP4qrCyc9PHuSdst8pqZ6+UfxgYYsJePA30AN+eLpXRo=; Received: (qmail 20013 invoked by alias); 20 Apr 2012 02:01:32 -0000 Received: (qmail 19968 invoked by uid 22791); 20 Apr 2012 02:01:21 -0000 X-SWARE-Spam-Status: No, hits=-6.9 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_NO, RCVD_IN_HOSTKARMA_W, TW_FN, TW_NV, TW_PM, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from rcsinet15.oracle.com (HELO rcsinet15.oracle.com) (148.87.113.117) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 20 Apr 2012 02:00:56 +0000 Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by rcsinet15.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id q3K20s2T011001 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 20 Apr 2012 02:00:55 GMT Received: from acsmt357.oracle.com (acsmt357.oracle.com [141.146.40.157]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q3K20rEW007474 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 20 Apr 2012 02:00:54 GMT Received: from abhmt114.oracle.com (abhmt114.oracle.com [141.146.116.66]) by acsmt357.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id q3K20rNu031388; Thu, 19 Apr 2012 21:00:53 -0500 Received: from [192.168.1.4] (/79.33.221.35) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 19 Apr 2012 19:00:52 -0700 Message-ID: <4F90C34E.3030606@oracle.com> Date: Fri, 20 Apr 2012 04:00:46 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:11.0) Gecko/20120328 Thunderbird/11.0.1 MIME-Version: 1.0 To: Jason Merrill CC: "gcc-patches@gcc.gnu.org" Subject: Re: [C++ Patch] PR 52363 References: <4F8EFD66.10306@oracle.com> <4F8F0F3A.1030701@redhat.com> <4F8F5CC3.6030906@oracle.com> <4F8F8F50.8050804@redhat.com> <4F9008E2.30404@oracle.com> <4F905E5D.5040801@redhat.com> <4F90657E.5020803@redhat.com> In-Reply-To: <4F90657E.5020803@redhat.com> 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 On 04/19/2012 09:20 PM, Jason Merrill wrote: > On 04/19/2012 03:00 PM, Paolo Carlini wrote: >> Yes, that's life ;) Seriously, if we want to avoid all those having >> to do with implicit_conversion in one swoop, the eventual patch will >> be pretty big, should I just go on and on? > > I think so. Once we start down this road, we should follow it to the end. OK. Here is a new version of the work (three times as big ;) with which I'm personally rather happy: eg, no more tf_warning_or_error in the whole call.c, besides an handful of uses in build_* calls. Booted and tested x86_64-linux Thanks! Paolo. ///////////////////////// /cp 2012-04-20 Paolo Carlini PR c++/52363 * call.c (tourney, perform_overload_resolution, build_operator_new_call, build_user_type_conversion_1, build_user_type_conversion, perform_overload_resolution, add_template_candidate, add_template_candidate_real, add_template_conv_candidate, add_builtin_candidates, add_builtin_candidate, build_builtin_candidate, add_conv_candidate, add_function_candidate, implicit_conversion, reference_binding, build_list_conv, conditional_conversion, add_candidates, can_convert_array, build_aggr_conv, build_array_conv, build_complex_conv, conditional_conversion): Add tsubst_flags_t parameter. (joust): Likewise, use it to handle SFINAE as if pedantic. (add_list_candidates, build_integral_nontype_arg_conv, perform_overload_resolution, build_new_function_call, build_operator_new_call, build_op_call_1, build_conditional_expr_1, build_new_op_1, convert_like_real, convert_arg_to_ellipsis, convert_default_arg, convert_for_arg_passing, build_over_call, build_new_method_call_1, can_convert_arg, can_convert_arg_bad, perform_implicit_conversion_flags, perform_direct_initialization_if_possible, initialize_reference): Adjust. * typeck.c (casts_away_constness, casts_away_constness_r): Add tsubst_flags_t parameter. (convert_arguments, check_for_casting_away_constness, build_static_cast_1, build_ptrmemfunc, convert_for_assignment): Adjust. * decl.c (reshape_init_r, check_default_argument): Likewise. * cp-gimplify.c (cxx_omp_clause_apply_fn): Likewise. * pt.c (convert_nontype_argument, check_non_deducible_conversion): Likewise. * init.c (build_new_1): Likewise. * cvt.c (convert_to_reference, ocp_convert, build_type_conversion, build_expr_type_conversion, ): Likewise. * search.c (check_final_overrider): Likewise. * cp-tree.h (build_user_type_conversion, build_operator_new_call, can_convert, can_convert_arg, can_convert_arg_bad, convert_default_arg, convert_arg_to_ellipsis, convert_for_arg_passing): Adjust declaration. /testsuite 2012-04-20 Paolo Carlini PR c++/52363 * testsuite/g++.dg/cpp0x/sfinae35.C: New. * testsuite/g++.dg/cpp0x/sfinae36.C: Likewise. Index: cp/typeck.c =================================================================== --- cp/typeck.c (revision 186600) +++ cp/typeck.c (working copy) @@ -55,8 +55,8 @@ static bool comp_except_types (tree, tree, bool); static bool comp_array_types (const_tree, const_tree, bool); static tree pointer_diff (tree, tree, tree); static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t); -static void casts_away_constness_r (tree *, tree *); -static bool casts_away_constness (tree, tree); +static void casts_away_constness_r (tree *, tree *, tsubst_flags_t); +static bool casts_away_constness (tree, tree, tsubst_flags_t); static void maybe_warn_about_returning_address_of_local (tree); static tree lookup_destructor (tree, tree, tree); static void warn_args_num (location_t, tree, bool); @@ -3489,7 +3489,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **v parmval = convert_for_initialization (NULL_TREE, type, val, flags, ICR_ARGPASS, fndecl, i, complain); - parmval = convert_for_arg_passing (type, parmval); + parmval = convert_for_arg_passing (type, parmval, complain); } if (parmval == error_mark_node) @@ -3506,7 +3506,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **v types. */ val = require_complete_type_sfinae (val, complain); else - val = convert_arg_to_ellipsis (val); + val = convert_arg_to_ellipsis (val, complain); VEC_replace (tree, *values, i, val); } @@ -3532,7 +3532,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **v tree parmval = convert_default_arg (TREE_VALUE (typetail), TREE_PURPOSE (typetail), - fndecl, i); + fndecl, i, complain); if (parmval == error_mark_node) return -1; @@ -5771,7 +5771,7 @@ check_for_casting_away_constness (tree src_type, t if (cast == CAST_EXPR && !warn_cast_qual) return false; - if (!casts_away_constness (src_type, dest_type)) + if (!casts_away_constness (src_type, dest_type, complain)) return false; switch (cast) @@ -5921,7 +5921,8 @@ build_static_cast_1 (tree type, tree expr, bool c_ && DERIVED_FROM_P (intype, TREE_TYPE (type)) && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)), build_pointer_type (TYPE_MAIN_VARIANT - (TREE_TYPE (type)))) + (TREE_TYPE (type))), + complain) && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype))) { @@ -6048,7 +6049,8 @@ build_static_cast_1 (tree type, tree expr, bool c_ && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (intype))), build_pointer_type (TYPE_MAIN_VARIANT - (TREE_TYPE (type))))) + (TREE_TYPE (type))), + complain)) { tree base; @@ -6089,7 +6091,7 @@ build_static_cast_1 (tree type, tree expr, bool c_ t1 = intype; t2 = type; } - if (can_convert (t1, t2) || can_convert (t2, t1)) + if (can_convert (t1, t2, complain) || can_convert (t2, t1, complain)) { if (!c_cast_p && check_for_casting_away_constness (intype, type, @@ -7290,7 +7292,8 @@ build_ptrmemfunc (tree type, tree pfn, int force, tree n; if (!force - && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn, LOOKUP_NORMAL)) + && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn, + LOOKUP_NORMAL, complain)) error ("invalid conversion to type %qT from type %qT", to_type, pfn_type); @@ -7555,7 +7558,7 @@ convert_for_assignment (tree type, tree rhs, We allow bad conversions here because by the time we get to this point we are committed to doing the conversion. If we end up doing a bad conversion, convert_like will complain. */ - if (!can_convert_arg_bad (type, rhstype, rhs, flags)) + if (!can_convert_arg_bad (type, rhstype, rhs, flags, complain)) { /* When -Wno-pmf-conversions is use, we just silently allow conversions from pointers-to-members to plain pointers. If @@ -8408,7 +8411,7 @@ cp_apply_type_quals_to_decl (int type_quals, tree if and only if there is no implicit conversion from T1 to T2. */ static void -casts_away_constness_r (tree *t1, tree *t2) +casts_away_constness_r (tree *t1, tree *t2, tsubst_flags_t complain) { int quals1; int quals2; @@ -8458,7 +8461,7 @@ static void else *t2 = TREE_TYPE (*t2); - casts_away_constness_r (t1, t2); + casts_away_constness_r (t1, t2, complain); *t1 = build_pointer_type (*t1); *t2 = build_pointer_type (*t2); *t1 = cp_build_qualified_type (*t1, quals1); @@ -8474,7 +8477,7 @@ static void */ static bool -casts_away_constness (tree t1, tree t2) +casts_away_constness (tree t1, tree t2, tsubst_flags_t complain) { if (TREE_CODE (t2) == REFERENCE_TYPE) { @@ -8486,7 +8489,8 @@ static bool casts away constness. */ t1 = (TREE_CODE (t1) == REFERENCE_TYPE ? TREE_TYPE (t1) : t1); return casts_away_constness (build_pointer_type (t1), - build_pointer_type (TREE_TYPE (t2))); + build_pointer_type (TREE_TYPE (t2)), + complain); } if (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2)) @@ -8499,7 +8503,8 @@ static bool constness. */ return casts_away_constness (build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t1)), - build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2))); + build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2)), + complain); /* Casting away constness is only something that makes sense for pointer or reference types. */ @@ -8510,8 +8515,8 @@ static bool /* Top-level qualifiers don't matter. */ t1 = TYPE_MAIN_VARIANT (t1); t2 = TYPE_MAIN_VARIANT (t2); - casts_away_constness_r (&t1, &t2); - if (!can_convert (t2, t1)) + casts_away_constness_r (&t1, &t2, complain); + if (!can_convert (t2, t1, complain)) return true; return false; Index: cp/init.c =================================================================== --- cp/init.c (revision 186600) +++ cp/init.c (working copy) @@ -2381,7 +2381,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, alloc_call = build_operator_new_call (fnname, placement, &size, &cookie_size, - &alloc_fn); + &alloc_fn, complain); } } Index: cp/decl.c =================================================================== --- cp/decl.c (revision 186600) +++ cp/decl.c (working copy) @@ -5266,7 +5266,8 @@ reshape_init_r (tree type, reshape_iter *d, bool f valid aggregate initialization. */ && !first_initializer_p && (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (init)) - || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL))) + || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL, + complain))) { d->cur++; return init; @@ -10602,7 +10603,8 @@ check_default_argument (tree decl, tree arg) A default argument expression is implicitly converted to the parameter type. */ if (!TREE_TYPE (arg) - || !can_convert_arg (decl_type, TREE_TYPE (arg), arg, LOOKUP_NORMAL)) + || !can_convert_arg (decl_type, TREE_TYPE (arg), arg, LOOKUP_NORMAL, + tf_warning_or_error)) { if (decl) error ("default argument for %q#D has type %qT", Index: cp/cp-gimplify.c =================================================================== --- cp/cp-gimplify.c (revision 186600) +++ cp/cp-gimplify.c (working copy) @@ -1273,7 +1273,8 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree for (parm = defparm; parm && parm != void_list_node; parm = TREE_CHAIN (parm), i++) argarray[i] = convert_default_arg (TREE_VALUE (parm), - TREE_PURPOSE (parm), fn, i); + TREE_PURPOSE (parm), fn, i, + tf_warning_or_error); t = build_call_a (fn, i, argarray); t = fold_convert (void_type_node, t); t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); @@ -1306,7 +1307,7 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree parm = TREE_CHAIN (parm), i++) argarray[i] = convert_default_arg (TREE_VALUE (parm), TREE_PURPOSE (parm), - fn, i); + fn, i, tf_warning_or_error); t = build_call_a (fn, i, argarray); t = fold_convert (void_type_node, t); return fold_build_cleanup_point_expr (TREE_TYPE (t), t); Index: cp/pt.c =================================================================== --- cp/pt.c (revision 186600) +++ cp/pt.c (working copy) @@ -6063,7 +6063,7 @@ convert_nontype_argument (tree type, tree expr, ts "because it is of type %qT", expr, type, TREE_TYPE (expr)); /* If we are just one standard conversion off, explain. */ - if (can_convert (type, TREE_TYPE (expr))) + if (can_convert (type, TREE_TYPE (expr), complain)) inform (input_location, "standard conversions are not allowed in this context"); return NULL_TREE; @@ -15128,14 +15128,15 @@ check_non_deducible_conversion (tree parm, tree ar if (strict == DEDUCE_CONV) { - if (can_convert_arg (type, parm, NULL_TREE, flags)) + if (can_convert_arg (type, parm, NULL_TREE, flags, + explain_p ? tf_warning_or_error : tf_none)) return unify_success (explain_p); } else if (strict != DEDUCE_EXACT) { if (can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg, - flags)) + flags, explain_p ? tf_warning_or_error : tf_none)) return unify_success (explain_p); } Index: cp/call.c =================================================================== --- cp/call.c (revision 186600) +++ cp/call.c (working copy) @@ -142,9 +142,10 @@ static struct obstack conversion_obstack; static bool conversion_obstack_initialized; struct rejection_reason; -static struct z_candidate * tourney (struct z_candidate *); +static struct z_candidate * tourney (struct z_candidate *, tsubst_flags_t); static int equal_functions (tree, tree); -static int joust (struct z_candidate *, struct z_candidate *, bool); +static int joust (struct z_candidate *, struct z_candidate *, bool, + tsubst_flags_t); static int compare_ics (conversion *, conversion *); static tree build_over_call (struct z_candidate *, int, tsubst_flags_t); static tree build_java_interface_fn_ref (tree, tree); @@ -160,7 +161,8 @@ static tree convert_like_real (conversion *, tree, bool, tsubst_flags_t); static void op_error (enum tree_code, enum tree_code, tree, tree, tree, bool); -static struct z_candidate *build_user_type_conversion_1 (tree, tree, int); +static struct z_candidate *build_user_type_conversion_1 (tree, tree, int, + tsubst_flags_t); static void print_z_candidate (const char *, struct z_candidate *); static void print_z_candidates (location_t, struct z_candidate *); static tree build_this (tree); @@ -168,34 +170,36 @@ static struct z_candidate *splice_viable (struct z static bool any_strictly_viable (struct z_candidate *); static struct z_candidate *add_template_candidate (struct z_candidate **, tree, tree, tree, tree, const VEC(tree,gc) *, - tree, tree, tree, int, unification_kind_t); + tree, tree, tree, int, unification_kind_t, tsubst_flags_t); static struct z_candidate *add_template_candidate_real (struct z_candidate **, tree, tree, tree, tree, const VEC(tree,gc) *, - tree, tree, tree, int, tree, unification_kind_t); + tree, tree, tree, int, tree, unification_kind_t, tsubst_flags_t); static struct z_candidate *add_template_conv_candidate (struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree, - tree, tree); + tree, tree, tsubst_flags_t); static void add_builtin_candidates (struct z_candidate **, enum tree_code, enum tree_code, - tree, tree *, int); + tree, tree *, int, tsubst_flags_t); static void add_builtin_candidate (struct z_candidate **, enum tree_code, enum tree_code, - tree, tree, tree, tree *, tree *, int); + tree, tree, tree, tree *, tree *, int, tsubst_flags_t); static bool is_complete (tree); static void build_builtin_candidate (struct z_candidate **, tree, tree, tree, tree *, tree *, - int); + int, tsubst_flags_t); static struct z_candidate *add_conv_candidate (struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree, - tree); + tree, tsubst_flags_t); static struct z_candidate *add_function_candidate (struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree, - tree, int); -static conversion *implicit_conversion (tree, tree, tree, bool, int); + tree, int, tsubst_flags_t); +static conversion *implicit_conversion (tree, tree, tree, bool, int, + tsubst_flags_t); static conversion *standard_conversion (tree, tree, tree, bool, int); -static conversion *reference_binding (tree, tree, tree, bool, int); +static conversion *reference_binding (tree, tree, tree, bool, int, + tsubst_flags_t); static conversion *build_conv (conversion_kind, tree, conversion *); -static conversion *build_list_conv (tree, tree, int); +static conversion *build_list_conv (tree, tree, int, tsubst_flags_t); static conversion *next_conversion (conversion *); static bool is_subseq (conversion *, conversion *); static conversion *maybe_handle_ref_bind (conversion **); @@ -208,11 +212,12 @@ static void add_warning (struct z_candidate *, str static bool reference_compatible_p (tree, tree); static conversion *direct_reference_binding (tree, conversion *); static bool promoted_arithmetic_type_p (tree); -static conversion *conditional_conversion (tree, tree); +static conversion *conditional_conversion (tree, tree, tsubst_flags_t); static char *name_as_c_string (tree, tree, bool *); static tree prep_operand (tree); static void add_candidates (tree, tree, const VEC(tree,gc) *, tree, tree, bool, - tree, tree, int, struct z_candidate **); + tree, tree, int, struct z_candidate **, + tsubst_flags_t); static conversion *merge_conversion_sequences (conversion *, conversion *); static bool magic_varargs_p (tree); static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t); @@ -793,7 +798,7 @@ build_conv (conversion_kind code, tree type, conve possible. */ static conversion * -build_list_conv (tree type, tree ctor, int flags) +build_list_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) { tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (type), 0); unsigned len = CONSTRUCTOR_NELTS (ctor); @@ -812,7 +817,7 @@ static conversion * { conversion *sub = implicit_conversion (elttype, TREE_TYPE (val), val, - false, flags); + false, flags, complain); if (sub == NULL) return NULL; @@ -857,7 +862,7 @@ next_conversion (conversion *conv) is a valid aggregate initializer for array type ATYPE. */ static bool -can_convert_array (tree atype, tree ctor, int flags) +can_convert_array (tree atype, tree ctor, int flags, tsubst_flags_t complain) { unsigned i; tree elttype = TREE_TYPE (atype); @@ -867,9 +872,10 @@ static bool bool ok; if (TREE_CODE (elttype) == ARRAY_TYPE && TREE_CODE (val) == CONSTRUCTOR) - ok = can_convert_array (elttype, val, flags); + ok = can_convert_array (elttype, val, flags, complain); else - ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags); + ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags, + complain); if (!ok) return false; } @@ -880,7 +886,7 @@ static bool aggregate class, if such a conversion is possible. */ static conversion * -build_aggr_conv (tree type, tree ctor, int flags) +build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) { unsigned HOST_WIDE_INT i = 0; conversion *c; @@ -909,9 +915,10 @@ static conversion * if (TREE_CODE (ftype) == ARRAY_TYPE && TREE_CODE (val) == CONSTRUCTOR) - ok = can_convert_array (ftype, val, flags); + ok = can_convert_array (ftype, val, flags, complain); else - ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags); + ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags, + complain); if (!ok) return NULL; @@ -935,7 +942,7 @@ static conversion * array type, if such a conversion is possible. */ static conversion * -build_array_conv (tree type, tree ctor, int flags) +build_array_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) { conversion *c; unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (ctor); @@ -957,7 +964,7 @@ static conversion * { conversion *sub = implicit_conversion (elttype, TREE_TYPE (val), val, - false, flags); + false, flags, complain); if (sub == NULL) return NULL; @@ -982,7 +989,8 @@ static conversion * complex type, if such a conversion is possible. */ static conversion * -build_complex_conv (tree type, tree ctor, int flags) +build_complex_conv (tree type, tree ctor, int flags, + tsubst_flags_t complain) { conversion *c; unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (ctor); @@ -1000,7 +1008,7 @@ static conversion * { conversion *sub = implicit_conversion (elttype, TREE_TYPE (val), val, - false, flags); + false, flags, complain); if (sub == NULL) return NULL; @@ -1438,7 +1446,8 @@ direct_reference_binding (tree type, conversion *c conversion is coming from a C-style cast. */ static conversion * -reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) +reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags, + tsubst_flags_t complain) { conversion *conv = NULL; tree to = TREE_TYPE (rto); @@ -1461,7 +1470,7 @@ static conversion * { maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); conv = implicit_conversion (to, from, expr, c_cast_p, - flags); + flags, complain); if (!CLASS_TYPE_P (to) && CONSTRUCTOR_NELTS (expr) == 1) { @@ -1597,7 +1606,8 @@ static conversion * the reference is bound to the lvalue result of the conversion in the second case. */ - z_candidate *cand = build_user_type_conversion_1 (rto, expr, flags); + z_candidate *cand = build_user_type_conversion_1 (rto, expr, flags, + complain); if (cand) return cand->second_conv; } @@ -1652,7 +1662,7 @@ static conversion * if (!conv) conv = implicit_conversion (to, from, expr, c_cast_p, - flags); + flags, complain); if (!conv) return NULL; @@ -1672,7 +1682,7 @@ static conversion * static conversion * implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, - int flags) + int flags, tsubst_flags_t complain) { conversion *conv; @@ -1687,7 +1697,7 @@ implicit_conversion (tree to, tree from, tree expr |LOOKUP_NO_NARROWING|LOOKUP_PROTECT); if (TREE_CODE (to) == REFERENCE_TYPE) - conv = reference_binding (to, from, expr, c_cast_p, flags); + conv = reference_binding (to, from, expr, c_cast_p, flags, complain); else conv = standard_conversion (to, from, expr, c_cast_p, flags); @@ -1697,12 +1707,12 @@ implicit_conversion (tree to, tree from, tree expr if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr)) { if (is_std_init_list (to)) - return build_list_conv (to, expr, flags); + return build_list_conv (to, expr, flags, complain); /* As an extension, allow list-initialization of _Complex. */ if (TREE_CODE (to) == COMPLEX_TYPE) { - conv = build_complex_conv (to, expr, flags); + conv = build_complex_conv (to, expr, flags, complain); if (conv) return conv; } @@ -1722,7 +1732,7 @@ implicit_conversion (tree to, tree from, tree expr elt = error_mark_node; conv = implicit_conversion (to, TREE_TYPE (elt), elt, - c_cast_p, flags); + c_cast_p, flags, complain); if (conv) { conv->check_narrowing = true; @@ -1733,7 +1743,7 @@ implicit_conversion (tree to, tree from, tree expr } } else if (TREE_CODE (to) == ARRAY_TYPE) - return build_array_conv (to, expr, flags); + return build_array_conv (to, expr, flags, complain); } if (expr != NULL_TREE @@ -1746,9 +1756,9 @@ implicit_conversion (tree to, tree from, tree expr if (CLASS_TYPE_P (to) && BRACE_ENCLOSED_INITIALIZER_P (expr) && !CLASSTYPE_NON_AGGREGATE (complete_type (to))) - return build_aggr_conv (to, expr, flags); + return build_aggr_conv (to, expr, flags, complain); - cand = build_user_type_conversion_1 (to, expr, flags); + cand = build_user_type_conversion_1 (to, expr, flags, complain); if (cand) conv = cand->second_conv; @@ -1818,7 +1828,8 @@ static struct z_candidate * add_function_candidate (struct z_candidate **candidates, tree fn, tree ctype, tree first_arg, const VEC(tree,gc) *args, tree access_path, - tree conversion_path, int flags) + tree conversion_path, int flags, + tsubst_flags_t complain) { tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn)); int i, len; @@ -1977,7 +1988,7 @@ add_function_candidate (struct z_candidate **candi lflags |= LOOKUP_ONLYCONVERTING; t = implicit_conversion (parmtype, argtype, arg, - /*c_cast_p=*/false, lflags); + /*c_cast_p=*/false, lflags, complain); to_type = parmtype; } else @@ -2025,7 +2036,8 @@ add_function_candidate (struct z_candidate **candi static struct z_candidate * add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj, tree first_arg, const VEC(tree,gc) *arglist, - tree access_path, tree conversion_path) + tree access_path, tree conversion_path, + tsubst_flags_t complain) { tree totype = TREE_TYPE (TREE_TYPE (fn)); int i, len, viable, flags; @@ -2065,7 +2077,7 @@ add_conv_candidate (struct z_candidate **candidate if (i == 0) { t = implicit_conversion (totype, argtype, arg, /*c_cast_p=*/false, - flags); + flags, complain); convert_type = totype; } else if (parmnode == void_list_node) @@ -2073,7 +2085,7 @@ add_conv_candidate (struct z_candidate **candidate else if (parmnode) { t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg, - /*c_cast_p=*/false, flags); + /*c_cast_p=*/false, flags, complain); convert_type = TREE_VALUE (parmnode); } else @@ -2115,7 +2127,7 @@ add_conv_candidate (struct z_candidate **candidate static void build_builtin_candidate (struct z_candidate **candidates, tree fnname, tree type1, tree type2, tree *args, tree *argtypes, - int flags) + int flags, tsubst_flags_t complain) { conversion *t; conversion **convs; @@ -2144,18 +2156,20 @@ build_builtin_candidate (struct z_candidate **cand break; t = implicit_conversion (types[i], argtypes[i], args[i], - /*c_cast_p=*/false, flags); + /*c_cast_p=*/false, flags, complain); if (! t) { viable = 0; /* We need something for printing the candidate. */ t = build_identity_conv (types[i], NULL_TREE); - reason = arg_conversion_rejection (NULL_TREE, i, argtypes[i], types[i]); + reason = arg_conversion_rejection (NULL_TREE, i, argtypes[i], + types[i]); } else if (t->bad_p) { viable = 0; - reason = bad_arg_conversion_rejection (NULL_TREE, i, argtypes[i], types[i]); + reason = bad_arg_conversion_rejection (NULL_TREE, i, argtypes[i], + types[i]); } convs[i] = t; } @@ -2166,7 +2180,8 @@ build_builtin_candidate (struct z_candidate **cand convs[2] = convs[1]; convs[1] = convs[0]; t = implicit_conversion (boolean_type_node, argtypes[2], args[2], - /*c_cast_p=*/false, flags); + /*c_cast_p=*/false, flags, + complain); if (t) convs[0] = t; else @@ -2220,7 +2235,8 @@ promoted_arithmetic_type_p (tree type) static void add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, enum tree_code code2, tree fnname, tree type1, - tree type2, tree *args, tree *argtypes, int flags) + tree type2, tree *args, tree *argtypes, int flags, + tsubst_flags_t complain) { switch (code) { @@ -2614,20 +2630,21 @@ add_builtin_candidate (struct z_candidate **candid if (cptype != error_mark_node) { build_builtin_candidate - (candidates, fnname, cptype, cptype, args, argtypes, flags); + (candidates, fnname, cptype, cptype, args, argtypes, + flags, complain); return; } } build_builtin_candidate - (candidates, fnname, type1, type1, args, argtypes, flags); + (candidates, fnname, type1, type1, args, argtypes, flags, complain); build_builtin_candidate - (candidates, fnname, type2, type2, args, argtypes, flags); + (candidates, fnname, type2, type2, args, argtypes, flags, complain); return; } build_builtin_candidate - (candidates, fnname, type1, type2, args, argtypes, flags); + (candidates, fnname, type1, type2, args, argtypes, flags, complain); } tree @@ -2656,7 +2673,7 @@ type_decays_to (tree type) static void add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, enum tree_code code2, tree fnname, tree *args, - int flags) + int flags, tsubst_flags_t complain) { int ref1, i; int enum_p = 0; @@ -2697,14 +2714,14 @@ add_builtin_candidates (struct z_candidate **candi case TRUTH_NOT_EXPR: build_builtin_candidate (candidates, fnname, boolean_type_node, - NULL_TREE, args, argtypes, flags); + NULL_TREE, args, argtypes, flags, complain); return; case TRUTH_ORIF_EXPR: case TRUTH_ANDIF_EXPR: build_builtin_candidate (candidates, fnname, boolean_type_node, - boolean_type_node, args, argtypes, flags); + boolean_type_node, args, argtypes, flags, complain); return; case ADDR_EXPR: @@ -2810,11 +2827,11 @@ add_builtin_candidates (struct z_candidate **candi FOR_EACH_VEC_ELT_REVERSE (tree, types[1], jx, u) add_builtin_candidate (candidates, code, code2, fnname, t, - u, args, argtypes, flags); + u, args, argtypes, flags, complain); else add_builtin_candidate (candidates, code, code2, fnname, t, - NULL_TREE, args, argtypes, flags); + NULL_TREE, args, argtypes, flags, complain); } release_tree_vector (types[0]); @@ -2837,7 +2854,8 @@ add_template_candidate_real (struct z_candidate ** tree ctype, tree explicit_targs, tree first_arg, const VEC(tree,gc) *arglist, tree return_type, tree access_path, tree conversion_path, - int flags, tree obj, unification_kind_t strict) + int flags, tree obj, unification_kind_t strict, + tsubst_flags_t complain) { int ntparms = DECL_NTPARMS (tmpl); tree targs = make_tree_vec (ntparms); @@ -2958,11 +2976,11 @@ add_template_candidate_real (struct z_candidate ** if (obj != NULL_TREE) /* Aha, this is a conversion function. */ cand = add_conv_candidate (candidates, fn, obj, first_arg, arglist, - access_path, conversion_path); + access_path, conversion_path, complain); else cand = add_function_candidate (candidates, fn, ctype, first_arg, arglist, access_path, - conversion_path, flags); + conversion_path, flags, complain); if (DECL_TI_TEMPLATE (fn) != tmpl) /* This situation can occur if a member template of a template class is specialized. Then, instantiate_template might return @@ -2998,13 +3016,13 @@ add_template_candidate (struct z_candidate **candi tree explicit_targs, tree first_arg, const VEC(tree,gc) *arglist, tree return_type, tree access_path, tree conversion_path, int flags, - unification_kind_t strict) + unification_kind_t strict, tsubst_flags_t complain) { return add_template_candidate_real (candidates, tmpl, ctype, explicit_targs, first_arg, arglist, return_type, access_path, conversion_path, - flags, NULL_TREE, strict); + flags, NULL_TREE, strict, complain); } @@ -3013,12 +3031,13 @@ add_template_conv_candidate (struct z_candidate ** tree obj, tree first_arg, const VEC(tree,gc) *arglist, tree return_type, tree access_path, - tree conversion_path) + tree conversion_path, tsubst_flags_t complain) { return add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE, first_arg, arglist, return_type, access_path, - conversion_path, 0, obj, DEDUCE_CONV); + conversion_path, 0, obj, DEDUCE_CONV, + complain); } /* The CANDS are the set of candidates that were considered for @@ -3341,7 +3360,8 @@ add_list_candidates (tree fns, tree first_arg, tree explicit_targs, bool template_only, tree conversion_path, tree access_path, int flags, - struct z_candidate **candidates) + struct z_candidate **candidates, + tsubst_flags_t complain) { VEC(tree,gc) *args; @@ -3365,7 +3385,7 @@ add_list_candidates (tree fns, tree first_arg, args = make_tree_vector_single (init_list); add_candidates (fns, first_arg, args, NULL_TREE, explicit_targs, template_only, conversion_path, - access_path, flags, candidates); + access_path, flags, candidates, complain); if (any_strictly_viable (*candidates)) return; } @@ -3379,7 +3399,7 @@ add_list_candidates (tree fns, tree first_arg, add_candidates (fns, first_arg, args, NULL_TREE, explicit_targs, template_only, conversion_path, - access_path, flags, candidates); + access_path, flags, candidates, complain); } /* Returns the best overload candidate to perform the requested @@ -3389,7 +3409,8 @@ add_list_candidates (tree fns, tree first_arg, per [dcl.init.ref], so we ignore temporary bindings. */ static struct z_candidate * -build_user_type_conversion_1 (tree totype, tree expr, int flags) +build_user_type_conversion_1 (tree totype, tree expr, int flags, + tsubst_flags_t complain) { struct z_candidate *candidates, *cand; tree fromtype; @@ -3460,14 +3481,14 @@ static struct z_candidate * /* List-initialization. */ add_list_candidates (ctors, first_arg, expr, totype, NULL_TREE, false, TYPE_BINFO (totype), TYPE_BINFO (totype), - ctorflags, &candidates); + ctorflags, &candidates, complain); } else { args = make_tree_vector_single (expr); add_candidates (ctors, first_arg, args, NULL_TREE, NULL_TREE, false, TYPE_BINFO (totype), TYPE_BINFO (totype), - ctorflags, &candidates); + ctorflags, &candidates, complain); } for (cand = candidates; cand; cand = cand->next) @@ -3508,7 +3529,7 @@ static struct z_candidate * add_candidates (TREE_VALUE (conv_fns), first_arg, NULL, totype, NULL_TREE, false, conversion_path, TYPE_BINFO (fromtype), - flags, &candidates); + flags, &candidates, complain); for (cand = candidates; cand != old_candidates; cand = cand->next) { @@ -3517,7 +3538,8 @@ static struct z_candidate * = implicit_conversion (totype, rettype, 0, - /*c_cast_p=*/false, convflags); + /*c_cast_p=*/false, convflags, + complain); /* If LOOKUP_NO_TEMP_BIND isn't set, then this is copy-initialization. In that case, "The result of the @@ -3582,13 +3604,14 @@ static struct z_candidate * return NULL; } - cand = tourney (candidates); + cand = tourney (candidates, complain); if (cand == 0) { - if (flags & LOOKUP_COMPLAIN) + if ((flags & LOOKUP_COMPLAIN) + && (complain & tf_error)) { error ("conversion from %qT to %qT is ambiguous", - fromtype, totype); + fromtype, totype); print_z_candidates (location_of (expr), candidates); } @@ -3628,13 +3651,14 @@ static struct z_candidate * /* Wrapper for above. */ tree -build_user_type_conversion (tree totype, tree expr, int flags) +build_user_type_conversion (tree totype, tree expr, int flags, + tsubst_flags_t complain) { struct z_candidate *cand; tree ret; bool subtime = timevar_cond_start (TV_OVERLOAD); - cand = build_user_type_conversion_1 (totype, expr, flags); + cand = build_user_type_conversion_1 (totype, expr, flags, complain); if (cand) { @@ -3642,7 +3666,7 @@ tree ret = error_mark_node; else { - expr = convert_like (cand->second_conv, expr, tf_warning_or_error); + expr = convert_like (cand->second_conv, expr, complain); ret = convert_from_reference (expr); } } @@ -3679,7 +3703,7 @@ build_integral_nontype_arg_conv (tree type, tree e conv = implicit_conversion (type, TREE_TYPE (expr), expr, /*c_cast_p=*/false, - LOOKUP_IMPLICIT); + LOOKUP_IMPLICIT, complain); /* for a non-type template-parameter of integral or enumeration type, integral promotions (4.5) and integral @@ -3763,7 +3787,7 @@ static struct z_candidate * perform_overload_resolution (tree fn, const VEC(tree,gc) *args, struct z_candidate **candidates, - bool *any_viable_p) + bool *any_viable_p, tsubst_flags_t complain) { struct z_candidate *cand; tree explicit_targs; @@ -3796,11 +3820,11 @@ perform_overload_resolution (tree fn, /*conversion_path=*/NULL_TREE, /*access_path=*/NULL_TREE, LOOKUP_NORMAL, - candidates); + candidates, complain); *candidates = splice_viable (*candidates, pedantic, any_viable_p); if (*any_viable_p) - cand = tourney (*candidates); + cand = tourney (*candidates, complain); else cand = NULL; @@ -3872,7 +3896,8 @@ build_new_function_call (tree fn, VEC(tree,gc) **a /* Get the high-water mark for the CONVERSION_OBSTACK. */ p = conversion_obstack_alloc (0); - cand = perform_overload_resolution (fn, *args, &candidates, &any_viable_p); + cand = perform_overload_resolution (fn, *args, &candidates, &any_viable_p, + complain); if (!cand) { @@ -3918,7 +3943,7 @@ build_new_function_call (tree fn, VEC(tree,gc) **a tree build_operator_new_call (tree fnname, VEC(tree,gc) **args, tree *size, tree *cookie_size, - tree *fn) + tree *fn, tsubst_flags_t complain) { tree fns; struct z_candidate *candidates; @@ -3928,7 +3953,7 @@ build_operator_new_call (tree fnname, VEC(tree,gc) if (fn) *fn = NULL_TREE; VEC_safe_insert (tree, gc, *args, 0, *size); - *args = resolve_args (*args, tf_warning_or_error); + *args = resolve_args (*args, complain); if (*args == NULL) return error_mark_node; @@ -3944,13 +3969,15 @@ build_operator_new_call (tree fnname, VEC(tree,gc) fns = lookup_function_nonclass (fnname, *args, /*block_p=*/false); /* Figure out what function is being called. */ - cand = perform_overload_resolution (fns, *args, &candidates, &any_viable_p); + cand = perform_overload_resolution (fns, *args, &candidates, &any_viable_p, + complain); /* If no suitable function could be found, issue an error message and give up. */ if (!cand) { - print_error_for_call_failure (fns, *args, any_viable_p, candidates); + if (complain & tf_error) + print_error_for_call_failure (fns, *args, any_viable_p, candidates); return error_mark_node; } @@ -4001,7 +4028,7 @@ build_operator_new_call (tree fnname, VEC(tree,gc) *fn = cand->fn; /* Build the CALL_EXPR. */ - return build_over_call (cand, LOOKUP_NORMAL, tf_warning_or_error); + return build_over_call (cand, LOOKUP_NORMAL, complain); } /* Build a new call to operator(). This may change ARGS. */ @@ -4057,7 +4084,7 @@ build_op_call_1 (tree obj, VEC(tree,gc) **args, ts first_mem_arg, *args, NULL_TREE, NULL_TREE, false, BASELINK_BINFO (fns), BASELINK_ACCESS_BINFO (fns), - LOOKUP_NORMAL, &candidates); + LOOKUP_NORMAL, &candidates, complain); } convs = lookup_conversions (type); @@ -4085,11 +4112,11 @@ build_op_call_1 (tree obj, VEC(tree,gc) **args, ts add_template_conv_candidate (&candidates, fn, obj, NULL_TREE, *args, totype, /*access_path=*/NULL_TREE, - /*conversion_path=*/NULL_TREE); + /*conversion_path=*/NULL_TREE, complain); else add_conv_candidate (&candidates, fn, obj, NULL_TREE, *args, /*conversion_path=*/NULL_TREE, - /*access_path=*/NULL_TREE); + /*access_path=*/NULL_TREE, complain); } } @@ -4106,7 +4133,7 @@ build_op_call_1 (tree obj, VEC(tree,gc) **args, ts } else { - cand = tourney (candidates); + cand = tourney (candidates, complain); if (cand == 0) { if (complain & tf_error) @@ -4251,7 +4278,7 @@ op_error (enum tree_code code, enum tree_code code convert E1 to E2 in [expr.cond]. */ static conversion * -conditional_conversion (tree e1, tree e2) +conditional_conversion (tree e1, tree e2, tsubst_flags_t complain) { tree t1 = non_reference (TREE_TYPE (e1)); tree t2 = non_reference (TREE_TYPE (e2)); @@ -4271,7 +4298,8 @@ static conversion * e1, /*c_cast_p=*/false, LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND - |LOOKUP_ONLYCONVERTING); + |LOOKUP_ONLYCONVERTING, + complain); if (conv) return conv; } @@ -4309,7 +4337,7 @@ static conversion * converted to the type that expression E2 would have if E2 were converted to an rvalue (or the type it has, if E2 is an rvalue). */ return implicit_conversion (t2, t1, e1, /*c_cast_p=*/false, - LOOKUP_IMPLICIT); + LOOKUP_IMPLICIT, complain); } /* Implement [expr.cond]. ARG1, ARG2, and ARG3 are the three @@ -4455,8 +4483,8 @@ build_conditional_expr_1 (tree arg1, tree arg2, tr /* Get the high-water mark for the CONVERSION_OBSTACK. */ p = conversion_obstack_alloc (0); - conv2 = conditional_conversion (arg2, arg3); - conv3 = conditional_conversion (arg3, arg2); + conv2 = conditional_conversion (arg2, arg3, complain); + conv3 = conditional_conversion (arg3, arg2, complain); /* [expr.cond] @@ -4568,7 +4596,7 @@ build_conditional_expr_1 (tree arg1, tree arg2, tr NOP_EXPR, ansi_opname (COND_EXPR), args, - LOOKUP_NORMAL); + LOOKUP_NORMAL, complain); /* [expr.cond] @@ -4584,7 +4612,7 @@ build_conditional_expr_1 (tree arg1, tree arg2, tr } return error_mark_node; } - cand = tourney (candidates); + cand = tourney (candidates, complain); if (!cand) { if (complain & tf_error) @@ -4793,7 +4821,8 @@ add_candidates (tree fns, tree first_arg, const VE tree explicit_targs, bool template_only, tree conversion_path, tree access_path, int flags, - struct z_candidate **candidates) + struct z_candidate **candidates, + tsubst_flags_t complain) { tree ctype; const VEC(tree,gc) *non_static_args; @@ -4899,7 +4928,8 @@ add_candidates (tree fns, tree first_arg, const VE access_path, conversion_path, flags, - strict); + strict, + complain); else if (!template_only) add_function_candidate (candidates, fn, @@ -4908,7 +4938,8 @@ add_candidates (tree fns, tree first_arg, const VE fn_args, access_path, conversion_path, - flags); + flags, + complain); } } @@ -4999,7 +5030,7 @@ build_new_op_1 (enum tree_code code, int flags, tr add_candidates (lookup_function_nonclass (fnname, arglist, /*block_p=*/true), NULL_TREE, arglist, NULL_TREE, NULL_TREE, false, NULL_TREE, NULL_TREE, - flags, &candidates); + flags, &candidates, complain); /* Add class-member operators to the candidate set. */ if (CLASS_TYPE_P (TREE_TYPE (arg1))) { @@ -5017,14 +5048,15 @@ build_new_op_1 (enum tree_code code, int flags, tr NULL_TREE, false, BASELINK_BINFO (fns), BASELINK_ACCESS_BINFO (fns), - flags, &candidates); + flags, &candidates, complain); } args[0] = arg1; args[1] = arg2; args[2] = NULL_TREE; - add_builtin_candidates (&candidates, code, code2, fnname, args, flags); + add_builtin_candidates (&candidates, code, code2, fnname, args, + flags, complain); switch (code) { @@ -5113,7 +5145,7 @@ build_new_op_1 (enum tree_code code, int flags, tr } else { - cand = tourney (candidates); + cand = tourney (candidates, complain); if (cand == 0) { if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error)) @@ -5140,7 +5172,7 @@ build_new_op_1 (enum tree_code code, int flags, tr { struct candidate_warning *w; for (w = cand->warnings; w; w = w->next) - joust (cand, w->loser, 1); + joust (cand, w->loser, 1, complain); } /* Check for comparison of different enum types. */ @@ -5770,7 +5802,8 @@ convert_like_real (conversion *convs, tree expr, t if (complain & tf_error) { /* Call build_user_type_conversion again for the error. */ - build_user_type_conversion (totype, convs->u.expr, LOOKUP_NORMAL); + build_user_type_conversion (totype, convs->u.expr, LOOKUP_NORMAL, + complain); if (fn) error (" initializing argument %P of %q+D", argnum, fn); } @@ -6010,7 +6043,7 @@ convert_like_real (conversion *convs, tree expr, t required. Return the converted value. */ tree -convert_arg_to_ellipsis (tree arg) +convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain) { tree arg_type; @@ -6018,7 +6051,7 @@ tree The lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard conversions are performed. */ - arg = decay_conversion (arg, tf_warning_or_error); + arg = decay_conversion (arg, complain); arg_type = TREE_TYPE (arg); /* [expr.call] @@ -6032,7 +6065,8 @@ tree < TYPE_PRECISION (double_type_node)) && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (arg_type))) { - if (warn_double_promotion && !c_inhibit_evaluation_warnings) + if ((complain & tf_warning) + && warn_double_promotion && !c_inhibit_evaluation_warnings) warning (OPT_Wdouble_promotion, "implicit conversion from %qT to %qT when passing " "argument to function", @@ -6045,8 +6079,9 @@ tree { if (SCOPED_ENUM_P (arg_type) && !abi_version_at_least (6)) { - warning (OPT_Wabi, "scoped enum %qT will not promote to an " - "integral type in a future version of GCC", arg_type); + if (complain & tf_warning) + warning (OPT_Wabi, "scoped enum %qT will not promote to an " + "integral type in a future version of GCC", arg_type); arg = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg); } arg = perform_integral_promotions (arg); @@ -6064,7 +6099,7 @@ tree /* Build up a real lvalue-to-rvalue conversion in case the copy constructor is trivial but not callable. */ if (!cp_unevaluated_operand && CLASS_TYPE_P (arg_type)) - force_rvalue (arg, tf_warning_or_error); + force_rvalue (arg, complain); /* [expr.call] 5.2.2/7: Passing a potentially-evaluated argument of class type (Clause 9) @@ -6080,8 +6115,13 @@ tree if (cp_unevaluated_operand == 0 && (type_has_nontrivial_copy_init (arg_type) || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (arg_type))) - error ("cannot pass objects of non-trivially-copyable " - "type %q#T through %<...%>", arg_type); + { + if (complain & tf_error) + error ("cannot pass objects of non-trivially-copyable " + "type %q#T through %<...%>", arg_type); + else + return error_mark_node; + } } return arg; @@ -6153,7 +6193,8 @@ pop_defarg_context (void) { VEC_pop (tree, default_arg_context); } tree -convert_default_arg (tree type, tree arg, tree fn, int parmnum) +convert_default_arg (tree type, tree arg, tree fn, int parmnum, + tsubst_flags_t complain) { int i; tree t; @@ -6165,7 +6206,8 @@ tree FOR_EACH_VEC_ELT (tree, default_arg_context, i, t) if (t == fn) { - error ("recursive evaluation of default argument for %q#D", fn); + if (complain & tf_error) + error ("recursive evaluation of default argument for %q#D", fn); return error_mark_node; } @@ -6173,8 +6215,9 @@ tree conversion cannot be performed. */ if (TREE_CODE (arg) == DEFAULT_ARG) { - error ("call to %qD uses the default argument for parameter %P, which " - "is not yet defined", fn, parmnum); + if (complain & tf_error) + error ("call to %qD uses the default argument for parameter %P, which " + "is not yet defined", fn, parmnum); return error_mark_node; } @@ -6198,17 +6241,17 @@ tree arg = break_out_target_exprs (arg); if (TREE_CODE (arg) == CONSTRUCTOR) { - arg = digest_init (type, arg, tf_warning_or_error); + arg = digest_init (type, arg, complain); arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT, ICR_DEFAULT_ARGUMENT, fn, parmnum, - tf_warning_or_error); + complain); } else { arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT, ICR_DEFAULT_ARGUMENT, fn, parmnum, - tf_warning_or_error); - arg = convert_for_arg_passing (type, arg); + complain); + arg = convert_for_arg_passing (type, arg, complain); } pop_deferring_access_checks(); @@ -6243,7 +6286,7 @@ type_passed_as (tree type) /* Actually perform the appropriate conversion. */ tree -convert_for_arg_passing (tree type, tree val) +convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain) { tree bitfield_type; @@ -6277,7 +6320,8 @@ tree && INT_CST_LT_UNSIGNED (TYPE_SIZE (type), TYPE_SIZE (integer_type_node))) val = perform_integral_promotions (val); - if (warn_missing_format_attribute) + if ((complain & tf_warning) + && warn_missing_format_attribute) { tree rhstype = TREE_TYPE (val); const enum tree_code coder = TREE_CODE (rhstype); @@ -6383,7 +6427,7 @@ build_over_call (struct z_candidate *cand, int fla { struct candidate_warning *w; for (w = cand->warnings; w; w = w->next) - joust (cand, w->loser, 1); + joust (cand, w->loser, 1, complain); } /* Make =delete work with SFINAE. */ @@ -6611,7 +6655,7 @@ build_over_call (struct z_candidate *cand, int fla ? complain : complain & (~tf_warning)); - val = convert_for_arg_passing (type, val); + val = convert_for_arg_passing (type, val, complain); if (val == error_mark_node) return error_mark_node; else @@ -6625,7 +6669,8 @@ build_over_call (struct z_candidate *cand, int fla return error_mark_node; argarray[j++] = convert_default_arg (TREE_VALUE (parm), TREE_PURPOSE (parm), - fn, i - is_method); + fn, i - is_method, + complain); } /* Ellipsis */ @@ -6636,7 +6681,7 @@ build_over_call (struct z_candidate *cand, int fla /* Do no conversions for magic varargs. */ a = mark_type_use (a); else - a = convert_arg_to_ellipsis (a); + a = convert_arg_to_ellipsis (a, complain); argarray[j++] = a; } @@ -7275,13 +7320,14 @@ build_new_method_call_1 (tree instance, tree fns, /* Otherwise go ahead with overload resolution. */ add_list_candidates (fns, first_mem_arg, init_list, basetype, explicit_targs, template_only, - conversion_path, access_binfo, flags, &candidates); + conversion_path, access_binfo, flags, + &candidates, complain); } else { add_candidates (fns, first_mem_arg, user_args, optype, explicit_targs, template_only, conversion_path, - access_binfo, flags, &candidates); + access_binfo, flags, &candidates, complain); } any_viable_p = false; candidates = splice_viable (candidates, pedantic, &any_viable_p); @@ -7318,7 +7364,7 @@ build_new_method_call_1 (tree instance, tree fns, } else { - cand = tourney (candidates); + cand = tourney (candidates, complain); if (cand == 0) { char *pretty_name; @@ -8013,7 +8059,8 @@ add_warning (struct z_candidate *winner, struct z_ 0: cand1 and cand2 are indistinguishable */ static int -joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn) +joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn, + tsubst_flags_t complain) { int winner = 0; int off1 = 0, off2 = 0; @@ -8076,7 +8123,8 @@ static int if (comp != 0) { - if (warn_sign_promo + if ((complain & tf_warning) + && warn_sign_promo && (CONVERSION_RANK (t1) + CONVERSION_RANK (t2) == cr_std + cr_promotion) && t1->kind == ck_std @@ -8121,7 +8169,8 @@ static int /* warn about confusing overload resolution for user-defined conversions, either between a constructor and a conversion op, or between two conversion ops. */ - if (winner && warn_conversion && cand1->second_conv + if ((complain & tf_warning) + && winner && warn_conversion && cand1->second_conv && (!DECL_CONSTRUCTOR_P (cand1->fn) || !DECL_CONSTRUCTOR_P (cand2->fn)) && winner != compare_ics (cand1->second_conv, cand2->second_conv)) { @@ -8283,12 +8332,18 @@ static int { if (warn) { - permerror (input_location, "default argument mismatch in " - "overload resolution"); - inform (input_location, - " candidate 1: %q+#F", cand1->fn); - inform (input_location, - " candidate 2: %q+#F", cand2->fn); + if (complain & tf_error) + { + permerror (input_location, + "default argument mismatch in " + "overload resolution"); + inform (input_location, + " candidate 1: %q+#F", cand1->fn); + inform (input_location, + " candidate 2: %q+#F", cand2->fn); + } + else + return 0; } else add_warning (cand1, cand2); @@ -8305,7 +8360,7 @@ tweak: /* Extension: If the worst conversion for one candidate is worse than the worst conversion for the other, take the first. */ - if (!pedantic) + if (!pedantic && (complain & tf_warning_or_error)) { conversion_rank rank1 = cr_identity, rank2 = cr_identity; struct z_candidate *w = 0, *l = 0; @@ -8351,7 +8406,7 @@ tweak: algorithm. */ static struct z_candidate * -tourney (struct z_candidate *candidates) +tourney (struct z_candidate *candidates, tsubst_flags_t complain) { struct z_candidate *champ = candidates, *challenger; int fate; @@ -8362,7 +8417,7 @@ static struct z_candidate * for (challenger = champ->next; challenger; ) { - fate = joust (champ, challenger, 0); + fate = joust (champ, challenger, 0, complain); if (fate == 1) challenger = challenger->next; else @@ -8392,7 +8447,7 @@ static struct z_candidate * && !(champ_compared_to_predecessor && challenger->next == champ); challenger = challenger->next) { - fate = joust (champ, challenger, 0); + fate = joust (champ, challenger, 0, complain); if (fate != 1) return NULL; } @@ -8403,15 +8458,16 @@ static struct z_candidate * /* Returns nonzero if things of type FROM can be converted to TO. */ bool -can_convert (tree to, tree from) +can_convert (tree to, tree from, tsubst_flags_t complain) { - return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT); + return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT, complain); } /* Returns nonzero if ARG (of type FROM) can be converted to TO. */ bool -can_convert_arg (tree to, tree from, tree arg, int flags) +can_convert_arg (tree to, tree from, tree arg, int flags, + tsubst_flags_t complain) { conversion *t; void *p; @@ -8421,7 +8477,7 @@ bool p = conversion_obstack_alloc (0); t = implicit_conversion (to, from, arg, /*c_cast_p=*/false, - flags); + flags, complain); ok_p = (t && !t->bad_p); /* Free all the conversions we allocated. */ @@ -8433,7 +8489,8 @@ bool /* Like can_convert_arg, but allows dubious conversions as well. */ bool -can_convert_arg_bad (tree to, tree from, tree arg, int flags) +can_convert_arg_bad (tree to, tree from, tree arg, int flags, + tsubst_flags_t complain) { conversion *t; void *p; @@ -8442,7 +8499,7 @@ bool p = conversion_obstack_alloc (0); /* Try to perform the conversion. */ t = implicit_conversion (to, from, arg, /*c_cast_p=*/false, - flags); + flags, complain); /* Free all the conversions we allocated. */ obstack_free (&conversion_obstack, p); @@ -8456,7 +8513,8 @@ bool doing a bad conversion, convert_like will complain. */ tree -perform_implicit_conversion_flags (tree type, tree expr, tsubst_flags_t complain, int flags) +perform_implicit_conversion_flags (tree type, tree expr, + tsubst_flags_t complain, int flags) { conversion *conv; void *p; @@ -8469,7 +8527,7 @@ tree conv = implicit_conversion (type, TREE_TYPE (expr), expr, /*c_cast_p=*/false, - flags); + flags, complain); if (!conv) { @@ -8510,7 +8568,8 @@ tree tree perform_implicit_conversion (tree type, tree expr, tsubst_flags_t complain) { - return perform_implicit_conversion_flags (type, expr, complain, LOOKUP_IMPLICIT); + return perform_implicit_conversion_flags (type, expr, complain, + LOOKUP_IMPLICIT); } /* Convert EXPR to TYPE (as a direct-initialization) if that is @@ -8554,7 +8613,7 @@ perform_direct_initialization_if_possible (tree ty conv = implicit_conversion (type, TREE_TYPE (expr), expr, c_cast_p, - LOOKUP_NORMAL); + LOOKUP_NORMAL, complain); if (!conv || conv->bad_p) expr = NULL_TREE; else @@ -8768,7 +8827,7 @@ initialize_reference (tree type, tree expr, p = conversion_obstack_alloc (0); conv = reference_binding (type, TREE_TYPE (expr), expr, /*c_cast_p=*/false, - flags); + flags, complain); if (!conv || conv->bad_p) { if (complain & tf_error) Index: cp/cvt.c =================================================================== --- cp/cvt.c (revision 186600) +++ cp/cvt.c (working copy) @@ -408,12 +408,12 @@ convert_to_reference (tree reftype, tree expr, int tree rval = NULL_TREE; tree rval_as_conversion = NULL_TREE; bool can_convert_intype_to_type; + tsubst_flags_t complain = ((flags & LOOKUP_COMPLAIN) + ? tf_warning_or_error : tf_none); if (TREE_CODE (type) == FUNCTION_TYPE && TREE_TYPE (expr) == unknown_type_node) - expr = instantiate_type (type, expr, - (flags & LOOKUP_COMPLAIN) - ? tf_warning_or_error : tf_none); + expr = instantiate_type (type, expr, complain); if (expr == error_mark_node) return error_mark_node; @@ -425,7 +425,8 @@ convert_to_reference (tree reftype, tree expr, int intype = TYPE_MAIN_VARIANT (intype); - can_convert_intype_to_type = can_convert (type, intype); + can_convert_intype_to_type = can_convert (type, intype, complain); + if (!can_convert_intype_to_type && (convtype & CONV_IMPLICIT) && MAYBE_CLASS_TYPE_P (intype) && ! (flags & LOOKUP_NO_CONVERSION)) @@ -445,7 +446,7 @@ convert_to_reference (tree reftype, tree expr, int } } - if (((convtype & CONV_STATIC) && can_convert (intype, type)) + if (((convtype & CONV_STATIC) && can_convert (intype, type, complain)) || ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type)) { if (flags & LOOKUP_COMPLAIN) @@ -821,7 +822,8 @@ ocp_convert (tree type, tree expr, int convtype, i /* For copy-initialization, first we create a temp of the proper type with a user-defined conversion sequence, then we direct-initialize the target with the temp (see [dcl.init]). */ - ctor = build_user_type_conversion (type, ctor, flags); + ctor = build_user_type_conversion (type, ctor, flags, + tf_warning_or_error); else { VEC(tree,gc) *ctor_vec = make_tree_vector_single (ctor); @@ -1451,7 +1453,8 @@ build_type_conversion (tree xtype, tree expr) { /* C++: check to see if we can convert this aggregate type into the required type. */ - return build_user_type_conversion (xtype, expr, LOOKUP_NORMAL); + return build_user_type_conversion (xtype, expr, LOOKUP_NORMAL, + tf_warning_or_error); } /* Convert the given EXPR to one of a group of types suitable for use in an @@ -1609,7 +1612,8 @@ build_expr_type_conversion (int desires, tree expr if (winner) { tree type = non_reference (TREE_TYPE (TREE_TYPE (winner))); - return build_user_type_conversion (type, expr, LOOKUP_NORMAL); + return build_user_type_conversion (type, expr, LOOKUP_NORMAL, + tf_warning_or_error); } return NULL_TREE; Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 186600) +++ cp/cp-tree.h (working copy) @@ -4862,11 +4862,13 @@ extern bool null_ptr_cst_p (tree); extern bool null_member_pointer_value_p (tree); extern bool sufficient_parms_p (const_tree); extern tree type_decays_to (tree); -extern tree build_user_type_conversion (tree, tree, int); +extern tree build_user_type_conversion (tree, tree, int, + tsubst_flags_t); extern tree build_new_function_call (tree, VEC(tree,gc) **, bool, tsubst_flags_t); extern tree build_operator_new_call (tree, VEC(tree,gc) **, tree *, - tree *, tree *); + tree *, tree *, + tsubst_flags_t); extern tree build_new_method_call (tree, tree, VEC(tree,gc) **, tree, int, tree *, tsubst_flags_t); @@ -4878,18 +4880,21 @@ extern tree build_new_op (enum tree_code, int, t extern tree build_op_call (tree, VEC(tree,gc) **, tsubst_flags_t); extern tree build_op_delete_call (enum tree_code, tree, tree, bool, tree, tree); -extern bool can_convert (tree, tree); -extern bool can_convert_arg (tree, tree, tree, int); -extern bool can_convert_arg_bad (tree, tree, tree, int); +extern bool can_convert (tree, tree, tsubst_flags_t); +extern bool can_convert_arg (tree, tree, tree, int, + tsubst_flags_t); +extern bool can_convert_arg_bad (tree, tree, tree, int, + tsubst_flags_t); extern bool enforce_access (tree, tree, tree); extern void push_defarg_context (tree); extern void pop_defarg_context (void); -extern tree convert_default_arg (tree, tree, tree, int); -extern tree convert_arg_to_ellipsis (tree); +extern tree convert_default_arg (tree, tree, tree, int, + tsubst_flags_t); +extern tree convert_arg_to_ellipsis (tree, tsubst_flags_t); extern tree build_x_va_arg (tree, tree); extern tree cxx_type_promotes_to (tree); extern tree type_passed_as (tree); -extern tree convert_for_arg_passing (tree, tree); +extern tree convert_for_arg_passing (tree, tree, tsubst_flags_t); extern bool is_properly_derived_from (tree, tree); extern tree initialize_reference (tree, tree, int, tsubst_flags_t); Index: cp/search.c =================================================================== --- cp/search.c (revision 186600) +++ cp/search.c (working copy) @@ -1,7 +1,8 @@ /* Breadth-first and depth-first routines for searching multiple-inheritance lattice for GNU C++. Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 + 1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, + 2012 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) @@ -1891,7 +1892,8 @@ check_final_overrider (tree overrider, tree basefn } } else if (!pedantic - && can_convert (TREE_TYPE (base_type), TREE_TYPE (over_type))) + && can_convert (TREE_TYPE (base_type), TREE_TYPE (over_type), + tf_warning_or_error)) /* GNU extension, allow trivial pointer conversions such as converting to void *, or qualification conversion. */ {