This patch extends various call-handling locations within the C++
frontend so that they can accept a possibly NULL vec<location_t> *,
using the location information if available in various diagnostics.

It updates the C++ frontend's parser for this production:

   postfix-expression:
     postfix-expression ( expression-list [opt] )

within cp_parser_postfix_expression so that it captures an
auto_vec<location_t> for the arguments (via
cp_parser_parenthesized_expression_list), and passes that around
within the parser, so that e.g.

  error: invalid conversion from 'int' to 'const char*' [-fpermissive]
     return callee_1 (first, second, third);
                                          ^

becomes:

  error: invalid conversion from 'int' to 'const char*' [-fpermissive]
     return callee_1 (first, second, third);
                             ^~~~~~

The vec<location_t> * are also passed to the arg-checking
code of r251238 ( https://gcc.gnu.org/ml/gcc-patches/2017-08/msg01164.html )
so that -Wformat can underline mismatching arguments for C++.

Doing this for C++ requires handling of the case where the vec<location_t>
from the expression-list needs to be offset by 1 relative to the args due
to the "this" parameter not being part of the expression-list, e.g. in:

  logger->log ("%i %s %i", 100, 101, 102);   [1]
                   ^~           ~~~

hence the patch adds a new "argument_locs" class to be responsible for
this in various places in c-family.

Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu;
OK for trunk?

[1] We don't yet underline the "%s" in C++; I plan to fix that as a
separate patch.

gcc/c-family/ChangeLog:
        * c-common.c (argument_locs::get_param_location): New method.
        (check_function_arguments): Convert param "arglocs" from
        vec<location_t> * to argument_locs.
        * c-common.h (class argument_locs): New class.
        (check_function_arguments): Convert final param from
        vec<location_t> * to argument_locs.
        (check_function_format): Likewise.
        * c-format.c (struct format_check_results): Add ctor; convert
        field "arglocs" from vec<location_t> * to argument_locs.
        (check_function_format): Convert param "arglocs" from
        vec<location_t> * to argument_locs.
        (check_format_info): Likewise.  Use a ctor when initializing
        format_ctx.
        (check_format_arg): Convert local "arglocs" from vec<location_t> *
        to argument_locs.
        (class argument_parser): Likewise for field "arglocs".
        (argument_parser::argument_parser): Likewise.
        (check_format_info_main): Likewise for param "arglocs".
        (check_format_types): Likewise.  Replace logic for looking up
        locations within arglocs with a call to
        argument_locs::get_param_location.

gcc/c/ChangeLog:
        * c-typeck.c (build_function_call_vec): Update for conversion
        of final parameter of check_function_arguments.

gcc/cp/ChangeLog:
        * call.c (print_z_candidate): Add optional "arglocs" param and
        pass it to fn_type_unification.
        (print_z_candidates): Add optional "arglocs" param and pass it to
        print_z_candidate.
        (print_error_for_call_failure): Add optional "arglocs" param and
        pass it to print_z_candidates.
        (build_new_function_call): Add "arglocs" param and
        pass it to print_error_for_call_failure and build_over_call.
        (convert_like_real): Convert param "expr" from tree to cp_expr.
        (build_over_call): Add optional "arglocs" param.  Use it if
        available when calling convert_like_with_context, by converting
        "arg" to a cp_expr. Use arglocs when calling
        check_function_arguments, determining the appropriate offset to
        use based on whether there was a "first_arg".
        (build_new_method_call_1): Add "arglocs" param and pass it to
        build_over_call.
        (build_new_method_call): Add "arglocs" param and pass it to
        build_new_method_call_1.
        * cp-tree.h (build_new_function_call): Add optional
        vec<location_t> * param.
        (build_new_method_call): Likewise.
        (fn_type_unification): Likewise.
        (finish_call_expr): Likewise.
        (cp_build_function_call_vec): Likewise.
        * parser.c (cp_parser_postfix_expression): Within handling of
        "postfix-expression ( expression-list [opt] )" production, add
        auto_vec<location_t> and pass it to be built to
        cp_parser_parenthesized_expression_list; pass it for use to
        calls to build_new_method_call and finish_call_expr.
        (cp_parser_parenthesized_expression_list): Add optional "arglocs"
        param.  Convert local "expr" to cp_expr, using it to populate
        "arglocs" if non-NULL.
        * pt.c (unify_type_mismatch): Convert final param from tree to
        cp_expr to fix the location of the "inform".
        (unify_arg_conversion): Likewise.
        (fn_type_unification): Add "arglocs" param and pass it to
        type_unification_real.
        (check_non_deducible_conversion): Convert "arg" from tree to
        cp_expr.
        (type_unification_real): Add optional "arglocs" param.
        Convert local "arg" from tree to cp_expr, reading its location
        from arglocs, or, failing that, from input_location.
        * semantics.c (finish_call_expr): Add optional
        vec<location_t> * param and pass to calls to build_new_method_call
        and build_new_function_call.
        * typeck.c (cp_build_function_call_vec): Add optional
        vec<location_t> * param and pass to call to
        check_function_arguments.

gcc/testsuite/ChangeLog:
        * g++.dg/Wformat-on-method.C: New test case.
        * g++.dg/diagnostic/param-type-mismatch.C: Update expected results
        to reflect underlining of pertinent arguments.
---
 gcc/c-family/c-common.c                            | 27 +++++++-
 gcc/c-family/c-common.h                            | 39 ++++++++++-
 gcc/c-family/c-format.c                            | 53 ++++++++-------
 gcc/c/c-typeck.c                                   |  3 +-
 gcc/cp/call.c                                      | 77 ++++++++++++++--------
 gcc/cp/cp-tree.h                                   | 15 +++--
 gcc/cp/parser.c                                    | 30 ++++++---
 gcc/cp/pt.c                                        | 54 ++++++++++-----
 gcc/cp/semantics.c                                 |  9 +--
 gcc/cp/typeck.c                                    |  6 +-
 gcc/testsuite/g++.dg/Wformat-on-method.C           | 31 +++++++++
 .../g++.dg/diagnostic/param-type-mismatch.C        | 18 ++---
 12 files changed, 261 insertions(+), 101 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/Wformat-on-method.C

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 156c89d..d238064 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -5534,12 +5534,35 @@ attribute_fallthrough_p (tree attr)
 }
 
 
