From patchwork Mon Jun 4 14:15:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 162809 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 EF028B6F13 for ; Tue, 5 Jun 2012 00:17:39 +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=1339424260; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Message-ID:Date:From:User-Agent:MIME-Version: To:CC:Subject:Content-Type:Mailing-List:Precedence:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=q6gjWOXQnLIMgg3XRE1cKwuWjsk=; b=Ao/ZArrRazkb/ZJ 4ftxNBMOmu6uWjSavksq4PgjsF6SVtO9BS8x57NBxcV3TzeWlOt9E6yqwC5xhoMR OlivNp3pkVNJO5O8UFgd1IOBUfnhDFvxz7ETbxGOPwDlMmHxN16MdM7n9ZyZVBt2 l0QlJFSgF1o+K8gSIM0pWRpq8SQM= 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:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=MXRhUH06xg51TqrAb0okWrtWAUsQnMtIiipfF50wrwY5Pst3gLqZKkCxB54Qqd aGTCuX4aaGRm9PdsdU8BRo+3GXXNHYFnxHW8Uan997Mg1EPRQFIxnXZRdsCCDzX5 xtX06rMdTADF11Rn8qGDc8CgIFBEPDl8nPdw8PNpB2EN0=; Received: (qmail 31117 invoked by alias); 4 Jun 2012 14:17:31 -0000 Received: (qmail 31074 invoked by uid 22791); 4 Jun 2012 14:17:22 -0000 X-SWARE-Spam-Status: No, hits=-6.5 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_NO, RCVD_IN_HOSTKARMA_W, TW_FN, TW_PM, TW_VT, TW_WR, 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; Mon, 04 Jun 2012 14:17:00 +0000 Received: from acsinet21.oracle.com (acsinet21.oracle.com [141.146.126.237]) by rcsinet15.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id q54EGwSt027042 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 4 Jun 2012 14:16:59 GMT Received: from acsmt358.oracle.com (acsmt358.oracle.com [141.146.40.158]) by acsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q54EGwg9006235 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 4 Jun 2012 14:16:58 GMT Received: from abhmt118.oracle.com (abhmt118.oracle.com [141.146.116.70]) by acsmt358.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id q54EGw47004427; Mon, 4 Jun 2012 09:16:58 -0500 Received: from [192.168.1.4] (/79.17.189.238) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 04 Jun 2012 07:16:57 -0700 Message-ID: <4FCCC301.7040505@oracle.com> Date: Mon, 04 Jun 2012 16:15:29 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20120421 Thunderbird/12.0 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: Jason Merrill Subject: [C++ Patch] PR 53567 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, in this "error reporting routines re-entered" ICE we try to emit a warning from ocp_convert while we are already producing an error message (we get to ocp_convert via the usual tsubst (tf_none) called by dump_template_bindings). I considered whether we could avoid the specific problem by passing different FLAGS to ocp_convert when build_static_cast_1 is called with tf_none, but I think it would be tricky and error-prone, because ocp_convert has a mix of errors, warnings, errors not protected by flags & LOOKUP_COMPLAIN. Anyway, when I tried the usual tsubst_flags_t route, I saw a large patch but also quite a few loose ends solved (which I noticed other times), convert_to_reference isn't special anymore in having to "synthesize" a complain, all in all very few explicit tf_warning_or_error remain, and in safe places, as far as I can see. Bootstrapped and tested x86_64-linux. Thanks, Paolo. ///////////////////// /cp 2012-06-04 Paolo Carlini PR c++/53567 * typeck.c (cp_perform_integral_promotions): New, like perform_integral_promotions but also takes a tsubst_flags_t parameter. (pointer_diff): Add tsubst_flags_t parameter. (decay_conversion, cp_default_conversion, cp_build_array_ref, cp_build_binary_op, cp_build_unary_op, build_static_cast_1, build_reinterpret_cast_1, cp_build_modify_expr, convert_for_assignment): Adjust. * init.c (expand_virtual_init, expand_default_init, build_new, build_vec_delete_1, build_vec_init, build_delete): Adjust. * class.c (build_base_path): Likewise. * decl.c (compute_array_index_type): Likewise. * rtti.c (ifnonnull): Add tsubst_flags_t parameter. (build_typeid, build_dynamic_cast_1): Adjust. * except.c (initialize_handler_parm): Likewise. * typeck2.c (process_init_constructor_record): Likewise. * semantics.c (finish_goto_stmt, handle_omp_for_class_iterator, finish_static_assert): Likewise. * call.c (build_op_delete_call, convert_like_real, convert_arg_to_ellipsis, convert_for_arg_passing): Likewise. * cvt.c (cp_convert_to_pointer, convert_to_pointer_force, build_up_reference, convert_to_reference, cp_convert, cp_convert_and_check, ocp_convert, convert_force): Add tsubst_flags_t parameter. * cp-tree.h: Adjust prototypes. /testsuite 2012-06-04 Paolo Carlini PR c++/53567 * g++.dg/cpp0x/alias-decl-19.C: New. Index: testsuite/g++.dg/cpp0x/alias-decl-19.C =================================================================== --- testsuite/g++.dg/cpp0x/alias-decl-19.C (revision 0) +++ testsuite/g++.dg/cpp0x/alias-decl-19.C (revision 0) @@ -0,0 +1,31 @@ +// PR c++/53567 +// { dg-do compile { target c++11 } } + +template struct IntegerType { typedef unsigned type; }; + +template +using UnderlyingEnumType = typename IntegerType EnumT(0))>::type; + +template > +struct EnumMask +{ + constexpr EnumMask(EnumT val) : m_val(val) {} + operator EnumT() { return m_val; } + + EnumT m_val; +}; + +enum class A : unsigned { x }; + +template +EnumMask operator ~(EnumT lhs) +{ + return EnumT(~unsigned(lhs) & unsigned(EnumT::maskAll)); // { dg-error "not a member" } + +} + +int main() +{ + ~A::x; + return 0; +} Index: cp/typeck.c =================================================================== --- cp/typeck.c (revision 188167) +++ cp/typeck.c (working copy) @@ -53,7 +53,7 @@ static tree rationalize_conditional_expr (enum tre static int comp_ptr_ttypes_real (tree, tree, int); 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 pointer_diff (tree, tree, tree, tsubst_flags_t); static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t); static void casts_away_constness_r (tree *, tree *, tsubst_flags_t); static bool casts_away_constness (tree, tree, tsubst_flags_t); @@ -1907,7 +1907,7 @@ decay_conversion (tree exp, tsubst_flags_t complai /* This way is better for a COMPONENT_REF since it can simplify the offset for a component. */ adr = cp_build_addr_expr (exp, complain); - return cp_convert (ptrtype, adr); + return cp_convert (ptrtype, adr, complain); } /* If a bitfield is used in a context where integral promotion @@ -1951,12 +1951,12 @@ cp_default_conversion (tree exp, tsubst_flags_t co /* Check for target-specific promotions. */ tree promoted_type = targetm.promoted_type (TREE_TYPE (exp)); if (promoted_type) - exp = cp_convert (promoted_type, exp); + exp = cp_convert (promoted_type, exp, complain); /* Perform the integral promotions first so that bitfield expressions (which may promote to "int", even if the bitfield is declared "unsigned") are promoted correctly. */ else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp))) - exp = perform_integral_promotions (exp); + exp = cp_perform_integral_promotions (exp, complain); /* Perform the other conversions. */ exp = decay_conversion (exp, complain); @@ -1976,7 +1976,7 @@ default_conversion (tree exp) converted value. */ tree -perform_integral_promotions (tree expr) +cp_perform_integral_promotions (tree expr, tsubst_flags_t complain) { tree type; tree promoted_type; @@ -1996,10 +1996,18 @@ tree return expr; promoted_type = type_promotes_to (type); if (type != promoted_type) - expr = cp_convert (promoted_type, expr); + expr = cp_convert (promoted_type, expr, complain); return expr; } +/* C version. */ + +tree +perform_integral_promotions (tree expr) +{ + return cp_perform_integral_promotions (expr, tf_warning_or_error); +} + /* Returns nonzero iff exp is a STRING_CST or the result of applying decay_conversion to one. */ @@ -2946,7 +2954,7 @@ cp_build_array_ref (location_t loc, tree array, tr does not say that we should. In fact, the natural thing would seem to be to convert IDX to ptrdiff_t; we're performing pointer arithmetic.) */ - idx = perform_integral_promotions (idx); + idx = cp_perform_integral_promotions (idx, complain); /* An array that is indexed by a non-constant cannot be stored in a register; we must be able to do @@ -3868,7 +3876,8 @@ cp_build_binary_op (location_t location, if (code0 == POINTER_TYPE && code1 == POINTER_TYPE && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0), TREE_TYPE (type1))) - return pointer_diff (op0, op1, common_pointer_type (type0, type1)); + return pointer_diff (op0, op1, common_pointer_type (type0, type1), + complain); /* In all other cases except pointer - int, the usual arithmetic rules apply. */ else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE)) @@ -4004,7 +4013,7 @@ cp_build_binary_op (location_t location, /* Convert the shift-count to an integer, regardless of size of value being shifted. */ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = cp_convert (integer_type_node, op1); + op1 = cp_convert (integer_type_node, op1, complain); /* Avoid converting op1 to result_type later. */ converted = 1; } @@ -4032,7 +4041,7 @@ cp_build_binary_op (location_t location, /* Convert the shift-count to an integer, regardless of size of value being shifted. */ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = cp_convert (integer_type_node, op1); + op1 = cp_convert (integer_type_node, op1, complain); /* Avoid converting op1 to result_type later. */ converted = 1; } @@ -4063,7 +4072,7 @@ cp_build_binary_op (location_t location, /* Convert the shift-count to an integer, regardless of size of value being shifted. */ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = cp_convert (integer_type_node, op1); + op1 = cp_convert (integer_type_node, op1, complain); } break; @@ -4163,12 +4172,12 @@ cp_build_binary_op (location_t location, op0 = cp_build_binary_op (location, TRUTH_ANDIF_EXPR, e1, e2, complain); - op1 = cp_convert (TREE_TYPE (op0), integer_one_node); + op1 = cp_convert (TREE_TYPE (op0), integer_one_node, complain); } else { op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier); - op1 = cp_convert (TREE_TYPE (op0), op1); + op1 = cp_convert (TREE_TYPE (op0), op1, complain); } result_type = TREE_TYPE (op0); } @@ -4191,9 +4200,9 @@ cp_build_binary_op (location_t location, CPO_COMPARISON, complain); if (!same_type_p (TREE_TYPE (op0), type)) - op0 = cp_convert_and_check (type, op0); + op0 = cp_convert_and_check (type, op0, complain); if (!same_type_p (TREE_TYPE (op1), type)) - op1 = cp_convert_and_check (type, op1); + op1 = cp_convert_and_check (type, op1, complain); if (op0 == error_mark_node || op1 == error_mark_node) return error_mark_node; @@ -4457,16 +4466,16 @@ cp_build_binary_op (location_t location, if (first_complex) { if (TREE_TYPE (op0) != result_type) - op0 = cp_convert_and_check (result_type, op0); + op0 = cp_convert_and_check (result_type, op0, complain); if (TREE_TYPE (op1) != real_type) - op1 = cp_convert_and_check (real_type, op1); + op1 = cp_convert_and_check (real_type, op1, complain); } else { if (TREE_TYPE (op0) != real_type) - op0 = cp_convert_and_check (real_type, op0); + op0 = cp_convert_and_check (real_type, op0, complain); if (TREE_TYPE (op1) != result_type) - op1 = cp_convert_and_check (result_type, op1); + op1 = cp_convert_and_check (result_type, op1, complain); } if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK) return error_mark_node; @@ -4551,7 +4560,7 @@ cp_build_binary_op (location_t location, tree val = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode); if (val != 0) - return cp_convert (boolean_type_node, val); + return cp_convert (boolean_type_node, val, complain); op0 = xop0, op1 = xop1; converted = 1; resultcode = xresultcode; @@ -4581,9 +4590,9 @@ cp_build_binary_op (location_t location, if (! converted) { if (TREE_TYPE (op0) != result_type) - op0 = cp_convert_and_check (result_type, op0); + op0 = cp_convert_and_check (result_type, op0, complain); if (TREE_TYPE (op1) != result_type) - op1 = cp_convert_and_check (result_type, op1); + op1 = cp_convert_and_check (result_type, op1, complain); if (op0 == error_mark_node || op1 == error_mark_node) return error_mark_node; @@ -4595,7 +4604,7 @@ cp_build_binary_op (location_t location, result = build2 (resultcode, build_type, op0, op1); result = fold_if_not_in_template (result); if (final_type != 0) - result = cp_convert (final_type, result); + result = cp_convert (final_type, result, complain); if (TREE_OVERFLOW_P (result) && !TREE_OVERFLOW_P (op0) @@ -4628,7 +4637,7 @@ cp_pointer_int_sum (enum tree_code resultcode, tre The resulting tree has type int. */ static tree -pointer_diff (tree op0, tree op1, tree ptrtype) +pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain) { tree result; tree restype = ptrdiff_type_node; @@ -4638,24 +4647,48 @@ static tree return error_mark_node; if (TREE_CODE (target_type) == VOID_TYPE) - permerror (input_location, "ISO C++ forbids using pointer of type % in subtraction"); + { + if (complain & tf_error) + permerror (input_location, "ISO C++ forbids using pointer of " + "type % in subtraction"); + else + return error_mark_node; + } if (TREE_CODE (target_type) == FUNCTION_TYPE) - permerror (input_location, "ISO C++ forbids using pointer to a function in subtraction"); + { + if (complain & tf_error) + permerror (input_location, "ISO C++ forbids using pointer to " + "a function in subtraction"); + else + return error_mark_node; + } if (TREE_CODE (target_type) == METHOD_TYPE) - permerror (input_location, "ISO C++ forbids using pointer to a method in subtraction"); + { + if (complain & tf_error) + permerror (input_location, "ISO C++ forbids using pointer to " + "a method in subtraction"); + else + return error_mark_node; + } /* First do the subtraction as integers; then drop through to build the divide operator. */ op0 = cp_build_binary_op (input_location, MINUS_EXPR, - cp_convert (restype, op0), - cp_convert (restype, op1), - tf_warning_or_error); + cp_convert (restype, op0, complain), + cp_convert (restype, op1, complain), + complain); /* This generates an error if op1 is a pointer to an incomplete type. */ if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1)))) - error ("invalid use of a pointer to an incomplete type in pointer arithmetic"); + { + if (complain & tf_error) + error ("invalid use of a pointer to an incomplete type in " + "pointer arithmetic"); + else + return error_mark_node; + } op1 = (TYPE_PTROB_P (ptrtype) ? size_in_bytes (target_type) @@ -4663,7 +4696,8 @@ static tree /* Do the division. */ - result = build2 (EXACT_DIV_EXPR, restype, op0, cp_convert (restype, op1)); + result = build2 (EXACT_DIV_EXPR, restype, op0, + cp_convert (restype, op1, complain)); return fold_if_not_in_template (result); } @@ -5176,7 +5210,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, else { if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg))) - arg = perform_integral_promotions (arg); + arg = cp_perform_integral_promotions (arg, complain); /* Make sure the result is not an lvalue: a unary plus or minus expression is always a rvalue. */ @@ -5201,7 +5235,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, arg, true))) errstring = _("wrong type argument to bit-complement"); else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg))) - arg = perform_integral_promotions (arg); + arg = cp_perform_integral_promotions (arg, complain); break; case ABS_EXPR: @@ -5359,7 +5393,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, else inc = integer_one_node; - inc = cp_convert (argtype, inc); + inc = cp_convert (argtype, inc, complain); /* If 'arg' is an Objective-C PROPERTY_REF expression, then we need to ask Objective-C to build the increment or decrement @@ -6075,7 +6109,7 @@ build_static_cast_1 (tree type, tree expr, bool c_ || SCALAR_FLOAT_TYPE_P (type)) && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype) || SCALAR_FLOAT_TYPE_P (intype))) - return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL); + return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL, complain); if (TYPE_PTR_P (type) && TYPE_PTR_P (intype) && CLASS_TYPE_P (TREE_TYPE (type)) @@ -6418,7 +6452,7 @@ build_reinterpret_cast_1 (tree type, tree expr, bo return error_mark_node; } - return cp_convert (type, expr); + return cp_convert (type, expr, complain); } tree @@ -7079,7 +7113,7 @@ cp_build_modify_expr (tree lhs, enum tree_code mod NULL_TREE, 0, complain, LOOKUP_IMPLICIT); if (!same_type_p (lhstype, olhstype)) - newrhs = cp_convert_and_check (lhstype, newrhs); + newrhs = cp_convert_and_check (lhstype, newrhs, complain); if (modifycode != INIT_EXPR) { @@ -7600,7 +7634,7 @@ convert_for_assignment (tree type, tree rhs, if (!warn_pmf2ptr && TYPE_PTR_P (type) && TYPE_PTRMEMFUNC_P (rhstype)) - rhs = cp_convert (strip_top_quals (type), rhs); + rhs = cp_convert (strip_top_quals (type), rhs, complain); else { if (complain & tf_error) Index: cp/init.c =================================================================== --- cp/init.c (revision 188167) +++ cp/init.c (working copy) @@ -1180,7 +1180,7 @@ expand_virtual_init (tree binfo, tree decl) gcc_assert (vtbl_ptr != error_mark_node); /* Assign the vtable to the vptr. */ - vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0); + vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0, tf_warning_or_error); finish_expr_stmt (cp_build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl, tf_warning_or_error)); } @@ -1598,7 +1598,8 @@ expand_default_init (tree binfo, tree true_exp, tr have already built up the constructor call so we could wrap it in an exception region. */; else - init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); + init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, + flags, complain); if (TREE_CODE (init) == MUST_NOT_THROW_EXPR) /* We need to protect the initialization of a catch parm with a @@ -2815,7 +2816,7 @@ build_new (VEC(tree,gc) **placement, tree type, tr return error_mark_node; } nelts = mark_rvalue_use (nelts); - nelts = cp_save_expr (cp_convert (sizetype, nelts)); + nelts = cp_save_expr (cp_convert (sizetype, nelts, complain)); } /* ``A reference cannot be created by the new operator. A reference @@ -3012,12 +3013,12 @@ build_vec_delete_1 (tree base, tree maxindex, tree base_tbd = cp_build_binary_op (input_location, MINUS_EXPR, cp_convert (string_type_node, - base), + base, complain), cookie_size, complain); if (base_tbd == error_mark_node) return error_mark_node; - base_tbd = cp_convert (ptype, base_tbd); + base_tbd = cp_convert (ptype, base_tbd, complain); /* True size with header. */ virtual_size = size_binop (PLUS_EXPR, virtual_size, cookie_size); } @@ -3189,14 +3190,14 @@ build_vec_init (tree base, tree maxindex, tree ini return stmt_expr; } - maxindex = cp_convert (ptrdiff_type_node, maxindex); + maxindex = cp_convert (ptrdiff_type_node, maxindex, complain); if (TREE_CODE (atype) == ARRAY_TYPE) { ptype = build_pointer_type (type); base = decay_conversion (base, complain); if (base == error_mark_node) return error_mark_node; - base = cp_convert (ptype, base); + base = cp_convert (ptype, base, complain); } else ptype = atype; @@ -3665,7 +3666,7 @@ build_delete (tree type, tree addr, special_functi addr = save_expr (addr); /* Throw away const and volatile on target type of addr. */ - addr = convert_force (build_pointer_type (type), addr, 0); + addr = convert_force (build_pointer_type (type), addr, 0, complain); } else if (TREE_CODE (type) == ARRAY_TYPE) { @@ -3691,7 +3692,7 @@ build_delete (tree type, tree addr, special_functi if (TREE_SIDE_EFFECTS (addr)) addr = save_expr (addr); - addr = convert_force (build_pointer_type (type), addr, 0); + addr = convert_force (build_pointer_type (type), addr, 0, complain); } gcc_assert (MAYBE_CLASS_TYPE_P (type)); Index: cp/class.c =================================================================== --- cp/class.c (revision 188167) +++ cp/class.c (working copy) @@ -366,7 +366,7 @@ build_base_path (enum tree_code code, /* Now that we've saved expr, build the real null test. */ if (null_test) { - tree zero = cp_convert (TREE_TYPE (expr), nullptr_node); + tree zero = cp_convert (TREE_TYPE (expr), nullptr_node, complain); null_test = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, expr, zero); } Index: cp/decl.c =================================================================== --- cp/decl.c (revision 188167) +++ cp/decl.c (working copy) @@ -8104,9 +8104,10 @@ compute_array_index_type (tree name, tree size, ts processing_template_decl = 0; itype = cp_build_binary_op (input_location, MINUS_EXPR, - cp_convert (ssizetype, size), - cp_convert (ssizetype, integer_one_node), - tf_warning_or_error); + cp_convert (ssizetype, size, complain), + cp_convert (ssizetype, integer_one_node, + complain), + complain); itype = fold (itype); processing_template_decl = saved_processing_template_decl; Index: cp/rtti.c =================================================================== --- cp/rtti.c (revision 188167) +++ cp/rtti.c (working copy) @@ -99,7 +99,7 @@ VEC(tree,gc) *unemitted_tinfo_decls; and are generated as needed. */ static GTY (()) VEC(tinfo_s,gc) *tinfo_descs; -static tree ifnonnull (tree, tree); +static tree ifnonnull (tree, tree, tsubst_flags_t); static tree tinfo_name (tree, bool); static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t); static tree throw_bad_cast (void); @@ -336,7 +336,8 @@ build_typeid (tree exp) This is an lvalue use of expr then. */ exp = mark_lvalue_use (exp); exp = stabilize_reference (exp); - cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0)); + cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0), + tf_warning_or_error); } exp = get_tinfo_decl_dynamic (exp); @@ -498,12 +499,13 @@ get_typeid (tree type) RESULT, it must have previously had a save_expr applied to it. */ static tree -ifnonnull (tree test, tree result) +ifnonnull (tree test, tree result, tsubst_flags_t complain) { return build3 (COND_EXPR, TREE_TYPE (result), build2 (EQ_EXPR, boolean_type_node, test, - cp_convert (TREE_TYPE (test), nullptr_node)), - cp_convert (TREE_TYPE (result), nullptr_node), + cp_convert (TREE_TYPE (test), nullptr_node, + complain)), + cp_convert (TREE_TYPE (result), nullptr_node, complain), result); } @@ -596,7 +598,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst /* Apply trivial conversion T -> T& for dereferenced ptrs. */ expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT, - LOOKUP_NORMAL, NULL_TREE); + LOOKUP_NORMAL, NULL_TREE, complain); } /* The dynamic_cast operator shall not cast away constness. */ @@ -644,7 +646,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst expr1 = build_headof (expr); if (TREE_TYPE (expr1) != type) expr1 = build1 (NOP_EXPR, type, expr1); - return ifnonnull (expr, expr1); + return ifnonnull (expr, expr1, complain); } else { @@ -752,12 +754,12 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst neq = cp_truthvalue_conversion (result); return cp_convert (type, build3 (COND_EXPR, TREE_TYPE (result), - neq, result, bad)); + neq, result, bad), complain); } /* Now back to the type we want from a void*. */ - result = cp_convert (type, result); - return ifnonnull (expr, result); + result = cp_convert (type, result, complain); + return ifnonnull (expr, result, complain); } } else Index: cp/except.c =================================================================== --- cp/except.c (revision 188167) +++ cp/except.c (working copy) @@ -424,7 +424,8 @@ initialize_handler_parm (tree decl, tree exp) && TYPE_PTR_P (TREE_TYPE (init_type))) exp = cp_build_addr_expr (exp, tf_warning_or_error); - exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0); + exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0, + tf_warning_or_error); init = convert_from_reference (exp); @@ -435,7 +436,8 @@ initialize_handler_parm (tree decl, tree exp) /* Generate the copy constructor call directly so we can wrap it. See also expand_default_init. */ init = ocp_convert (TREE_TYPE (decl), init, - CONV_IMPLICIT|CONV_FORCE_TEMP, 0); + CONV_IMPLICIT|CONV_FORCE_TEMP, 0, + tf_warning_or_error); /* Force cleanups now to avoid nesting problems with the MUST_NOT_THROW_EXPR. */ init = fold_build_cleanup_point_expr (TREE_TYPE (init), init); Index: cp/typeck2.c =================================================================== --- cp/typeck2.c (revision 188167) +++ cp/typeck2.c (working copy) @@ -1265,7 +1265,7 @@ process_init_constructor_record (tree type, tree i /* If this is a bitfield, now convert to the lowered type. */ if (type != TREE_TYPE (field)) - next = cp_convert_and_check (TREE_TYPE (field), next); + next = cp_convert_and_check (TREE_TYPE (field), next, complain); flags |= picflag_from_initializer (next); CONSTRUCTOR_APPEND_ELT (v, field, next); } Index: cp/semantics.c =================================================================== --- cp/semantics.c (revision 188167) +++ cp/semantics.c (working copy) @@ -565,7 +565,8 @@ finish_goto_stmt (tree destination) destination = mark_rvalue_use (destination); if (!processing_template_decl) { - destination = cp_convert (ptr_type_node, destination); + destination = cp_convert (ptr_type_node, destination, + tf_warning_or_error); if (error_operand_p (destination)) return NULL_TREE; } @@ -4527,7 +4528,8 @@ handle_omp_for_class_iterator (int i, location_t l if (error_operand_p (iter_incr)) return true; incr = TREE_OPERAND (rhs, 1); - incr = cp_convert (TREE_TYPE (diff), incr); + incr = cp_convert (TREE_TYPE (diff), incr, + tf_warning_or_error); if (TREE_CODE (rhs) == MINUS_EXPR) { incr = build1 (NEGATE_EXPR, TREE_TYPE (diff), incr); @@ -4582,7 +4584,7 @@ handle_omp_for_class_iterator (int i, location_t l return true; } - incr = cp_convert (TREE_TYPE (diff), incr); + incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error); for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE && OMP_CLAUSE_DECL (c) == iter) @@ -5131,7 +5133,7 @@ finish_static_assert (tree condition, tree message /* Fold the expression and convert it to a boolean value. */ condition = fold_non_dependent_expr (condition); - condition = cp_convert (boolean_type_node, condition); + condition = cp_convert (boolean_type_node, condition, tf_warning_or_error); condition = maybe_constant_value (condition); if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition)) Index: cp/call.c =================================================================== --- cp/call.c (revision 188167) +++ cp/call.c (working copy) @@ -5413,7 +5413,7 @@ build_op_delete_call (enum tree_code code, tree ad fns = lookup_name_nonclass (fnname); /* Strip const and volatile from addr. */ - addr = cp_convert (ptr_type_node, addr); + addr = cp_convert (ptr_type_node, addr, tf_warning_or_error); if (placement) { @@ -5685,9 +5685,10 @@ convert_like_real (conversion *convs, tree expr, t complain); if (convs->kind == ck_ref_bind) return convert_to_reference (totype, expr, CONV_IMPLICIT, - LOOKUP_NORMAL, NULL_TREE); + LOOKUP_NORMAL, NULL_TREE, + complain); else - return cp_convert (totype, expr); + return cp_convert (totype, expr, complain); } else if (t->kind == ck_user || !t->bad_p) { @@ -5712,7 +5713,7 @@ convert_like_real (conversion *convs, tree expr, t permerror (DECL_SOURCE_LOCATION (fn), " initializing argument %P of %qD", argnum, fn); - return cp_convert (totype, expr); + return cp_convert (totype, expr, complain); } if (issue_conversion_warnings && (complain & tf_warning)) @@ -5851,7 +5852,7 @@ convert_like_real (conversion *convs, tree expr, t /* Take the address explicitly rather than via decay_conversion to avoid the error about taking the address of a temporary. */ array = cp_build_addr_expr (array, complain); - array = cp_convert (build_pointer_type (elttype), array); + array = cp_convert (build_pointer_type (elttype), array, complain); /* Build up the initializer_list object. */ totype = complete_type (totype); @@ -6017,7 +6018,7 @@ convert_like_real (conversion *convs, tree expr, t reference. This will adjust the pointer if a derived to base conversion is being performed. */ expr = cp_convert (build_pointer_type (TREE_TYPE (ref_type)), - expr); + expr, complain); /* Convert the pointer to the desired reference type. */ return build_nop (ref_type, expr); } @@ -6099,9 +6100,9 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t if (complain & tf_warning) warning_at (loc, 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 = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg, complain); } - arg = perform_integral_promotions (arg); + arg = cp_perform_integral_promotions (arg, complain); } arg = require_complete_type (arg); @@ -6336,7 +6337,7 @@ convert_for_arg_passing (tree type, tree val, tsub && COMPLETE_TYPE_P (type) && INT_CST_LT_UNSIGNED (TYPE_SIZE (type), TYPE_SIZE (integer_type_node))) - val = perform_integral_promotions (val); + val = cp_perform_integral_promotions (val, complain); if ((complain & tf_warning) && warn_suggest_attribute_format) { Index: cp/cvt.c =================================================================== --- cp/cvt.c (revision 188167) +++ cp/cvt.c (working copy) @@ -38,10 +38,10 @@ along with GCC; see the file COPYING3. If not see #include "decl.h" #include "target.h" -static tree cp_convert_to_pointer (tree, tree); -static tree convert_to_pointer_force (tree, tree); +static tree cp_convert_to_pointer (tree, tree, tsubst_flags_t); +static tree convert_to_pointer_force (tree, tree, tsubst_flags_t); static tree build_type_conversion (tree, tree); -static tree build_up_reference (tree, tree, int, tree); +static tree build_up_reference (tree, tree, int, tree, tsubst_flags_t); static void warn_ref_binding (location_t, tree, tree, tree); /* Change of width--truncation and extension of integers or reals-- @@ -74,7 +74,7 @@ static void warn_ref_binding (location_t, tree, tr else try C-style pointer conversion. */ static tree -cp_convert_to_pointer (tree type, tree expr) +cp_convert_to_pointer (tree type, tree expr, tsubst_flags_t complain) { tree intype = TREE_TYPE (expr); enum tree_code form; @@ -89,15 +89,17 @@ static tree intype = complete_type (intype); if (!COMPLETE_TYPE_P (intype)) { - error_at (loc, "can%'t convert from incomplete type %qT to %qT", - intype, type); + if (complain & tf_error) + error_at (loc, "can%'t convert from incomplete type %qT to %qT", + intype, type); return error_mark_node; } rval = build_type_conversion (type, expr); if (rval) { - if (rval == error_mark_node) + if ((complain & tf_error) + && rval == error_mark_node) error_at (loc, "conversion of %qE from %qT to %qT is ambiguous", expr, intype, type); return rval; @@ -111,7 +113,7 @@ static tree { if (TYPE_PTRMEMFUNC_P (intype) || TREE_CODE (intype) == METHOD_TYPE) - return convert_member_func_to_ptr (type, expr, tf_warning_or_error); + return convert_member_func_to_ptr (type, expr, complain); if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE) return build_nop (type, expr); intype = TREE_TYPE (expr); @@ -159,8 +161,7 @@ static tree if (binfo || same_p) { if (binfo) - expr = build_base_path (code, expr, binfo, 0, - tf_warning_or_error); + expr = build_base_path (code, expr, binfo, 0, complain); /* Add any qualifier conversions. */ return build_nop (type, expr); } @@ -168,8 +169,9 @@ static tree if (TYPE_PTRMEMFUNC_P (type)) { - error_at (loc, "cannot convert %qE from type %qT to type %qT", - expr, intype, type); + if (complain & tf_error) + error_at (loc, "cannot convert %qE from type %qT to type %qT", + expr, intype, type); return error_mark_node; } @@ -178,20 +180,20 @@ static tree else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype)) || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))) return convert_ptrmem (type, expr, /*allow_inverse_p=*/false, - /*c_cast_p=*/false, tf_warning_or_error); + /*c_cast_p=*/false, complain); else if (TYPE_PTRMEMFUNC_P (intype)) { if (!warn_pmf2ptr) { if (TREE_CODE (expr) == PTRMEM_CST) - return cp_convert_to_pointer (type, - PTRMEM_CST_MEMBER (expr)); + return cp_convert_to_pointer (type, PTRMEM_CST_MEMBER (expr), + complain); else if (TREE_CODE (expr) == OFFSET_REF) { tree object = TREE_OPERAND (expr, 0); return get_member_function_from_ptrfunc (&object, TREE_OPERAND (expr, 1), - tf_warning_or_error); + complain); } } error_at (loc, "cannot convert %qE from type %qT to type %qT", @@ -201,14 +203,15 @@ static tree if (null_ptr_cst_p (expr)) { - if (c_inhibit_evaluation_warnings == 0 + if ((complain & tf_warning) + && c_inhibit_evaluation_warnings == 0 && !NULLPTR_TYPE_P (TREE_TYPE (expr))) warning_at (loc, OPT_Wzero_as_null_pointer_constant, "zero as null pointer constant"); if (TYPE_PTRMEMFUNC_P (type)) return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0, - /*c_cast_p=*/false, tf_warning_or_error); + /*c_cast_p=*/false, complain); if (TYPE_PTRDATAMEM_P (type)) { @@ -223,7 +226,8 @@ static tree } else if (TYPE_PTRMEM_P (type) && INTEGRAL_CODE_P (form)) { - error_at (loc, "invalid conversion from %qT to %qT", intype, type); + if (complain & tf_error) + error_at (loc, "invalid conversion from %qT to %qT", intype, type); return error_mark_node; } @@ -231,7 +235,8 @@ static tree { if (TYPE_PRECISION (intype) == POINTER_SIZE) return build1 (CONVERT_EXPR, type, expr); - expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr); + expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr, + complain); /* Modes may be different but sizes should be the same. There is supposed to be some integral type that is the same width as a pointer. */ @@ -242,10 +247,11 @@ static tree } if (type_unknown_p (expr)) - return instantiate_type (type, expr, tf_warning_or_error); + return instantiate_type (type, expr, complain); - error_at (loc, "cannot convert %qE from type %qT to type %qT", - expr, intype, type); + if (complain & tf_error) + error_at (loc, "cannot convert %qE from type %qT to type %qT", + expr, intype, type); return error_mark_node; } @@ -254,7 +260,7 @@ static tree (such as conversion from sub-type to private super-type). */ static tree -convert_to_pointer_force (tree type, tree expr) +convert_to_pointer_force (tree type, tree expr, tsubst_flags_t complain) { tree intype = TREE_TYPE (expr); enum tree_code form = TREE_CODE (intype); @@ -284,8 +290,7 @@ static tree return error_mark_node; if (binfo) { - expr = build_base_path (code, expr, binfo, 0, - tf_warning_or_error); + expr = build_base_path (code, expr, binfo, 0, complain); if (expr == error_mark_node) return error_mark_node; /* Add any qualifier conversions. */ @@ -297,7 +302,7 @@ static tree } } - return cp_convert_to_pointer (type, expr); + return cp_convert_to_pointer (type, expr, complain); } /* We are passing something to a function which requires a reference. @@ -309,7 +314,8 @@ static tree If DIRECT_BIND is set, DECL is the reference we're binding to. */ static tree -build_up_reference (tree type, tree arg, int flags, tree decl) +build_up_reference (tree type, tree arg, int flags, tree decl, + tsubst_flags_t complain) { tree rval; tree argtype = TREE_TYPE (arg); @@ -351,12 +357,12 @@ static tree return error_mark_node; if (binfo == NULL_TREE) return error_not_base_type (target_type, argtype); - rval = build_base_path (PLUS_EXPR, rval, binfo, 1, - tf_warning_or_error); + rval = build_base_path (PLUS_EXPR, rval, binfo, 1, complain); } else rval - = convert_to_pointer_force (build_pointer_type (target_type), rval); + = convert_to_pointer_force (build_pointer_type (target_type), + rval, complain); return build_nop (type, rval); } @@ -403,15 +409,13 @@ warn_ref_binding (location_t loc, tree reftype, tr tree convert_to_reference (tree reftype, tree expr, int convtype, - int flags, tree decl) + int flags, tree decl, tsubst_flags_t complain) { tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype)); tree intype; 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); location_t loc = EXPR_LOC_OR_HERE (expr); if (TREE_CODE (type) == FUNCTION_TYPE @@ -457,7 +461,8 @@ convert_to_reference (tree reftype, tree expr, int tree ttl = TREE_TYPE (reftype); tree ttr = lvalue_type (expr); - if (! real_lvalue_p (expr)) + if ((complain & tf_warning) + && ! real_lvalue_p (expr)) warn_ref_binding (loc, reftype, intype, decl); if (! (convtype & CONV_CONST) @@ -466,7 +471,7 @@ convert_to_reference (tree reftype, tree expr, int ttr, reftype); } - return build_up_reference (reftype, expr, flags, decl); + return build_up_reference (reftype, expr, flags, decl, complain); } else if ((convtype & CONV_REINTERPRET) && lvalue_p (expr)) { @@ -477,16 +482,17 @@ convert_to_reference (tree reftype, tree expr, int /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they meant. */ - if (TREE_CODE (intype) == POINTER_TYPE + if ((complain & tf_warning) + && TREE_CODE (intype) == POINTER_TYPE && (comptypes (TREE_TYPE (intype), type, COMPARE_BASE | COMPARE_DERIVED))) warning_at (loc, 0, "casting %qT to %qT does not dereference pointer", intype, reftype); - rval = cp_build_addr_expr (expr, tf_warning_or_error); + rval = cp_build_addr_expr (expr, complain); if (rval != error_mark_node) rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), - rval, 0); + rval, 0, complain); if (rval != error_mark_node) rval = build1 (NOP_EXPR, reftype, rval); } @@ -494,11 +500,12 @@ convert_to_reference (tree reftype, tree expr, int { rval = convert_for_initialization (NULL_TREE, type, expr, flags, ICR_CONVERTING, 0, 0, - tf_warning_or_error); + complain); if (rval == NULL_TREE || rval == error_mark_node) return rval; - warn_ref_binding (loc, reftype, intype, decl); - rval = build_up_reference (reftype, rval, flags, decl); + if (complain & tf_warning) + warn_ref_binding (loc, reftype, intype, decl); + rval = build_up_reference (reftype, rval, flags, decl, complain); } if (rval) @@ -595,9 +602,9 @@ cp_fold_convert (tree type, tree expr) /* C++ conversions, preference to static cast conversions. */ tree -cp_convert (tree type, tree expr) +cp_convert (tree type, tree expr, tsubst_flags_t complain) { - return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL); + return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL, complain); } /* C++ equivalent of convert_and_check but using cp_convert as the @@ -608,16 +615,17 @@ tree i.e. because of language rules and not because of an explicit cast. */ tree -cp_convert_and_check (tree type, tree expr) +cp_convert_and_check (tree type, tree expr, tsubst_flags_t complain) { tree result; if (TREE_TYPE (expr) == type) return expr; - result = cp_convert (type, expr); + result = cp_convert (type, expr, complain); - if (c_inhibit_evaluation_warnings == 0 + if ((complain & tf_warning) + && c_inhibit_evaluation_warnings == 0 && !TREE_OVERFLOW_P (expr) && result != error_mark_node) warnings_for_convert_and_check (type, expr, result); @@ -630,7 +638,8 @@ tree FLAGS indicates how we should behave. */ tree -ocp_convert (tree type, tree expr, int convtype, int flags) +ocp_convert (tree type, tree expr, int convtype, int flags, + tsubst_flags_t complain) { tree e = expr; enum tree_code code = TREE_CODE (type); @@ -647,7 +656,8 @@ tree if ((invalid_conv_diag = targetm.invalid_conversion (TREE_TYPE (expr), type))) { - error (invalid_conv_diag); + if (complain & tf_error) + error (invalid_conv_diag); return error_mark_node; } @@ -696,7 +706,7 @@ tree if (code == VOID_TYPE && (convtype & CONV_STATIC)) { - e = convert_to_void (e, ICV_CAST, tf_warning_or_error); + e = convert_to_void (e, ICV_CAST, complain); return e; } @@ -714,9 +724,15 @@ tree && ! (convtype & CONV_STATIC)) || TREE_CODE (intype) == POINTER_TYPE) { - if (flags & LOOKUP_COMPLAIN) - permerror (loc, "conversion from %q#T to %q#T", intype, type); - if (!flag_permissive) + if (complain & tf_error) + { + if (flags & LOOKUP_COMPLAIN) + permerror (loc, "conversion from %q#T to %q#T", + intype, type); + if (!flag_permissive) + return error_mark_node; + } + else return error_mark_node; } @@ -727,7 +743,8 @@ tree the original value is within the range of the enumeration values. Otherwise, the resulting enumeration value is unspecified. */ - if (TREE_CODE (expr) == INTEGER_CST + if ((complain & tf_warning) + && TREE_CODE (expr) == INTEGER_CST && !int_fits_type_p (expr, ENUM_UNDERLYING_TYPE (type))) warning_at (loc, OPT_Wconversion, "the result of the conversion is unspecified because " @@ -740,7 +757,8 @@ tree rval = build_type_conversion (type, e); if (rval) return rval; - if (flags & LOOKUP_COMPLAIN) + if ((complain & tf_error) + && (flags & LOOKUP_COMPLAIN)) error_at (loc, "%q#T used where a %qT was expected", intype, type); return error_mark_node; } @@ -748,8 +766,10 @@ tree { if (TREE_CODE (intype) == VOID_TYPE) { - error_at (loc, "could not convert %qE from % to %", - expr); + if (complain & tf_error) + error_at (loc, + "could not convert %qE from % to %", + expr); return error_mark_node; } @@ -768,7 +788,7 @@ tree if (NULLPTR_TYPE_P (type) && e && null_ptr_cst_p (e)) return nullptr_node; if (POINTER_TYPE_P (type) || TYPE_PTRMEM_P (type)) - return fold_if_not_in_template (cp_convert_to_pointer (type, e)); + return fold_if_not_in_template (cp_convert_to_pointer (type, e, complain)); if (code == VECTOR_TYPE) { tree in_vtype = TREE_TYPE (e); @@ -778,8 +798,10 @@ tree ret_val = build_type_conversion (type, e); if (ret_val) return ret_val; - if (flags & LOOKUP_COMPLAIN) - error_at (loc, "%q#T used where a %qT was expected", in_vtype, type); + if ((complain & tf_error) + && (flags & LOOKUP_COMPLAIN)) + error_at (loc, "%q#T used where a %qT was expected", + in_vtype, type); return error_mark_node; } return fold_if_not_in_template (convert_to_vector (type, e)); @@ -793,8 +815,10 @@ tree if (rval) return rval; else - if (flags & LOOKUP_COMPLAIN) - error_at (loc, "%q#T used where a floating point value was expected", + if ((complain & tf_error) + && (flags & LOOKUP_COMPLAIN)) + error_at (loc, + "%q#T used where a floating point value was expected", TREE_TYPE (e)); } if (code == REAL_TYPE) @@ -826,35 +850,33 @@ tree return error_mark_node; if (BRACE_ENCLOSED_INITIALIZER_P (ctor)) - ctor = perform_implicit_conversion (type, ctor, tf_warning_or_error); + ctor = perform_implicit_conversion (type, ctor, complain); else if ((flags & LOOKUP_ONLYCONVERTING) && ! (CLASS_TYPE_P (dtype) && DERIVED_FROM_P (type, dtype))) /* 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, - tf_warning_or_error); + ctor = build_user_type_conversion (type, ctor, flags, complain); else { VEC(tree,gc) *ctor_vec = make_tree_vector_single (ctor); ctor = build_special_member_call (NULL_TREE, complete_ctor_identifier, &ctor_vec, - type, flags, - tf_warning_or_error); + type, flags, complain); release_tree_vector (ctor_vec); } if (ctor) - return build_cplus_new (type, ctor, tf_warning_or_error); + return build_cplus_new (type, ctor, complain); } if (flags & LOOKUP_COMPLAIN) { /* If the conversion failed and expr was an invalid use of pointer to member function, try to report a meaningful error. */ - if (invalid_nonstatic_memfn_p (expr, tf_warning_or_error)) + if (invalid_nonstatic_memfn_p (expr, complain)) /* We displayed the error message. */; - else + else if (complain & tf_error) error_at (loc, "conversion from %qT to non-scalar type %qT requested", TREE_TYPE (expr), type); } @@ -1416,7 +1438,8 @@ convert (tree type, tree expr) return fold_if_not_in_template (build_nop (type, expr)); return ocp_convert (type, expr, CONV_OLD_CONVERT, - LOOKUP_NORMAL|LOOKUP_NO_CONVERSION); + LOOKUP_NORMAL|LOOKUP_NO_CONVERSION, + tf_warning_or_error); } /* Like cp_convert, except permit conversions to take place which @@ -1424,7 +1447,7 @@ convert (tree type, tree expr) (such as conversion from sub-type to private super-type). */ tree -convert_force (tree type, tree expr, int convtype) +convert_force (tree type, tree expr, int convtype, tsubst_flags_t complain) { tree e = expr; enum tree_code code = TREE_CODE (type); @@ -1432,10 +1455,11 @@ tree if (code == REFERENCE_TYPE) return (fold_if_not_in_template (convert_to_reference (type, e, CONV_C_CAST, LOOKUP_COMPLAIN, - NULL_TREE))); + NULL_TREE, complain))); if (code == POINTER_TYPE) - return fold_if_not_in_template (convert_to_pointer_force (type, e)); + return fold_if_not_in_template (convert_to_pointer_force (type, e, + complain)); /* From typeck.c convert_for_assignment */ if (((TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE && TREE_CODE (e) == ADDR_EXPR @@ -1446,9 +1470,9 @@ tree && TYPE_PTRMEMFUNC_P (type)) /* compatible pointer to member functions. */ return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1, - /*c_cast_p=*/1, tf_warning_or_error); + /*c_cast_p=*/1, complain); - return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL); + return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL, complain); } /* Convert an aggregate EXPR to type XTYPE. If a conversion Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 188167) +++ cp/cp-tree.h (working copy) @@ -5001,16 +5001,19 @@ extern void adjust_clone_args (tree); extern void deduce_noexcept_on_destructor (tree); /* in cvt.c */ -extern tree convert_to_reference (tree, tree, int, int, tree); +extern tree convert_to_reference (tree, tree, int, int, tree, + tsubst_flags_t); extern tree convert_from_reference (tree); extern tree force_rvalue (tree, tsubst_flags_t); -extern tree ocp_convert (tree, tree, int, int); -extern tree cp_convert (tree, tree); -extern tree cp_convert_and_check (tree, tree); +extern tree ocp_convert (tree, tree, int, int, + tsubst_flags_t); +extern tree cp_convert (tree, tree, tsubst_flags_t); +extern tree cp_convert_and_check (tree, tree, tsubst_flags_t); extern tree cp_fold_convert (tree, tree); extern tree convert_to_void (tree, impl_conv_void, tsubst_flags_t); -extern tree convert_force (tree, tree, int); +extern tree convert_force (tree, tree, int, + tsubst_flags_t); extern tree build_expr_type_conversion (int, tree, bool); extern tree type_promotes_to (tree); extern tree perform_qualification_conversions (tree, tree); @@ -5899,6 +5902,7 @@ extern void check_template_keyword (tree); extern bool check_raw_literal_operator (const_tree decl); extern bool check_literal_operator_args (const_tree, bool *, bool *); extern void maybe_warn_about_useless_cast (tree, tree, tsubst_flags_t); +extern tree cp_perform_integral_promotions (tree, tsubst_flags_t); /* in typeck2.c */ extern void require_complete_eh_spec_types (tree, tree);