Ping. On Fri, Aug 01, 2014 at 01:59:42PM +0200, Marek Polacek wrote: > This is the first patch in a series that strives to improve C++ location info. > > The following is more like a base for another improvements, thus it contains > only one small test. It adds a location_t parameter and a vector of > location_t > of arguments to finish_call_expr - so functions such as build_over_call and > build_new_method_call can have this info as well. Next patch will pass these > locations down to build_cxx_call/build_call_a/... functions - I hope we'll > then > get rid of that pesky issue that the caret points to final ) of the function, > which is a pain in gdb if the function declarator spans multiple lines. > > I'd prefer to do smaller (<1000 lines) incremental patches, where every patch > improves something concrete, rather than one huge megapatch. > Maybe you'll want to preapprove similar patches (add location_t to get better > diagnostics) in due course - up to you. > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > 2014-08-01 Marek Polacek <pola...@redhat.com> > > * call.c (convert_like, convert_like_with_context): Add location_t > parameter. > (build_user_type_conversion): Adjust convert_like call. > (build_integral_nontype_arg_conv): Likewise. > (build_new_function_call): Add location_t and vec<location_t> > parameters. Use them. > (build_operator_new_call): Adjust build_over_call call. > (build_op_call_1): Adjust build_over_call and > convert_like_with_context calls. > (build_new_op_1): Likewise. > (build_conditional_expr_1): Adjust convert_like call. > (convert_like_real): Add location_t parameter. Use it. > (build_over_call): Add location_t and vec<location_t> parameters. > Use them. > (build_special_member_call): Adjust build_new_method_call call. > (build_new_method_call_1): Add location_t and vec<location_t> > parameters. Use them. > (build_new_method_call): Likewise. > (perform_implicit_conversion_flags): Adjust convert_like call. > (perform_direct_initialization_if_possible): Adjust convert_like_real > call. > (initialize_reference): Adjust convert_like calls. > * cp-array-notation.c (expand_sec_reduce_builtin): Adjust > finish_call_expr call. > * cp-tree.h: Adjust declarations. > * init.c (build_new_1): Adjust build_new_method_call call. > (build_dtor_call): Likewise. > * method.c (locate_fn_flags): Likewise. > * parser.c (cp_parser_userdef_char_literal): Adjust finish_call_expr > call. > (cp_parser_userdef_numeric_literal): Likewise. > (cp_parser_userdef_string_literal): Likewise. > (cp_parser_postfix_expression): New vector of locations. Adjust > cp_parser_parenthesized_expression_list call. Make it fill the > vector of locations of arguments. Adjust build_new_method_call > and finish_call_expr calls. Release the vector of locations. > (cp_parser_parenthesized_expression_list): Fill the vector of > locations of arguments. > (cp_parser_new_placement): Adjust > cp_parser_parenthesized_expression_list call. > (cp_parser_new_initializer): Likewise. > (cp_parser_mem_initializer): Likewise. > (cp_parser_initializer): Likewise. > (cp_parser_gnu_attribute_list): Likewise. > (cp_parser_std_attribute): Likewise. > (cp_parser_functional_cast): Likewise. > (cp_parser_omp_declare_reduction_exprs): Likewise. > (cp_parser_perform_range_for_lookup): Adjust finish_call_expr calls. > (cp_parser_range_for_member_function): Likewise. > * pt.c (tsubst_copy_and_build): Adjust build_new_method_call and > finish_call_expr calls. > * semantics.c (finish_call_expr): Add location_t and vec<location_t> > parameters. Use them. > (finish_omp_barrier): Update finish_call_expr call. > (finish_omp_flush): Likewise. > (finish_omp_taskwait): Likewise. > (finish_omp_taskyield): Likewise. > (finish_omp_cancel): Likewise. > (finish_omp_cancellation_point): Likewise. > > * g++.dg/diagnostic/location-1.C: New test. > > diff --git gcc/cp/call.c gcc/cp/call.c > index 4d37c65..b9db4b9 100644 > --- gcc/cp/call.c > +++ gcc/cp/call.c > @@ -148,18 +148,19 @@ static int equal_functions (tree, tree); > 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_over_call (location_t, vec<location_t>, > + struct z_candidate *, int, tsubst_flags_t); > static tree build_java_interface_fn_ref (tree, tree); > -#define convert_like(CONV, EXPR, COMPLAIN) \ > - convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0, \ > - /*issue_conversion_warnings=*/true, \ > - /*c_cast_p=*/false, (COMPLAIN)) > -#define convert_like_with_context(CONV, EXPR, FN, ARGNO, COMPLAIN ) \ > - convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0, > \ > +#define convert_like(LOC, CONV, EXPR, COMPLAIN) > \ > + convert_like_real ((LOC), (CONV), (EXPR), NULL_TREE, 0, 0, \ > /*issue_conversion_warnings=*/true, \ > /*c_cast_p=*/false, (COMPLAIN)) > -static tree convert_like_real (conversion *, tree, tree, int, int, bool, > - bool, tsubst_flags_t); > +#define convert_like_with_context(LOC, CONV, EXPR, FN, ARGNO, COMPLAIN ) > \ > + convert_like_real ((LOC), (CONV), (EXPR), (FN), (ARGNO), 0, > \ > + /*issue_conversion_warnings=*/true, \ > + /*c_cast_p=*/false, (COMPLAIN)) > +static tree convert_like_real (location_t, conversion *, tree, tree, int, > int, > + bool, bool, tsubst_flags_t); > static void op_error (location_t, enum tree_code, enum tree_code, tree, > tree, tree, bool); > static struct z_candidate *build_user_type_conversion_1 (tree, tree, int, > @@ -3813,7 +3814,8 @@ build_user_type_conversion (tree totype, tree expr, int > flags, > ret = error_mark_node; > else > { > - expr = convert_like (cand->second_conv, expr, complain); > + expr = convert_like (input_location, cand->second_conv, expr, > + complain); > ret = convert_from_reference (expr); > } > } > @@ -3885,7 +3887,7 @@ build_integral_nontype_arg_conv (tree type, tree expr, > tsubst_flags_t complain) > } > > if (conv) > - expr = convert_like (conv, expr, complain); > + expr = convert_like (loc, conv, expr, complain); > else > expr = error_mark_node; > > @@ -4007,7 +4009,8 @@ print_error_for_call_failure (tree fn, vec<tree, va_gc> > *args, > ARGS. */ > > tree > -build_new_function_call (tree fn, vec<tree, va_gc> **args, bool koenig_p, > +build_new_function_call (location_t loc, tree fn, vec<location_t> arg_loc, > + vec<tree, va_gc> **args, bool koenig_p, > tsubst_flags_t complain) > { > struct z_candidate *candidates, *cand; > @@ -4069,7 +4072,7 @@ build_new_function_call (tree fn, vec<tree, va_gc> > **args, bool koenig_p, > about peculiar null pointer conversion. */ > if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) > flags |= LOOKUP_EXPLICIT_TMPL_ARGS; > - result = build_over_call (cand, flags, complain); > + result = build_over_call (loc, arg_loc, cand, flags, complain); > } > > /* Free all the conversions we allocated. */ > @@ -4180,7 +4183,8 @@ build_operator_new_call (tree fnname, vec<tree, va_gc> > **args, > *fn = cand->fn; > > /* Build the CALL_EXPR. */ > - return build_over_call (cand, LOOKUP_NORMAL, complain); > + return build_over_call (input_location, vNULL, cand, LOOKUP_NORMAL, > + complain); > } > > /* Build a new call to operator(). This may change ARGS. */ > @@ -4300,11 +4304,12 @@ build_op_call_1 (tree obj, vec<tree, va_gc> **args, > tsubst_flags_t complain) > DECL_NAME here. */ > else if (TREE_CODE (cand->fn) == FUNCTION_DECL > && DECL_OVERLOADED_OPERATOR_P (cand->fn) == CALL_EXPR) > - result = build_over_call (cand, LOOKUP_NORMAL, complain); > + result = build_over_call (input_location, vNULL, cand, LOOKUP_NORMAL, > + complain); > else > { > - obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1, > - complain); > + obj = convert_like_with_context (input_location, cand->convs[0], > + obj, cand->fn, -1, complain); > obj = convert_from_reference (obj); > result = cp_build_function_call_vec (obj, args, complain); > } > @@ -4806,15 +4811,15 @@ build_conditional_expr_1 (location_t loc, tree arg1, > tree arg2, tree arg3, > if (conv2 && !conv2->bad_p && conv3 && !conv3->bad_p) > inform (loc, " and each type can be converted to the other"); > else if (conv2 && conv2->kind == ck_ambig) > - convert_like (conv2, arg2, complain); > + convert_like (loc, conv2, arg2, complain); > else > - convert_like (conv3, arg3, complain); > + convert_like (loc, conv3, arg3, complain); > } > result = error_mark_node; > } > else if (conv2 && !conv2->bad_p) > { > - arg2 = convert_like (conv2, arg2, complain); > + arg2 = convert_like (loc, conv2, arg2, complain); > arg2 = convert_from_reference (arg2); > arg2_type = TREE_TYPE (arg2); > /* Even if CONV2 is a valid conversion, the result of the > @@ -4828,7 +4833,7 @@ build_conditional_expr_1 (location_t loc, tree arg1, > tree arg2, tree arg3, > } > else if (conv3 && !conv3->bad_p) > { > - arg3 = convert_like (conv3, arg3, complain); > + arg3 = convert_like (loc, conv3, arg3, complain); > arg3 = convert_from_reference (arg3); > arg3_type = TREE_TYPE (arg3); > if (error_operand_p (arg3)) > @@ -4938,12 +4943,12 @@ build_conditional_expr_1 (location_t loc, tree arg1, > tree arg2, tree arg3, > the converted operands are used in place of the original > operands for the remainder of this section. */ > conv = cand->convs[0]; > - arg1 = convert_like (conv, arg1, complain); > + arg1 = convert_like (loc, conv, arg1, complain); > conv = cand->convs[1]; > - arg2 = convert_like (conv, arg2, complain); > + arg2 = convert_like (loc, conv, arg2, complain); > arg2_type = TREE_TYPE (arg2); > conv = cand->convs[2]; > - arg3 = convert_like (conv, arg3, complain); > + arg3 = convert_like (loc, conv, arg3, complain); > arg3_type = TREE_TYPE (arg3); > } > > @@ -5527,7 +5532,8 @@ build_new_op_1 (location_t loc, enum tree_code code, > int flags, tree arg1, > if (resolve_args (arglist, complain) == NULL) > result = error_mark_node; > else > - result = build_over_call (cand, LOOKUP_NORMAL, complain); > + result = build_over_call (loc, vNULL, cand, LOOKUP_NORMAL, > + complain); > } > else > { > @@ -5570,7 +5576,7 @@ build_new_op_1 (location_t loc, enum tree_code code, > int flags, tree arg1, > conv = cand->convs[0]; > if (conv->kind == ck_ref_bind) > conv = next_conversion (conv); > - arg1 = convert_like (conv, arg1, complain); > + arg1 = convert_like (loc, conv, arg1, complain); > > if (arg2) > { > @@ -5588,14 +5594,14 @@ build_new_op_1 (location_t loc, enum tree_code code, > int flags, tree arg1, > code_orig_arg1, arg1, > code_orig_arg2, arg2); > > - arg2 = convert_like (conv, arg2, complain); > + arg2 = convert_like (loc, conv, arg2, complain); > } > if (arg3) > { > conv = cand->convs[2]; > if (conv->kind == ck_ref_bind) > conv = next_conversion (conv); > - arg3 = convert_like (conv, arg3, complain); > + arg3 = convert_like (loc, conv, arg3, complain); > } > > } > @@ -6034,14 +6040,13 @@ maybe_print_user_conv_context (conversion *convs) > conversions to inaccessible bases are permitted. */ > > static tree > -convert_like_real (conversion *convs, tree expr, tree fn, int argnum, > - int inner, bool issue_conversion_warnings, > +convert_like_real (location_t loc, conversion *convs, tree expr, tree fn, > + int argnum, int inner, bool issue_conversion_warnings, > bool c_cast_p, tsubst_flags_t complain) > { > tree totype = convs->type; > diagnostic_t diag_kind; > int flags; > - location_t loc = EXPR_LOC_OR_LOC (expr, input_location); > > if (convs->bad_p && !(complain & tf_error)) > return error_mark_node; > @@ -6089,7 +6094,7 @@ convert_like_real (conversion *convs, tree expr, tree > fn, int argnum, > totype); > if (complained) > print_z_candidate (loc, "candidate is:", t->cand); > - expr = convert_like_real (t, expr, fn, argnum, 1, > + expr = convert_like_real (loc, t, expr, fn, argnum, 1, > /*issue_conversion_warnings=*/false, > /*c_cast_p=*/false, > complain); > @@ -6106,14 +6111,14 @@ convert_like_real (conversion *convs, tree expr, tree > fn, int argnum, > } > else if (t->kind == ck_user || !t->bad_p) > { > - expr = convert_like_real (t, expr, fn, argnum, 1, > + expr = convert_like_real (loc, t, expr, fn, argnum, 1, > /*issue_conversion_warnings=*/false, > /*c_cast_p=*/false, > complain); > break; > } > else if (t->kind == ck_ambig) > - return convert_like_real (t, expr, fn, argnum, 1, > + return convert_like_real (loc, t, expr, fn, argnum, 1, > /*issue_conversion_warnings=*/false, > /*c_cast_p=*/false, > complain); > @@ -6176,7 +6181,7 @@ convert_like_real (conversion *convs, tree expr, tree > fn, int argnum, > for (i = 0; i < cand->num_convs; ++i) > cand->convs[i]->user_conv_p = true; > > - expr = build_over_call (cand, LOOKUP_NORMAL, complain); > + expr = build_over_call (loc, vNULL, cand, LOOKUP_NORMAL, complain); > > /* If this is a constructor or a function returning an aggr type, > we need to build up a TARGET_EXPR. */ > @@ -6247,8 +6252,8 @@ convert_like_real (conversion *convs, tree expr, tree > fn, int argnum, > /* Convert all the elements. */ > FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val) > { > - tree sub = convert_like_real (convs->u.list[ix], val, fn, argnum, > - 1, false, false, complain); > + tree sub = convert_like_real (loc, convs->u.list[ix], val, fn, > + argnum, 1, false, false, complain); > if (sub == error_mark_node) > return sub; > if (!BRACE_ENCLOSED_INITIALIZER_P (val)) > @@ -6302,9 +6307,10 @@ convert_like_real (conversion *convs, tree expr, tree > fn, int argnum, > break; > }; > > - expr = convert_like_real (next_conversion (convs), expr, fn, argnum, > + expr = convert_like_real (loc, next_conversion (convs), expr, fn, argnum, > convs->kind == ck_ref_bind ? -1 : 1, > - convs->kind == ck_ref_bind ? > issue_conversion_warnings : false, > + convs->kind == ck_ref_bind > + ? issue_conversion_warnings : false, > c_cast_p, > complain); > if (expr == error_mark_node) > @@ -6870,11 +6876,12 @@ mark_versions_used (tree fn) > > /* Subroutine of the various build_*_call functions. Overload resolution > has chosen a winning candidate CAND; build up a CALL_EXPR accordingly. > - ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a > - bitmask of various LOOKUP_* flags which apply to the call itself. */ > + FLAGS is a bitmask of various LOOKUP_* flags which apply to the call > + itself. */ > > static tree > -build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t > complain) > +build_over_call (location_t loc, vec<location_t> arg_loc, > + struct z_candidate *cand, int flags, tsubst_flags_t complain) > { > tree fn = cand->fn; > const vec<tree, va_gc> *args = cand->args; > @@ -6924,7 +6931,7 @@ build_over_call (struct z_candidate *cand, int flags, > tsubst_flags_t complain) > addr = build_addr_func (fn, complain); > if (addr == error_mark_node) > return error_mark_node; > - expr = build_call_array_loc (input_location, return_type, > + expr = build_call_array_loc (loc, return_type, > addr, nargs, argarray); > if (TREE_THIS_VOLATILE (fn) && cfun) > current_function_returns_abnormally = 1; > @@ -7052,7 +7059,7 @@ build_over_call (struct z_candidate *cand, int flags, > tsubst_flags_t complain) > { > if (complain & tf_error) > { > - if (permerror (input_location, "passing %qT as %<this%> " > + if (permerror (loc, "passing %qT as %<this%> " > "argument discards qualifiers", > TREE_TYPE (argtype))) > inform (DECL_SOURCE_LOCATION (fn), " in call to %qD", fn); > @@ -7085,9 +7092,9 @@ build_over_call (struct z_candidate *cand, int flags, > tsubst_flags_t complain) > BINFO_TYPE (cand->conversion_path), true)) > { > if (complain & tf_error) > - error ("%qT is not an accessible base of %qT", > - BINFO_TYPE (cand->conversion_path), > - TREE_TYPE (argtype)); > + error_at (loc, "%qT is not an accessible base of %qT", > + BINFO_TYPE (cand->conversion_path), > + TREE_TYPE (argtype)); > else > return error_mark_node; > } > @@ -7117,6 +7124,12 @@ build_over_call (struct z_candidate *cand, int flags, > tsubst_flags_t complain) > tree type = TREE_VALUE (parm); > tree arg = (*args)[arg_index]; > bool conversion_warning = true; > + /* Some __atomic_* builtins have additional hidden argument at > + position 0. */ > + location_t ploc > + = !arg_loc.is_empty () && args->length () == arg_loc.length () > + ? expansion_point_location_if_in_system_header (arg_loc[arg_index]) > + : input_location; > > conv = convs[i]; > > @@ -7167,15 +7180,16 @@ build_over_call (struct z_candidate *cand, int flags, > tsubst_flags_t complain) > || (TREE_VEC_LENGTH (cand->explicit_targs) > <= TEMPLATE_TYPE_IDX (pattype)))) > { > - pedwarn (input_location, 0, "deducing %qT as %qT", > + pedwarn (loc, 0, "deducing %qT as %qT", > non_reference (TREE_TYPE (patparm)), > non_reference (type)); > - pedwarn (input_location, 0, " in call to %q+D", cand->fn); > - pedwarn (input_location, 0, > + pedwarn (loc, 0, " in call to %q+D", cand->fn); > + pedwarn (loc, 0, > " (you can disable this with -fno-deduce-init-list)"); > } > } > - val = convert_like_with_context (conv, arg, fn, i - is_method, > + val = convert_like_with_context (ploc, conv, arg, fn, > + i - is_method, > conversion_warning > ? complain > : complain & (~tf_warning)); > @@ -7678,7 +7692,7 @@ build_special_member_call (tree instance, tree name, > vec<tree, va_gc> **args, > vec_safe_insert (*args, 0, sub_vtt); > } > > - ret = build_new_method_call (instance, fns, args, > + ret = build_new_method_call (input_location, instance, fns, vNULL, args, > TYPE_BINFO (BINFO_TYPE (binfo)), > flags, /*fn=*/NULL, > complain); > @@ -7747,7 +7761,8 @@ name_as_c_string (tree name, tree type, bool *free_p) > This may change ARGS. */ > > static tree > -build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args, > +build_new_method_call_1 (location_t loc, tree instance, tree fns, > + vec<location_t> arg_loc, vec<tree, va_gc> **args, > tree conversion_path, int flags, > tree *fn_p, tsubst_flags_t complain) > { > @@ -8067,7 +8082,8 @@ build_new_method_call_1 (tree instance, tree fns, > vec<tree, va_gc> **args, > if (fn_p) > *fn_p = fn; > /* Build the actual CALL_EXPR. */ > - call = build_over_call (cand, flags, complain); > + call = build_over_call (loc, arg_loc, cand, flags, > + complain); > /* In an expression of the form `a->f()' where `f' turns > out to be a static member function, `a' is > none-the-less evaluated. */ > @@ -8130,13 +8146,15 @@ build_new_method_call_1 (tree instance, tree fns, > vec<tree, va_gc> **args, > /* Wrapper for above. */ > > tree > -build_new_method_call (tree instance, tree fns, vec<tree, va_gc> **args, > +build_new_method_call (location_t loc, tree instance, tree fns, > + vec<location_t> arg_loc, vec<tree, va_gc> **args, > tree conversion_path, int flags, > tree *fn_p, tsubst_flags_t complain) > { > tree ret; > bool subtime = timevar_cond_start (TV_OVERLOAD); > - ret = build_new_method_call_1 (instance, fns, args, conversion_path, flags, > + ret = build_new_method_call_1 (loc, instance, fns, arg_loc, args, > + conversion_path, flags, > fn_p, complain); > timevar_cond_stop (TV_OVERLOAD, subtime); > return ret; > @@ -9284,7 +9302,7 @@ perform_implicit_conversion_flags (tree type, tree expr, > IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true; > } > else > - expr = convert_like (conv, expr, complain); > + expr = convert_like (loc, conv, expr, complain); > > /* Free all the conversions we allocated. */ > obstack_free (&conversion_obstack, p); > @@ -9344,7 +9362,7 @@ perform_direct_initialization_if_possible (tree type, > if (!conv || conv->bad_p) > expr = NULL_TREE; > else > - expr = convert_like_real (conv, expr, NULL_TREE, 0, 0, > + expr = convert_like_real (input_location, conv, expr, NULL_TREE, 0, 0, > /*issue_conversion_warnings=*/false, > c_cast_p, > complain); > @@ -9575,7 +9593,7 @@ initialize_reference (tree type, tree expr, > if (complain & tf_error) > { > if (conv) > - convert_like (conv, expr, complain); > + convert_like (loc, conv, expr, complain); > else if (!CP_TYPE_CONST_P (TREE_TYPE (type)) > && !TYPE_REF_IS_RVALUE (type) > && !real_lvalue_p (expr)) > @@ -9592,7 +9610,7 @@ initialize_reference (tree type, tree expr, > > if (conv->kind == ck_ref_bind) > /* Perform the conversion. */ > - expr = convert_like (conv, expr, complain); > + expr = convert_like (loc, conv, expr, complain); > else if (conv->kind == ck_ambig) > /* We gave an error in build_user_type_conversion_1. */ > expr = error_mark_node; > diff --git gcc/cp/cp-array-notation.c gcc/cp/cp-array-notation.c > index b45449b..44a3fbe 100644 > --- gcc/cp/cp-array-notation.c > +++ gcc/cp/cp-array-notation.c > @@ -475,8 +475,8 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree > *new_var) > vec_safe_push (func_args, identity_value); > vec_safe_push (func_args, func_parm); > > - new_expr = finish_call_expr (call_fn, &func_args, false, true, > - tf_warning_or_error); > + new_expr = finish_call_expr (location, call_fn, vNULL, &func_args, > + false, true, tf_warning_or_error); > if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE) > new_expr = build_x_modify_expr (location, *new_var, NOP_EXPR, new_expr, > tf_warning_or_error); > diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h > index 0c0d804..a12f18e 100644 > --- gcc/cp/cp-tree.h > +++ gcc/cp/cp-tree.h > @@ -5068,12 +5068,16 @@ extern bool sufficient_parms_p > (const_tree); > extern tree type_decays_to (tree); > extern tree build_user_type_conversion (tree, tree, int, > tsubst_flags_t); > -extern tree build_new_function_call (tree, vec<tree, va_gc> **, > bool, > +extern tree build_new_function_call (location_t, tree, > + vec<location_t>, > + vec<tree, va_gc> **, bool, > tsubst_flags_t); > extern tree build_operator_new_call (tree, vec<tree, va_gc> **, > tree *, > tree *, tree, tree *, > tsubst_flags_t); > -extern tree build_new_method_call (tree, tree, vec<tree, va_gc> > **, > +extern tree build_new_method_call (location_t, tree, tree, > + vec<location_t>, > + vec<tree, va_gc> **, > tree, int, tree *, > tsubst_flags_t); > extern tree build_special_member_call (tree, tree, vec<tree, > va_gc> **, > @@ -5832,7 +5836,9 @@ extern tree stmt_expr_value_expr (tree); > bool empty_expr_stmt_p (tree); > extern tree perform_koenig_lookup (tree, vec<tree, va_gc> *, > tsubst_flags_t); > -extern tree finish_call_expr (tree, vec<tree, va_gc> **, > bool, > +extern tree finish_call_expr (location_t, tree, > + vec<location_t>, > + vec<tree, va_gc> **, bool, > bool, tsubst_flags_t); > extern tree finish_increment_expr (tree, enum tree_code); > extern tree finish_this_expr (void); > diff --git gcc/cp/init.c gcc/cp/init.c > index f8cae28..4b702ea 100644 > --- gcc/cp/init.c > +++ gcc/cp/init.c > @@ -2594,8 +2594,9 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, > tree nelts, > } > return error_mark_node; > } > - alloc_call = build_new_method_call (build_dummy_object (elt_type), > - fns, placement, > + alloc_call = build_new_method_call (input_location, > + build_dummy_object (elt_type), > + fns, vNULL, placement, > /*conversion_path=*/NULL_TREE, > LOOKUP_NORMAL, > &alloc_fn, > @@ -3879,8 +3880,8 @@ build_dtor_call (tree exp, special_function_kind > dtor_kind, int flags, > gcc_unreachable (); > } > fn = lookup_fnfields (TREE_TYPE (exp), name, /*protect=*/2); > - return build_new_method_call (exp, fn, > - /*args=*/NULL, > + return build_new_method_call (input_location, exp, fn, > + vNULL, /*args=*/NULL, > /*conversion_path=*/NULL_TREE, > flags, > /*fn_p=*/NULL, > diff --git gcc/cp/method.c gcc/cp/method.c > index f86a214..151c6a8 100644 > --- gcc/cp/method.c > +++ gcc/cp/method.c > @@ -904,7 +904,8 @@ locate_fn_flags (tree type, tree name, tree argtype, int > flags, > } > > fns = lookup_fnfields (binfo, name, 0); > - rval = build_new_method_call (ob, fns, &args, binfo, flags, &fn, complain); > + rval = build_new_method_call (input_location, ob, fns, vNULL, &args, binfo, > + flags, &fn, complain); > > release_tree_vector (args); > if (fn && rval == error_mark_node) > diff --git gcc/cp/parser.c gcc/cp/parser.c > index 32c7a3f..768bab6 100644 > --- gcc/cp/parser.c > +++ gcc/cp/parser.c > @@ -1929,8 +1929,8 @@ static tree cp_parser_postfix_open_square_expression > static tree cp_parser_postfix_dot_deref_expression > (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t); > static vec<tree, va_gc> *cp_parser_parenthesized_expression_list > - (cp_parser *, int, bool, bool, bool *, bool = false); > -/* Values for the second parameter of > cp_parser_parenthesized_expression_list. */ > + (cp_parser *, vec<location_t> *, int, bool, bool, bool *, bool = false); > +/* Values for the third parameter of > cp_parser_parenthesized_expression_list. */ > enum { non_attr = 0, normal_attr = 1, id_attr = 2 }; > static void cp_parser_pseudo_destructor_name > (cp_parser *, tree, tree *, tree *); > @@ -3812,7 +3812,8 @@ cp_parser_userdef_char_literal (cp_parser *parser) > release_tree_vector (args); > return error_mark_node; > } > - result = finish_call_expr (decl, &args, false, true, tf_warning_or_error); > + result = finish_call_expr (token->location, decl, vNULL, &args, false, > true, > + tf_warning_or_error); > release_tree_vector (args); > if (result != error_mark_node) > return result; > @@ -3907,7 +3908,8 @@ cp_parser_userdef_numeric_literal (cp_parser *parser) > decl = lookup_literal_operator (name, args); > if (decl && decl != error_mark_node) > { > - result = finish_call_expr (decl, &args, false, true, tf_none); > + result = finish_call_expr (token->location, decl, vNULL, &args, false, > + true, tf_none); > if (result != error_mark_node) > { > if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE && overflow > 0) > @@ -3938,7 +3940,8 @@ cp_parser_userdef_numeric_literal (cp_parser *parser) > decl = lookup_literal_operator (name, args); > if (decl && decl != error_mark_node) > { > - result = finish_call_expr (decl, &args, false, true, tf_none); > + result = finish_call_expr (token->location, decl, vNULL, &args, false, > + true, tf_none); > if (result != error_mark_node) > { > release_tree_vector (args); > @@ -3956,7 +3959,8 @@ cp_parser_userdef_numeric_literal (cp_parser *parser) > { > tree tmpl_args = make_char_string_pack (num_string); > decl = lookup_template_function (decl, tmpl_args); > - result = finish_call_expr (decl, &args, false, true, tf_none); > + result = finish_call_expr (token->location, decl, vNULL, &args, false, > + true, tf_none); > if (result != error_mark_node) > { > release_tree_vector (args); > @@ -3996,7 +4000,8 @@ cp_parser_userdef_string_literal (tree literal) > { > tree tmpl_args = make_string_pack (value); > decl = lookup_template_function (decl, tmpl_args); > - result = finish_call_expr (decl, &args, false, true, tf_none); > + result = finish_call_expr (input_location, decl, vNULL, &args, false, > + true, tf_none); > if (result != error_mark_node) > { > release_tree_vector (args); > @@ -4017,7 +4022,8 @@ cp_parser_userdef_string_literal (tree literal) > release_tree_vector (args); > return error_mark_node; > } > - result = finish_call_expr (decl, &args, false, true, tf_none); > + result = finish_call_expr (input_location, decl, vNULL, &args, false, > + true, tf_none); > release_tree_vector (args); > if (result != error_mark_node) > return result; > @@ -5899,7 +5905,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool > address_p, bool cast_p, > tree p; > > cp_lexer_consume_token (parser->lexer); > - vec = cp_parser_parenthesized_expression_list (parser, non_attr, > + vec = cp_parser_parenthesized_expression_list (parser, NULL, non_attr, > /*cast_p=*/false, /*allow_expansion_p=*/true, > /*non_constant_p=*/NULL); > if (vec == NULL) > @@ -6064,6 +6070,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool > address_p, bool cast_p, > bool saved_non_integral_constant_expression_p = false; > tsubst_flags_t complain = complain_flags (decltype_p); > vec<tree, va_gc> *args; > + location_t fn_loc = token->location; > + vec<location_t> arg_loc = vNULL; > > is_member_access = false; > > @@ -6080,7 +6088,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool > address_p, bool cast_p, > parser->integral_constant_expression_p = false; > } > args = (cp_parser_parenthesized_expression_list > - (parser, non_attr, > + (parser, &arg_loc, non_attr, > /*cast_p=*/false, /*allow_expansion_p=*/true, > /*non_constant_p=*/NULL, > /*want_literal_zero_p=*/warn_memset_transposed_args)); > @@ -6197,7 +6205,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool > address_p, bool cast_p, > { > postfix_expression > = (build_new_method_call > - (instance, fn, &args, NULL_TREE, > + (fn_loc, instance, fn, arg_loc, &args, NULL_TREE, > (idk == CP_ID_KIND_QUALIFIED > ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL > : LOOKUP_NORMAL), > @@ -6206,7 +6214,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool > address_p, bool cast_p, > } > else > postfix_expression > - = finish_call_expr (postfix_expression, &args, > + = finish_call_expr (fn_loc, postfix_expression, > + arg_loc, &args, > /*disallow_virtual=*/false, > /*koenig_p=*/false, > complain); > @@ -6221,14 +6230,16 @@ cp_parser_postfix_expression (cp_parser *parser, bool > address_p, bool cast_p, > /* A call to a static class member, or a namespace-scope > function. */ > postfix_expression > - = finish_call_expr (postfix_expression, &args, > + = finish_call_expr (fn_loc, postfix_expression, > + arg_loc, &args, > /*disallow_virtual=*/true, > koenig_p, > complain); > else > /* All other function calls. */ > postfix_expression > - = finish_call_expr (postfix_expression, &args, > + = finish_call_expr (fn_loc, postfix_expression, > + arg_loc, &args, > /*disallow_virtual=*/false, > koenig_p, > complain); > @@ -6237,6 +6248,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool > address_p, bool cast_p, > idk = CP_ID_KIND_NONE; > > release_tree_vector (args); > + arg_loc.release (); > } > break; > > @@ -6698,6 +6710,7 @@ static GTY(()) tree literal_zeros[itk_none]; > > static vec<tree, va_gc> * > cp_parser_parenthesized_expression_list (cp_parser* parser, > + vec<location_t> *arg_loc, > int is_attribute_list, > bool cast_p, > bool allow_expansion_p, > @@ -6730,6 +6743,10 @@ cp_parser_parenthesized_expression_list (cp_parser* > parser, > { > tree expr; > > + /* Remember the location of the token. */ > + if (arg_loc) > + arg_loc->safe_push (cp_lexer_peek_token (parser->lexer)->location); > + > /* At the beginning of attribute lists, check to see if the > next token is an identifier. */ > if (is_attribute_list == id_attr > @@ -7445,7 +7462,7 @@ cp_parser_new_placement (cp_parser* parser) > > /* Parse the expression-list. */ > expression_list = (cp_parser_parenthesized_expression_list > - (parser, non_attr, /*cast_p=*/false, > + (parser, NULL, non_attr, /*cast_p=*/false, > /*allow_expansion_p=*/true, > /*non_constant_p=*/NULL)); > > @@ -7650,7 +7667,7 @@ cp_parser_new_initializer (cp_parser* parser) > } > else > expression_list = (cp_parser_parenthesized_expression_list > - (parser, non_attr, /*cast_p=*/false, > + (parser, NULL, non_attr, /*cast_p=*/false, > /*allow_expansion_p=*/true, > /*non_constant_p=*/NULL)); > > @@ -10557,12 +10574,12 @@ cp_parser_perform_range_for_lookup (tree range, > tree *begin, tree *end) > > member_begin = perform_koenig_lookup (id_begin, vec, > tf_warning_or_error); > - *begin = finish_call_expr (member_begin, &vec, false, true, > - tf_warning_or_error); > + *begin = finish_call_expr (input_location, member_begin, vNULL, &vec, > + false, true, tf_warning_or_error); > member_end = perform_koenig_lookup (id_end, vec, > tf_warning_or_error); > - *end = finish_call_expr (member_end, &vec, false, true, > - tf_warning_or_error); > + *end = finish_call_expr (input_location, member_end, vNULL, &vec, > + false, true, tf_warning_or_error); > > release_tree_vector (vec); > } > @@ -10608,7 +10625,7 @@ cp_parser_range_for_member_function (tree range, tree > identifier) > return error_mark_node; > > vec = make_tree_vector (); > - res = finish_call_expr (member, &vec, > + res = finish_call_expr (input_location, member, vNULL, &vec, > /*disallow_virtual=*/false, > /*koenig_p=*/false, > tf_warning_or_error); > @@ -12578,7 +12595,7 @@ cp_parser_mem_initializer (cp_parser* parser) > else > { > vec<tree, va_gc> *vec; > - vec = cp_parser_parenthesized_expression_list (parser, non_attr, > + vec = cp_parser_parenthesized_expression_list (parser, NULL, non_attr, > /*cast_p=*/false, > /*allow_expansion_p=*/true, > /*non_constant_p=*/NULL); > @@ -19044,7 +19061,7 @@ cp_parser_initializer (cp_parser* parser, bool* > is_direct_init, > else if (token->type == CPP_OPEN_PAREN) > { > vec<tree, va_gc> *vec; > - vec = cp_parser_parenthesized_expression_list (parser, non_attr, > + vec = cp_parser_parenthesized_expression_list (parser, NULL, non_attr, > /*cast_p=*/false, > /*allow_expansion_p=*/true, > non_constant_p); > @@ -21977,7 +21994,7 @@ cp_parser_gnu_attribute_list (cp_parser* parser) > } > else > vec = cp_parser_parenthesized_expression_list > - (parser, attr_flag, /*cast_p=*/false, > + (parser, NULL, attr_flag, /*cast_p=*/false, > /*allow_expansion_p=*/false, > /*non_constant_p=*/NULL); > if (vec == NULL) > @@ -22132,7 +22149,7 @@ cp_parser_std_attribute (cp_parser *parser) > attr_flag = id_attr; > > vec = cp_parser_parenthesized_expression_list > - (parser, attr_flag, /*cast_p=*/false, > + (parser, NULL, attr_flag, /*cast_p=*/false, > /*allow_expansion_p=*/true, > /*non_constant_p=*/NULL); > if (vec == NULL) > @@ -23560,7 +23577,7 @@ cp_parser_functional_cast (cp_parser* parser, tree > type) > } > > > - vec = cp_parser_parenthesized_expression_list (parser, non_attr, > + vec = cp_parser_parenthesized_expression_list (parser, NULL, non_attr, > /*cast_p=*/true, > /*allow_expansion_p=*/true, > /*non_constant_p=*/NULL); > @@ -30975,7 +30992,7 @@ cp_parser_omp_declare_reduction_exprs (tree fndecl, > cp_parser *parser) > || cp_parser_error_occurred (parser) > || !cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN) > || ((args = cp_parser_parenthesized_expression_list > - (parser, non_attr, /*cast_p=*/false, > + (parser, NULL, non_attr, /*cast_p=*/false, > /*allow_expansion_p=*/true, > /*non_constant_p=*/NULL)), > cp_parser_error_occurred (parser))) > diff --git gcc/cp/pt.c gcc/cp/pt.c > index baabcb1..54e6606 100644 > --- gcc/cp/pt.c > +++ gcc/cp/pt.c > @@ -14966,20 +14966,20 @@ tsubst_copy_and_build (tree t, > || any_type_dependent_arguments_p (call_args))) > ret = build_nt_call_vec (function, call_args); > else if (!BASELINK_P (fn)) > - ret = finish_call_expr (function, &call_args, > + ret = finish_call_expr (loc, function, vNULL, &call_args, > /*disallow_virtual=*/false, > /*koenig_p=*/false, > complain); > else > ret = (build_new_method_call > - (instance, fn, > + (loc, instance, fn, vNULL, > &call_args, NULL_TREE, > qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL, > /*fn_p=*/NULL, > complain)); > } > else > - ret = finish_call_expr (function, &call_args, > + ret = finish_call_expr (loc, function, vNULL, &call_args, > /*disallow_virtual=*/qualified_p, > koenig_p, > complain); > diff --git gcc/cp/semantics.c gcc/cp/semantics.c > index c87764d..5f4d2da 100644 > --- gcc/cp/semantics.c > +++ gcc/cp/semantics.c > @@ -2194,7 +2194,8 @@ perform_koenig_lookup (tree fn, vec<tree, va_gc> *args, > Returns code for the call. */ > > tree > -finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual, > +finish_call_expr (location_t loc, tree fn, vec<location_t> arg_loc, > + vec<tree, va_gc> **args, bool disallow_virtual, > bool koenig_p, tsubst_flags_t complain) > { > tree result; > @@ -2259,7 +2260,8 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, > bool disallow_virtual, > if (BASELINK_P (member)) > { > tree object = TREE_OPERAND (fn, 0); > - return build_new_method_call (object, member, > + return build_new_method_call (loc, object, member, > + arg_loc, > args, NULL_TREE, > (disallow_virtual > ? LOOKUP_NORMAL | LOOKUP_NONVIRTUAL > @@ -2315,7 +2317,8 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, > bool disallow_virtual, > object = build_non_dependent_expr (object); > } > > - result = build_new_method_call (object, fn, args, NULL_TREE, > + result = build_new_method_call (loc, object, fn, arg_loc, args, > + NULL_TREE, > (disallow_virtual > ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL > : LOOKUP_NORMAL), > @@ -2362,7 +2365,8 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, > bool disallow_virtual, > } > > /* A call to a namespace-scope function. */ > - result = build_new_function_call (fn, args, koenig_p, complain); > + result = build_new_function_call (loc, fn, arg_loc, args, koenig_p, > + complain); > } > } > else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR) > @@ -6628,7 +6632,8 @@ finish_omp_barrier (void) > { > tree fn = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER); > vec<tree, va_gc> *vec = make_tree_vector (); > - tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); > + tree stmt = finish_call_expr (input_location, fn, vNULL, &vec, false, > false, > + tf_warning_or_error); > release_tree_vector (vec); > finish_expr_stmt (stmt); > } > @@ -6638,7 +6643,8 @@ finish_omp_flush (void) > { > tree fn = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE); > vec<tree, va_gc> *vec = make_tree_vector (); > - tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); > + tree stmt = finish_call_expr (input_location, fn, vNULL, &vec, false, > false, > + tf_warning_or_error); > release_tree_vector (vec); > finish_expr_stmt (stmt); > } > @@ -6648,7 +6654,8 @@ finish_omp_taskwait (void) > { > tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT); > vec<tree, va_gc> *vec = make_tree_vector (); > - tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); > + tree stmt = finish_call_expr (input_location, fn, vNULL, &vec, false, > false, > + tf_warning_or_error); > release_tree_vector (vec); > finish_expr_stmt (stmt); > } > @@ -6658,7 +6665,8 @@ finish_omp_taskyield (void) > { > tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD); > vec<tree, va_gc> *vec = make_tree_vector (); > - tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); > + tree stmt = finish_call_expr (input_location, fn, vNULL, &vec, false, > false, > + tf_warning_or_error); > release_tree_vector (vec); > finish_expr_stmt (stmt); > } > @@ -6695,7 +6703,8 @@ finish_omp_cancel (tree clauses) > ifc = boolean_true_node; > vec->quick_push (build_int_cst (integer_type_node, mask)); > vec->quick_push (ifc); > - tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); > + tree stmt = finish_call_expr (input_location, fn, vNULL, &vec, false, > false, > + tf_warning_or_error); > release_tree_vector (vec); > finish_expr_stmt (stmt); > } > @@ -6721,7 +6730,8 @@ finish_omp_cancellation_point (tree clauses) > } > vec<tree, va_gc> *vec > = make_tree_vector_single (build_int_cst (integer_type_node, mask)); > - tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); > + tree stmt = finish_call_expr (input_location, fn, vNULL, &vec, false, > false, > + tf_warning_or_error); > release_tree_vector (vec); > finish_expr_stmt (stmt); > } > diff --git gcc/testsuite/g++.dg/diagnostic/location-1.C > gcc/testsuite/g++.dg/diagnostic/location-1.C > index e69de29..f9c3445 100644 > --- gcc/testsuite/g++.dg/diagnostic/location-1.C > +++ gcc/testsuite/g++.dg/diagnostic/location-1.C > @@ -0,0 +1,11 @@ > +// { dg-do compile } > + > +int foo (int *, int *, int *); > + > +void > +bar (void) > +{ > + foo (1, // { dg-error "8:invalid conversion" } > + 2, // { dg-error "10:invalid conversion" } > + 3); // { dg-error "12:invalid conversion" } > +} > > Marek
Marek