+/* Lookup the location of the argument with 0-based index PARAM_IDX,
+   gracefully failing if data is unavailable, and handling
+   offsetting the index for the case where the "this"
+   wasn't in the expression-list.  */
+
+location_t
+argument_locs::get_param_location (unsigned int param_idx) const
+{
+  if (m_locs == NULL)
+    return UNKNOWN_LOCATION;
+
+  if (param_idx < m_offset)
+    return UNKNOWN_LOCATION;
+
+  param_idx -= m_offset;
+
+  gcc_assert (param_idx < m_locs->length ());
+
+  return (*m_locs)[param_idx];
+}
+
 /* Check for valid arguments being passed to a function with FNTYPE.
    There are NARGS arguments in the array ARGARRAY.  LOC should be used for
-   diagnostics.  Return true if -Wnonnull warning has been diagnosed.  */
+   diagnostics.  Return true if -Wnonnull warning has been diagnosed.
+   ARGLOCS gives the locations of the arguments
+   (if its "locs" is non-NULL).  */
 bool
 check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype,
-                         int nargs, tree *argarray, vec<location_t> *arglocs)
+                         int nargs, tree *argarray, argument_locs arglocs)
 {
   bool warned_p = false;
 
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 8e36768..7a0a5a0 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -807,8 +807,43 @@ extern const char *fname_as_string (int);
 extern tree fname_decl (location_t, unsigned, tree);
 
 extern int check_user_alignment (const_tree, bool);
+
+/* Information about the locations of arguments at a callsite,
+   based on parsing an expression-list.
+
+   A bundle of a (possibly NULL) vec<location_t> *, together with
+   an offset for determining how this vec corresponds to the
+   arguments at a callsite.
+
+   We either have an offset of 0:
+     | argarray[0] | argarray[1] | argarray[2] | ...
+     | m_locs  [0] | m_locs  [1] | m_locs  [2] | ...
+
+   or an offset of 1:
+     | argarray[0] | argarray[1] | argarray[2] | argarray[3]
+     | "this"      | m_locs  [0] | m_locs  [1] | m_locs[2]
+
+   for the C++ cases where the expression-list didn't contain "this",
+   such as in "ptr->call (expr0, expr1, expr2)".  */
+
+class argument_locs
+{
+ public:
+  argument_locs (const vec<location_t> *locs, unsigned int offset)
+  : m_locs (locs), m_offset (offset)
+  {
+    gcc_assert (offset == 0 || offset == 1);
+  }
+
+  location_t get_param_location (unsigned int param_idx) const;
+
+ private:
+  const vec<location_t> *m_locs;
+  unsigned int m_offset;
+};
+
 extern bool check_function_arguments (location_t loc, const_tree, const_tree,
-                                     int, tree *, vec<location_t> *);
+                                     int, tree *, argument_locs);
 extern void check_function_arguments_recurse (void (*)
                                              (void *, tree,
                                               unsigned HOST_WIDE_INT),
@@ -816,7 +851,7 @@ extern void check_function_arguments_recurse (void (*)
                                              unsigned HOST_WIDE_INT);
 extern bool check_builtin_function_arguments (location_t, vec<location_t>,
                                              tree, int, tree *);
-extern void check_function_format (tree, int, tree *, vec<location_t> *);
+extern void check_function_format (tree, int, tree *, argument_locs);
 extern bool attribute_fallthrough_p (tree);
 extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
 extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index 0dba979..e992a06 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -986,10 +986,16 @@ struct format_check_results
 
 struct format_check_context
 {
+  format_check_context (format_check_results *res_,
+                       function_format_info *info_,
+                       tree params_,
+                       argument_locs arglocs_)
+  : res (res_), info (info_), params (params_), arglocs (arglocs_) {}
+
   format_check_results *res;
   function_format_info *info;
   tree params;
-  vec<location_t> *arglocs;
+  argument_locs arglocs;
 };
 
 /* Return the format name (as specified in the original table) for the format
@@ -1012,8 +1018,7 @@ format_flags (int format_num)
   gcc_unreachable ();
 }
 
-static void check_format_info (function_format_info *, tree,
-                              vec<location_t> *);
+static void check_format_info (function_format_info *, tree, argument_locs);
 static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT);
 static void check_format_info_main (format_check_results *,
                                    function_format_info *, const char *,
@@ -1021,7 +1026,7 @@ static void check_format_info_main (format_check_results 
*,
                                    int, tree,
                                    unsigned HOST_WIDE_INT,
                                    object_allocator<format_wanted_type> &,
-                                   vec<location_t> *);
+                                   argument_locs);
 
 static void init_dollar_format_checking (int, tree);
 static int maybe_read_dollar_number (const char **, int,
@@ -1037,7 +1042,7 @@ static void check_format_types (const substring_loc 
&fmt_loc,
                                const format_kind_info *fki,
                                int offset_to_type_start,
                                char conversion_char,
-                               vec<location_t> *arglocs);
+                               argument_locs arglocs);
 static void format_type_warning (const substring_loc &fmt_loc,
                                 source_range *param_range,
                                 format_wanted_type *, tree,
@@ -1081,7 +1086,7 @@ decode_format_type (const char *s)
 
 void
 check_function_format (tree attrs, int nargs, tree *argarray,
-                      vec<location_t> *arglocs)
+                      argument_locs arglocs)
 {
   tree a;
 
@@ -1406,9 +1411,8 @@ get_flag_spec (const format_flag_spec *spec, int flag, 
const char *predicates)
 
 static void
 check_format_info (function_format_info *info, tree params,
-                  vec<location_t> *arglocs)
+                  argument_locs arglocs)
 {
-  format_check_context format_ctx;
   unsigned HOST_WIDE_INT arg_num;
   tree format_tree;
   format_check_results res;
@@ -1437,10 +1441,7 @@ check_format_info (function_format_info *info, tree 
params,
   res.number_other = 0;
   res.format_string_loc = input_location;
 
-  format_ctx.res = &res;
-  format_ctx.info = info;
-  format_ctx.params = params;
-  format_ctx.arglocs = arglocs;
+  format_check_context format_ctx (&res, info, params, arglocs);
 
   check_function_arguments_recurse (check_format_arg, &format_ctx,
                                    format_tree, arg_num);
@@ -1525,7 +1526,7 @@ check_format_arg (void *ctx, tree format_tree,
   format_check_results *res = format_ctx->res;
   function_format_info *info = format_ctx->info;
   tree params = format_ctx->params;
-  vec<location_t> *arglocs = format_ctx->arglocs;
+  argument_locs arglocs = format_ctx->arglocs;
 
   int format_length;
   HOST_WIDE_INT offset;
@@ -1777,7 +1778,7 @@ class argument_parser
                   location_t format_string_loc, flag_chars_t &flag_chars,
                   int &has_operand_number, tree first_fillin_param,
                   object_allocator <format_wanted_type> &fwt_pool_,
-                  vec<location_t> *arglocs);
+                  argument_locs arglocs);
 
   bool read_any_dollar ();
 
@@ -1856,7 +1857,7 @@ class argument_parser
  private:
   format_wanted_type *first_wanted_type;
   format_wanted_type *last_wanted_type;
-  vec<location_t> *arglocs;
+  argument_locs arglocs;
 };
 
 /* flag_chars_t's constructor.  */
@@ -2008,7 +2009,7 @@ argument_parser (function_format_info *info_, const char 
*&format_chars_,
                 int &has_operand_number_,
                 tree first_fillin_param_,
                 object_allocator <format_wanted_type> &fwt_pool_,
-                vec<location_t> *arglocs_)
+                argument_locs arglocs_)
 : info (info_),
   fki (&format_types[info->format_type]),
   flag_specs (fki->flag_specs),
@@ -2768,7 +2769,7 @@ check_format_info_main (format_check_results *res,
                        int format_length, tree params,
                        unsigned HOST_WIDE_INT arg_num,
                        object_allocator <format_wanted_type> &fwt_pool,
-                       vec<location_t> *arglocs)
+                       argument_locs arglocs)
 {
   const char * const orig_format_chars = format_chars;
   const tree first_fillin_param = params;
@@ -3046,7 +3047,7 @@ check_format_types (const substring_loc &fmt_loc,
                    format_wanted_type *types, const format_kind_info *fki,
                    int offset_to_type_start,
                    char conversion_char,
-                   vec<location_t> *arglocs)
+                   argument_locs arglocs)
 {
   for (; types != 0; types = types->next)
     {
@@ -3085,22 +3086,24 @@ check_format_types (const substring_loc &fmt_loc,
       char_type_flag = 0;
 
       source_range param_range;
-      source_range *param_range_ptr;
+      source_range *param_range_ptr = NULL;
       if (EXPR_HAS_LOCATION (cur_param))
        {
          param_range = EXPR_LOCATION_RANGE (cur_param);
          param_range_ptr = &param_range;
        }
-      else if (arglocs)
+      else
        {
          /* arg_num is 1-based.  */
          gcc_assert (types->arg_num > 0);
-         location_t param_loc = (*arglocs)[types->arg_num - 1];
-         param_range = get_range_from_loc (line_table, param_loc);
-         param_range_ptr = &param_range;
+         unsigned int param_idx = types->arg_num - 1;
+         location_t param_loc = arglocs.get_param_location (param_idx);
+         if (param_loc != UNKNOWN_LOCATION)
+           {
+             param_range = get_range_from_loc (line_table, param_loc);
+             param_range_ptr = &param_range;
+           }
        }
-      else
-       param_range_ptr = NULL;
 
       STRIP_NOPS (cur_param);
 
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index d7ca148..5999a3b 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -3118,7 +3118,8 @@ build_function_call_vec (location_t loc, vec<location_t> 
arg_loc,
 
   /* Check that the arguments to the function are valid.  */
   bool warned_p = check_function_arguments (loc, fundecl, fntype,
-                                           nargs, argarray, &arg_loc);
+                                           nargs, argarray,
+                                           argument_locs (&arg_loc, 0));
 
   if (name != NULL_TREE
       && !strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10))
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 067db59a..afcdd99 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -147,7 +147,8 @@ 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 (struct z_candidate *, int, tsubst_flags_t,
+                            vec<location_t> * = NULL);
 #define convert_like(CONV, EXPR, COMPLAIN)                     \
   convert_like_real ((CONV), (EXPR), NULL_TREE, 0,             \
                     /*issue_conversion_warnings=*/true,        \
@@ -156,14 +157,16 @@ static tree build_over_call (struct z_candidate *, int, 
tsubst_flags_t);
   convert_like_real ((CONV), (EXPR), (FN), (ARGNO),                    \
                     /*issue_conversion_warnings=*/true,                \
                     /*c_cast_p=*/false, (COMPLAIN))
-static tree convert_like_real (conversion *, tree, tree, int, bool,
+static tree convert_like_real (conversion *, cp_expr, tree, 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,
                                                         tsubst_flags_t);
-static void print_z_candidate (location_t, const char *, struct z_candidate *);
-static void print_z_candidates (location_t, struct z_candidate *);
+static void print_z_candidate (location_t, const char *, struct z_candidate *,
+                              vec<location_t> * = NULL);
+static void print_z_candidates (location_t, struct z_candidate *,
+                               vec<location_t> * = NULL);
 static tree build_this (tree);
 static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
 static bool any_strictly_viable (struct z_candidate *);
@@ -3442,7 +3445,8 @@ print_arity_information (location_t loc, unsigned int 
have, unsigned int want)
 
 static void
 print_z_candidate (location_t loc, const char *msgstr,
-                  struct z_candidate *candidate)
+                  struct z_candidate *candidate,
+                  vec<location_t> *arglocs)
 {
   const char *msg = (msgstr == NULL
                     ? ""
@@ -3531,7 +3535,7 @@ print_z_candidate (location_t loc, const char *msgstr,
                               r->u.template_unification.return_type,
                               r->u.template_unification.strict,
                               r->u.template_unification.flags,
-                              true, false);
+                              true, false, arglocs);
          break;
        case rr_invalid_copy:
          inform (cloc,
@@ -3560,7 +3564,8 @@ print_z_candidate (location_t loc, const char *msgstr,
 }
 
 static void
-print_z_candidates (location_t loc, struct z_candidate *candidates)
+print_z_candidates (location_t loc, struct z_candidate *candidates,
+                   vec<location_t> *arglocs)
 {
   struct z_candidate *cand1;
   struct z_candidate **cand2;
@@ -3606,7 +3611,7 @@ print_z_candidates (location_t loc, struct z_candidate 
*candidates)
     }
 
   for (; candidates; candidates = candidates->next)
-    print_z_candidate (loc, "candidate:", candidates);
+    print_z_candidate (loc, "candidate:", candidates, arglocs);
 }
 
 /* USER_SEQ is a user-defined conversion sequence, beginning with a
@@ -4212,7 +4217,8 @@ perform_overload_resolution (tree fn,
 
 static void
 print_error_for_call_failure (tree fn, vec<tree, va_gc> *args,
-                             struct z_candidate *candidates)
+                             struct z_candidate *candidates,
+                             vec<location_t> *arglocs = NULL)
 {
   tree targs = NULL_TREE;
   if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
@@ -4232,7 +4238,7 @@ print_error_for_call_failure (tree fn, vec<tree, va_gc> 
*args,
     error_at (loc, "call of overloaded %<%D(%A)%> is ambiguous",
              name, build_tree_list_vec (args));
   if (candidates)
-    print_z_candidates (loc, candidates);
+    print_z_candidates (loc, candidates, arglocs);
 }
 
 /* Return an expression for a call to FN (a namespace-scope function,
@@ -4241,7 +4247,8 @@ print_error_for_call_failure (tree fn, vec<tree, va_gc> 
*args,
 
 tree
 build_new_function_call (tree fn, vec<tree, va_gc> **args,
-                        tsubst_flags_t complain)
+                        tsubst_flags_t complain,
+                        vec<location_t> *arglocs)
 {
   struct z_candidate *candidates, *cand;
   bool any_viable_p;
@@ -4275,7 +4282,7 @@ build_new_function_call (tree fn, vec<tree, va_gc> **args,
            return cp_build_function_call_vec (candidates->fn, args, complain);
 
          // Otherwise, emit notes for non-viable candidates.
-         print_error_for_call_failure (fn, *args, candidates);
+         print_error_for_call_failure (fn, *args, candidates, arglocs);
        }
       result = error_mark_node;
     }
@@ -4307,7 +4314,7 @@ build_new_function_call (tree fn, vec<tree, va_gc> **args,
           flags |= LOOKUP_EXPLICIT_TMPL_ARGS;
         }
 
-      result = build_over_call (cand, flags, complain);
+      result = build_over_call (cand, flags, complain, arglocs);
     }
 
   /* Free all the conversions we allocated.  */
@@ -6588,14 +6595,16 @@ 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,
+convert_like_real (conversion *convs, cp_expr expr, tree fn, int argnum,
                   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);
+  location_t loc = expr.get_location ();
+  if (loc == UNKNOWN_LOCATION)
+    loc = input_location;
 
   if (convs->bad_p && !(complain & tf_error))
     return error_mark_node;
@@ -6983,13 +6992,13 @@ convert_like_real (conversion *convs, tree expr, tree 
fn, int argnum,
                   cannot create a temporary.  */
                if (lvalue & clk_bitfield)
                  error_at (loc, "cannot bind bitfield %qE to %qT",
-                           expr, ref_type);
+                           expr.get_value (), ref_type);
                else if (lvalue & clk_packed)
                  error_at (loc, "cannot bind packed field %qE to %qT",
-                           expr, ref_type);
+                           expr.get_value (), ref_type);
                else
                  error_at (loc, "cannot bind rvalue %qE to %qT",
-                           expr, ref_type);
+                           expr.get_value (), ref_type);
                return error_mark_node;
              }
            /* If the source is a packed field, and we must use a copy
@@ -7003,7 +7012,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, 
int argnum,
                && type_has_nontrivial_copy_init (type))
              {
                error_at (loc, "cannot bind packed field %qE to %qT",
-                         expr, ref_type);
+                         expr.get_value (), ref_type);
                return error_mark_node;
              }
            if (lvalue & clk_bitfield)
@@ -7542,7 +7551,8 @@ unsafe_copy_elision_p (tree target, tree exp)
    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 (struct z_candidate *cand, int flags, tsubst_flags_t complain,
+                vec<location_t> *arglocs)
 {
   tree fn = cand->fn;
   const vec<tree, va_gc> *args = cand->args;
@@ -7687,6 +7697,15 @@ build_over_call (struct z_candidate *cand, int flags, 
tsubst_flags_t complain)
     nargs = parmlen;
   argarray = XALLOCAVEC (tree, nargs);
 
+  /* Determine offset to args covered by ARGLOCS within argarray.
+     We either have an offset of 0:
+       | argarray[0] | argarray[1] | argarray[2] | ...
+       | arglocs [0] | arglocs [1] | arglocs [2] | ...
+     or an offset of 1:
+       | argarray[0] | argarray[1] | argarray[2] | ...
+       | first_arg   | arglocs [0] | arglocs [1] | arglocs[2] ...*/
+  int arglocs_offset = first_arg != NULL_TREE ? 1 : 0;
+
   /* The implicit parameters to a constructor are not considered by overload
      resolution, and must be of the proper type.  */
   if (DECL_CONSTRUCTOR_P (fn))
@@ -7805,7 +7824,9 @@ build_over_call (struct z_candidate *cand, int flags, 
tsubst_flags_t complain)
        parm = TREE_CHAIN (parm), ++arg_index, ++i)
     {
       tree type = TREE_VALUE (parm);
-      tree arg = (*args)[arg_index];
+      cp_expr arg = (*args)[arg_index];
+      if (arglocs)
+       arg.set_location ((*arglocs)[arg_index]);
       bool conversion_warning = true;
 
       conv = convs[i];
@@ -7949,7 +7970,9 @@ build_over_call (struct z_candidate *cand, int flags, 
tsubst_flags_t complain)
        fargs[j] = maybe_constant_value (argarray[j]);
 
       warned_p = check_function_arguments (input_location, fn, TREE_TYPE (fn),
-                                          nargs, fargs, NULL);
+                                          nargs, fargs,
+                                          argument_locs (arglocs,
+                                                         arglocs_offset));
     }
 
   if (DECL_INHERITED_CTOR (fn))
@@ -8917,7 +8940,8 @@ name_as_c_string (tree name, tree type, bool *free_p)
 static tree
 build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
                         tree conversion_path, int flags,
-                        tree *fn_p, tsubst_flags_t complain)
+                        tree *fn_p, tsubst_flags_t complain,
+                        vec<location_t> *arglocs)
 {
   struct z_candidate *candidates = 0, *cand;
   tree explicit_targs = NULL_TREE;
@@ -9248,7 +9272,7 @@ 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 (cand, flags, complain, arglocs);
              /* In an expression of the form `a->f()' where `f' turns
                 out to be a static member function, `a' is
                 none-the-less evaluated.  */
@@ -9313,12 +9337,13 @@ build_new_method_call_1 (tree instance, tree fns, 
vec<tree, va_gc> **args,
 tree
 build_new_method_call (tree instance, tree fns, vec<tree, va_gc> **args,
                       tree conversion_path, int flags,
-                      tree *fn_p, tsubst_flags_t complain)
+                      tree *fn_p, tsubst_flags_t complain,
+                      vec<location_t> *arglocs)
 {
   tree ret;
   bool subtime = timevar_cond_start (TV_OVERLOAD);
   ret = build_new_method_call_1 (instance, fns, args, conversion_path, flags,
-                                 fn_p, complain);
+                                 fn_p, complain, arglocs);
   timevar_cond_stop (TV_OVERLOAD, subtime);
   return ret;
 }
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4dd9fc6..b1ec172 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5862,13 +5862,15 @@ extern tree extract_call_expr                   (tree);
 extern tree build_user_type_conversion         (tree, tree, int,
                                                 tsubst_flags_t);
 extern tree build_new_function_call            (tree, vec<tree, va_gc> **,
-                                                tsubst_flags_t);
+                                                tsubst_flags_t,
+                                                vec<location_t> * = NULL);
 extern tree build_operator_new_call            (tree, vec<tree, va_gc> **,
                                                 tree *, tree *, tree, tree,
                                                 tree *, tsubst_flags_t);
 extern tree build_new_method_call              (tree, tree,
                                                 vec<tree, va_gc> **, tree,
-                                                int, tree *, tsubst_flags_t);
+                                                int, tree *, tsubst_flags_t,
+                                                vec<location_t> * = NULL);
 extern tree build_special_member_call          (tree, tree,
                                                 vec<tree, va_gc> **,
                                                 tree, int, tsubst_flags_t);
@@ -6433,7 +6435,8 @@ extern tree instantiate_template          (tree, tree, 
tsubst_flags_t);
 extern tree fn_type_unification                        (tree, tree, tree,
                                                 const tree *, unsigned int,
                                                 tree, unification_kind_t, int,
-                                                bool, bool);
+                                                bool, bool,
+                                                vec<location_t> * = NULL);
 extern void mark_decl_instantiated             (tree, int);
 extern int more_specialized_fn                 (tree, tree, int);
 extern void do_decl_instantiation              (tree, tree);
@@ -6720,7 +6723,8 @@ bool empty_expr_stmt_p                            (tree);
 extern cp_expr perform_koenig_lookup           (cp_expr, vec<tree, va_gc> *,
                                                 tsubst_flags_t);
 extern tree finish_call_expr                   (tree, vec<tree, va_gc> **, 
bool,
-                                                bool, tsubst_flags_t);
+                                                bool, tsubst_flags_t,
+                                                vec<location_t> * = NULL);
 extern tree lookup_and_finish_template_variable (tree, tree, tsubst_flags_t = 
tf_warning_or_error);
 extern tree finish_template_variable           (tree, tsubst_flags_t = 
tf_warning_or_error);
 extern cp_expr finish_increment_expr           (cp_expr, enum tree_code);
@@ -7026,7 +7030,8 @@ extern tree get_member_function_from_ptrfunc      (tree 
*, tree, tsubst_flags_t);
 extern tree cp_build_function_call_nary         (tree, tsubst_flags_t, ...)
                                                ATTRIBUTE_SENTINEL;
 extern tree cp_build_function_call_vec         (tree, vec<tree, va_gc> **,
-                                                tsubst_flags_t);
+                                                tsubst_flags_t,
+                                                vec<location_t> * = NULL);
 extern tree build_x_binary_op                  (location_t,
                                                 enum tree_code, tree,
                                                 enum tree_code, tree,
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b849824..29de054 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -2051,7 +2051,8 @@ static tree cp_parser_postfix_open_square_expression
 static tree cp_parser_postfix_dot_deref_expression
   (cp_parser *, enum cpp_ttype, cp_expr, bool, cp_id_kind *, location_t);
 static vec<tree, va_gc> *cp_parser_parenthesized_expression_list
-  (cp_parser *, int, bool, bool, bool *, location_t * = NULL);
+  (cp_parser *, int, bool, bool, bool *, location_t * = NULL,
+   vec<location_t> * = NULL);
 /* Values for the second parameter of cp_parser_parenthesized_expression_list. 
 */
 enum { non_attr = 0, normal_attr = 1, id_attr = 2 };
 static void cp_parser_pseudo_destructor_name
@@ -6961,6 +6962,7 @@ 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;
+           auto_vec<location_t> arglocs;
            location_t close_paren_loc = UNKNOWN_LOCATION;
 
             is_member_access = false;
@@ -6981,7 +6983,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool 
address_p, bool cast_p,
                    (parser, non_attr,
                     /*cast_p=*/false, /*allow_expansion_p=*/true,
                     /*non_constant_p=*/NULL,
-                    /*close_paren_loc=*/&close_paren_loc));
+                    /*close_paren_loc=*/&close_paren_loc,
+                    &arglocs));
            if (is_builtin_constant_p)
              {
                parser->integral_constant_expression_p
@@ -7092,14 +7095,16 @@ cp_parser_postfix_expression (cp_parser *parser, bool 
address_p, bool cast_p,
                         ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
                         : LOOKUP_NORMAL),
                        /*fn_p=*/NULL,
-                       complain));
+                       complain,
+                       &arglocs));
                  }
                else
                  postfix_expression
                    = finish_call_expr (postfix_expression, &args,
                                        /*disallow_virtual=*/false,
                                        /*koenig_p=*/false,
-                                       complain);
+                                       complain,
+                                       &arglocs);
              }
            else if (TREE_CODE (postfix_expression) == OFFSET_REF
                     || TREE_CODE (postfix_expression) == MEMBER_REF
@@ -7114,14 +7119,16 @@ cp_parser_postfix_expression (cp_parser *parser, bool 
address_p, bool cast_p,
                = finish_call_expr (postfix_expression, &args,
                                    /*disallow_virtual=*/true,
                                    koenig_p,
-                                   complain);
+                                   complain,
+                                   &arglocs);
            else
              /* All other function calls.  */
              postfix_expression
                = finish_call_expr (postfix_expression, &args,
                                    /*disallow_virtual=*/false,
                                    koenig_p,
-                                   complain);
+                                   complain,
+                                   &arglocs);
 
            if (close_paren_loc != UNKNOWN_LOCATION)
              {
@@ -7637,7 +7644,8 @@ cp_parser_parenthesized_expression_list (cp_parser* 
parser,
                                         bool cast_p,
                                          bool allow_expansion_p,
                                         bool *non_constant_p,
-                                        location_t *close_paren_loc)
+                                        location_t *close_paren_loc,
+                                        vec<location_t> *arglocs)
 {
   vec<tree, va_gc> *expression_list;
   bool fold_expr_p = is_attribute_list != non_attr;
@@ -7664,8 +7672,6 @@ cp_parser_parenthesized_expression_list (cp_parser* 
parser,
   if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
     while (true)
       {
-       tree expr;
-
        /* At the beginning of attribute lists, check to see if the
           next token is an identifier.  */
        if (is_attribute_list == id_attr
@@ -7680,6 +7686,7 @@ cp_parser_parenthesized_expression_list (cp_parser* 
parser,
          }
        else
          {
+           cp_expr expr;
            bool expr_non_constant_p;
 
            /* Parse the next assignment-expression.  */
@@ -7723,7 +7730,10 @@ cp_parser_parenthesized_expression_list (cp_parser* 
parser,
                expressions to the list, so that we can still tell if
                the correct form for a parenthesized expression-list
                is found. That gives better errors.  */
-           vec_safe_push (expression_list, expr);
+           vec_safe_push (expression_list, expr.get_value ());
+
+           if (arglocs)
+             arglocs->safe_push (expr.get_location ());
 
            if (expr == error_mark_node)
              goto skip_comma;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8d816c7..c642077 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -155,7 +155,8 @@ static int maybe_adjust_types_for_deduction 
(unification_kind_t, tree*, tree*,
 static int type_unification_real (tree, tree, tree, const tree *,
                                  unsigned int, int, unification_kind_t, int,
                                  vec<deferred_access_check, va_gc> **,
-                                 bool);
+                                 bool,
+                                 vec<location_t> * = NULL);
 static void note_template_header (int);
 static tree convert_nontype_argument_function (tree, tree, tsubst_flags_t);
 static tree convert_nontype_argument (tree, tree, tsubst_flags_t);
@@ -6191,10 +6192,16 @@ unify_cv_qual_mismatch (bool explain_p, tree parm, tree 
arg)
 }
 
 static int
-unify_type_mismatch (bool explain_p, tree parm, tree arg)
+unify_type_mismatch (bool explain_p, tree parm, cp_expr arg)
 {
   if (explain_p)
-    inform (input_location, "  mismatched types %qT and %qT", parm, arg);
+    {
+      location_t loc = arg.get_location ();
+      if (loc == UNKNOWN_LOCATION)
+       loc = input_location;
+      inform (loc, "  mismatched types %qT and %qT", parm,
+             arg.get_value ());
+    }
   return unify_invalid (explain_p);
 }
 
@@ -6310,12 +6317,17 @@ unify_too_few_arguments (bool explain_p, int have, int 
wanted,
 
 static int
 unify_arg_conversion (bool explain_p, tree to_type,
-                     tree from_type, tree arg)
+                     tree from_type, cp_expr arg)
 {
   if (explain_p)
-    inform (EXPR_LOC_OR_LOC (arg, input_location),
-           "  cannot convert %qE (type %qT) to type %qT",
-           arg, from_type, to_type);
+    {
+      location_t loc = arg.get_location ();
+      if (loc == UNKNOWN_LOCATION)
+       loc = input_location;
+      inform (loc,
+             "  cannot convert %qE (type %qT) to type %qT",
+             arg.get_value (), from_type, to_type);
+    }
   return unify_invalid (explain_p);
 }
 
@@ -18416,7 +18428,8 @@ fn_type_unification (tree fn,
                     unification_kind_t strict,
                     int flags,
                     bool explain_p,
-                    bool decltype_p)
+                    bool decltype_p,
+                    vec<location_t> *arglocs)
 {
   tree parms;
   tree fntype;
@@ -18625,7 +18638,7 @@ fn_type_unification (tree fn,
 
   ok = !type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
                               full_targs, parms, args, nargs, /*subr=*/0,
-                              strict, flags, &checks, explain_p);
+                              strict, flags, &checks, explain_p, arglocs);
   if (!explain_p)
     pop_tinst_level ();
   if (!ok)
@@ -18860,7 +18873,7 @@ maybe_adjust_types_for_deduction (unification_kind_t 
strict,
    unify_one_argument.  */
 
 static int
-check_non_deducible_conversion (tree parm, tree arg, int strict,
+check_non_deducible_conversion (tree parm, cp_expr arg, int strict,
                                int flags, bool explain_p)
 {
   tree type;
@@ -18882,7 +18895,7 @@ check_non_deducible_conversion (tree parm, tree arg, 
int strict,
   else if (strict != DEDUCE_EXACT)
     {
       if (can_convert_arg (parm, type,
-                          TYPE_P (arg) ? NULL_TREE : arg,
+                          TYPE_P (arg) ? NULL_TREE : arg.get_value (),
                           flags, explain_p ? tf_warning_or_error : tf_none))
        return unify_success (explain_p);
     }
@@ -19187,9 +19200,10 @@ type_unification_real (tree tparms,
                       unification_kind_t strict,
                       int flags,
                       vec<deferred_access_check, va_gc> **checks,
-                      bool explain_p)
+                      bool explain_p,
+                      vec<location_t> *arglocs)
 {
-  tree parm, arg;
+  tree parm;
   int i;
   int ntparms = TREE_VEC_LENGTH (tparms);
   int saw_undeduced = 0;
@@ -19235,7 +19249,12 @@ type_unification_real (tree tparms,
           parameter pack is a non-deduced context.  */
        continue;
 
-      arg = args[ia];
+      cp_expr arg = args[ia];
+      if (arglocs)
+       arg.set_location ((*arglocs)[ia]);
+      else
+       if (!CAN_HAVE_LOCATION_P (arg.get_value ()))
+         arg.set_location (input_location);
       ++ia;
 
       if (unify_one_argument (tparms, full_targs, parm, arg, subr, strict,
@@ -19398,7 +19417,12 @@ type_unification_real (tree tparms,
                 parameter pack is a non-deduced context.  */
              continue;
 
-           arg = args[ia];
+           cp_expr arg = args[ia];
+           if (arglocs)
+             arg.set_location ((*arglocs)[ia]);
+           else
+             if (!CAN_HAVE_LOCATION_P (arg.get_value ()))
+               arg.set_location (input_location);
            ++ia;
 
            if (uses_template_parms (parm))
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 5401e78..d58eef2 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2304,7 +2304,8 @@ perform_koenig_lookup (cp_expr fn, vec<tree, va_gc> *args,
 
 tree
 finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
-                 bool koenig_p, tsubst_flags_t complain)
+                 bool koenig_p, tsubst_flags_t complain,
+                 vec<location_t> *arglocs)
 {
   tree result;
   tree orig_fn;
@@ -2388,7 +2389,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool 
disallow_virtual,
                                          ? LOOKUP_NORMAL | LOOKUP_NONVIRTUAL
                                         : LOOKUP_NORMAL),
                                        /*fn_p=*/NULL,
-                                       complain);
+                                       complain, arglocs);
        }
     }
 
@@ -2440,7 +2441,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool 
disallow_virtual,
                                       ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
                                       : LOOKUP_NORMAL),
                                      /*fn_p=*/NULL,
-                                     complain);
+                                     complain, arglocs);
     }
   else if (is_overloaded_fn (fn))
     {
@@ -2483,7 +2484,7 @@ 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, complain);
+         result = build_new_function_call (fn, args, complain, arglocs);
        }
     }
   else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 63667f3..3c8ef7a3 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -3577,7 +3577,8 @@ cp_build_function_call_nary (tree function, 
tsubst_flags_t complain, ...)
 
 tree
 cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
-                           tsubst_flags_t complain)
+                           tsubst_flags_t complain,
+                           vec<location_t> *arglocs)
 {
   tree fntype, fndecl;
   int is_method;
@@ -3699,7 +3700,8 @@ cp_build_function_call_vec (tree function, vec<tree, 
va_gc> **params,
   /* Check for errors in format strings and inappropriately
      null parameters.  */
   bool warned_p = check_function_arguments (input_location, fndecl, fntype,
-                                           nargs, argarray, NULL);
+                                           nargs, argarray,
+                                           argument_locs (arglocs, 0));
 
   ret = build_cxx_call (function, nargs, argarray, complain);
 
diff --git a/gcc/testsuite/g++.dg/Wformat-on-method.C 
b/gcc/testsuite/g++.dg/Wformat-on-method.C
new file mode 100644
index 0000000..4ff22fb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/Wformat-on-method.C
@@ -0,0 +1,31 @@
+/* { dg-options "-Wformat -fdiagnostics-show-caret" } */
+
+struct logger
+{
+  void log (const char *fmt, ...)
+    __attribute__ ((format (gnu_printf, (2), (3))));
+
+  void test ();
+};
+
+/* Test of location-lookup within method call.  */
+
+void test (logger *logger)
+{
+  logger->log ("%i %s %i", 100, 101, 102); /* { dg-warning "format '%s' 
expects argument of type 'char\\*', but argument 4 has type 'int'" } */
+/* { dg-begin-multiline-output "" }
+   logger->log ("%i %s %i", 100, 101, 102);
+                                 ~~~     ^
+   { dg-end-multiline-output "" } */
+}
+
+/* Test of location-lookup with implicit "this".  */
+
+void logger::test ()
+{
+  log ("%i %s %i", 100, 101, 102); /* { dg-warning "format '%s' expects 
argument of type 'char\\*', but argument 4 has type 'int'" } */
+/* { dg-begin-multiline-output "" }
+   log ("%i %s %i", 100, 101, 102);
+                         ~~~     ^
+   { dg-end-multiline-output "" } */
+}
diff --git a/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch.C 
b/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch.C
index b8833ef..f9f5d74 100644
--- a/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch.C
+++ b/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch.C
@@ -17,7 +17,7 @@ int test_1 (int first, int second, float third)
   return callee_1 (first, second, third); // { dg-error "invalid conversion 
from 'int' to 'const char\\*'" }
   /* { dg-begin-multiline-output "" }
    return callee_1 (first, second, third);
-                                        ^
+                           ^~~~~~
      { dg-end-multiline-output "" } */
   // { dg-message "initializing argument 2 of 'int callee_1\\(int, const 
char\\*, float\\)'" "" { target *-*-* } callee_1 }
   /* { dg-begin-multiline-output "" }
@@ -35,7 +35,7 @@ int test_2 (int first, int second, float third)
   return callee_2 (first, second, third); // { dg-error "invalid conversion 
from 'int' to 'const char\\*'" }
   /* { dg-begin-multiline-output "" }
    return callee_2 (first, second, third);
-                                        ^
+                           ^~~~~~
      { dg-end-multiline-output "" } */
   // { dg-message "initializing argument 2 of 'int callee_2\\(int, const 
char\\*, float\\)'" "" { target *-*-* } callee_2 }
   /* { dg-begin-multiline-output "" }
@@ -56,7 +56,7 @@ int test_3 (int first, int second, float third)
   return callee_3 (first, second, third); // { dg-error "invalid conversion 
from 'int' to 'const char\\*'" }
   /* { dg-begin-multiline-output "" }
    return callee_3 (first, second, third);
-                                        ^
+                           ^~~~~~
      { dg-end-multiline-output "" } */
   // { dg-message "initializing argument 2 of 'int callee_3\\(int, const 
char\\*, float\\)'" "" { target *-*-* } callee_3 }
   /* { dg-begin-multiline-output "" }
@@ -74,7 +74,7 @@ int test_4 (int first, int second, float third)
   return s4::member_1 (first, second, third); // { dg-error "invalid 
conversion from 'int' to 'const char\\*'" }
   /* { dg-begin-multiline-output "" }
    return s4::member_1 (first, second, third);
-                                            ^
+                               ^~~~~~
      { dg-end-multiline-output "" } */
   /* { dg-begin-multiline-output "" }
  struct s4 { static int member_1 (int one, const char *two, float three); };
@@ -92,7 +92,7 @@ int test_5 (int first, int second, float third)
   return inst.member_1 (first, second, third); // { dg-error "invalid 
conversion from 'int' to 'const char\\*'" }
   /* { dg-begin-multiline-output "" }
    return inst.member_1 (first, second, third);
-                                             ^
+                                ^~~~~~
      { dg-end-multiline-output "" } */
   /* { dg-begin-multiline-output "" }
  struct s5 { int member_1 (int one, const char *two, float three); };
@@ -109,7 +109,7 @@ int test_6 (int first, int second, float third, s6 *ptr)
   return ptr->member_1 (first, second, third); // { dg-error "invalid 
conversion from 'int' to 'const char\\*'" }
   /* { dg-begin-multiline-output "" }
    return ptr->member_1 (first, second, third);
-                                             ^
+                                ^~~~~~
      { dg-end-multiline-output "" } */
   /* { dg-begin-multiline-output "" }
  struct s6 { int member_1 (int one, const char *two, float three); };
@@ -131,7 +131,7 @@ int test_7 (int first, int second, float third)
      { dg-end-multiline-output "" } */
   /* { dg-begin-multiline-output "" }
    return test_7 <const char *> (first, second, third);
-                                                     ^
+                                        ^~~~~~
      { dg-end-multiline-output "" } */
   /* { dg-begin-multiline-output "" }
  int test_7 (int one, T two, float three);
@@ -149,7 +149,7 @@ int test_8 (int first, int second, float third)
   return s8 <const char *>::member_1 (first, second, third); // { dg-error 
"invalid conversion from 'int' to 'const char\\*'" }
   /* { dg-begin-multiline-output "" }
    return s8 <const char *>::member_1 (first, second, third);
-                                                           ^
+                                              ^~~~~~
      { dg-end-multiline-output "" } */
   /* { dg-begin-multiline-output "" }
  struct s8 { static int member_1 (int one, T two, float three); };
@@ -168,7 +168,7 @@ int test_9 (int first, int second, float third)
   return inst.member_1 (first, second, third); // { dg-error "invalid 
conversion from 'int' to 'const char\\*'" }
   /* { dg-begin-multiline-output "" }
    return inst.member_1 (first, second, third);
-                                             ^
+                                ^~~~~~
      { dg-end-multiline-output "" } */
   /* { dg-begin-multiline-output "" }
  struct s9 { int member_1 (int one, T two, float three); };
-- 
1.8.5.3

Reply via email to