On Thu, 2024-12-19 at 18:40 -0500, David Malcolm wrote:

Jason: are the C++ changes OK?  Patch can also be seen at:
https://gcc.gnu.org/pipermail/gcc-patches/2024-December/672076.html

Joseph approved the C part of this in
https://gcc.gnu.org/pipermail/gcc-patches/2025-January/672473.html

Thanks
Dave



> Consider this case of a bad call to a callback function (perhaps
> due to C23 changing the meaning of () in function decls):
> 
> struct p {
>         int (*bar)();
> };
> 
> void baz() {
>     struct p q;
>     q.bar(1);
> }
> 
> Before this patch the C frontend emits:
> 
> t.c: In function 'baz':
> t.c:7:5: error: too many arguments to function 'q.bar'
>     7 |     q.bar(1);
>       |     ^
> 
> and the C++ frontend emits:
> 
> t.c: In function 'void baz()':
> t.c:7:10: error: too many arguments to function
>     7 |     q.bar(1);
>       |     ~~~~~^~~
> 
> neither of which give the user much help in terms of knowing what
> was expected, and where the relevant declaration is.
> 
> With this patch the C frontend emits:
> 
> t.c: In function 'baz':
> t.c:7:5: error: too many arguments to function 'q.bar'; expected 0,
> have 1
>     7 |     q.bar(1);
>       |     ^     ~
> t.c:2:15: note: declared here
>     2 |         int (*bar)();
>       |               ^~~
> 
> (showing the expected vs actual counts, the pertinent field decl, and
> underlining the first extraneous argument at the callsite)
> 
> and the C++ frontend emits:
> 
> t.c: In function 'void baz()':
> t.c:7:10: error: too many arguments to function; expected 0, have 1
>     7 |     q.bar(1);
>       |     ~~~~~^~~
> 
> (showing the expected vs actual counts; the other data was not
> accessible
> without a more invasive patch)
> 
> Similarly, the patch also updates the "too few arguments" case to
> also
> show expected vs actual counts.  Doing so requires a tweak to the
> wording to say "at least" for the case of variadic fns, and for C++
> fns
> with default args, where e.g. previously the C FE emitted:
> 
> s.c: In function 'test':
> s.c:5:3: error: too few arguments to function 'callee'
>     5 |   callee ();
>       |   ^~~~~~
> s.c:1:6: note: declared here
>     1 | void callee (const char *, ...);
>       |      ^~~~~~
> 
> with this patch it emits:
> 
> s.c: In function 'test':
> s.c:5:3: error: too few arguments to function 'callee'; expected at
> least 1, have 0
>     5 |   callee ();
>       |   ^~~~~~
> s.c:1:6: note: declared here
>     1 | void callee (const char *, ...);
>       |      ^~~~~~
> 
> Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
> OK for trunk?
> 
> gcc/c/ChangeLog:
>       PR c/118112
>       * c-typeck.cc (inform_declaration): Add "function_expr"
> param and
>       use it for cases where we couldn't show the function decl to
> show
>       field decls for callbacks.
>       (build_function_call_vec): Add missing
> auto_diagnostic_group.
>       Update for new param of inform_declaration.
>       (convert_arguments): Likewise.  For the "too many arguments"
> case
>       add the expected vs actual counts to the message, and if we
> have
>       it, add the location_t of the first surplus param as a
> secondary
>       location within the diagnostic.  For the "too few arguments"
> case,
>       determine the minimum number of arguments required and add
> the
>       expected vs actual counts to the message, tweaking it to "at
> least"
>       for variadic functions.
> 
> gcc/cp/ChangeLog:
>       PR c/118112
>       * typeck.cc (error_args_num): Add params "expected_num",
>       "actual_num", and "at_least_p".  Compute "too_many_p" from
> these
>       rather than have it be a param.  Add expected vs actual
> counts to
>       the messages and tweak them for the "at least" case.
>       (convert_arguments): Update calls to error_args_num to pass
> in
>       expected vs actual number, and the "at_least_p", determining
> this
>       for the "too few" case.
> 
> gcc/testsuite/ChangeLog:
>       PR c/118112
>       * c-c++-common/too-few-arguments.c: New test.
>       * c-c++-common/too-many-arguments.c: New test.
>       * g++.dg/cpp0x/variadic169.C: Verify the reported expected
> vs
>       actual argument counts.
>       * g++.dg/modules/macloc-1_c.C: Update regexp for addition of
> param
>       counts to error message.
>       * g++.dg/modules/macloc-1_d.C: Likewise.
> 
> Signed-off-by: David Malcolm <dmalc...@redhat.com>
> ---
>  gcc/c/c-typeck.cc                             | 77 ++++++++++++---
>  gcc/cp/typeck.cc                              | 94 ++++++++++++++---
> -
>  .../c-c++-common/too-few-arguments.c          | 38 ++++++++
>  .../c-c++-common/too-many-arguments.c         | 96
> +++++++++++++++++++
>  gcc/testsuite/g++.dg/cpp0x/variadic169.C      |  2 +-
>  gcc/testsuite/g++.dg/modules/macloc-1_c.C     |  4 +-
>  gcc/testsuite/g++.dg/modules/macloc-1_d.C     |  4 +-
>  7 files changed, 280 insertions(+), 35 deletions(-)
>  create mode 100644 gcc/testsuite/c-c++-common/too-few-arguments.c
>  create mode 100644 gcc/testsuite/c-c++-common/too-many-arguments.c
> 
> diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
> index 902898d1944b..685d490a187f 100644
> --- a/gcc/c/c-typeck.cc
> +++ b/gcc/c/c-typeck.cc
> @@ -3737,14 +3737,30 @@ build_function_call (location_t loc, tree
> function, tree params)
>    return ret;
>  }
>  
> -/* Give a note about the location of the declaration of DECL.  */
> +/* Give a note about the location of the declaration of DECL,
> +   or, failing that, a pertinent declaration for FUNCTION_EXPR.  */
>  
>  static void
> -inform_declaration (tree decl)
> +inform_declaration (tree decl, tree function_expr)
>  {
>    if (decl && (TREE_CODE (decl) != FUNCTION_DECL
>              || !DECL_IS_UNDECLARED_BUILTIN (decl)))
>      inform (DECL_SOURCE_LOCATION (decl), "declared here");
> +  else if (function_expr)
> +    switch (TREE_CODE (function_expr))
> +      {
> +      default:
> +     break;
> +      case COMPONENT_REF:
> +     /* Show the decl of the pertinent field (e.g. for callback
> +        fields in a struct.  */
> +     {
> +       tree field_decl = TREE_OPERAND (function_expr, 1);
> +       if (location_t loc = DECL_SOURCE_LOCATION (field_decl))
> +         inform (loc, "declared here");
> +     }
> +     break;
> +      }
>  }
>  
>  /* C implementation of callback for use when checking param types. 
> */
> @@ -3819,10 +3835,11 @@ build_function_call_vec (location_t loc,
> vec<location_t> arg_loc,
>                 function);
>        else if (DECL_P (function))
>       {
> +       auto_diagnostic_group d;
>         error_at (loc,
>                   "called object %qD is not a function or function
> pointer",
>                   function);
> -       inform_declaration (function);
> +       inform_declaration (function, NULL_TREE);
>       }
>        else
>       error_at (loc,
> @@ -4276,25 +4293,37 @@ convert_arguments (location_t loc,
> vec<location_t> arg_loc, tree fntype,
>  
>        if (type == void_type_node)
>       {
> +       auto_diagnostic_group d;
> +       int num_expected = parmnum;
> +       int num_actual = values->length ();
> +       gcc_rich_location rich_loc (loc);
> +       if (ploc != input_location)
> +         rich_loc.add_range (ploc);
>         if (selector)
> -         error_at (loc, "too many arguments to method %qE",
> selector);
> +         error_at (&rich_loc,
> +                   "too many arguments to method %qE; expected
> %i, have %i",
> +                   selector, num_expected, num_actual);
>         else
> -         error_at (loc, "too many arguments to function %qE",
> function);
> -       inform_declaration (fundecl);
> +         error_at (&rich_loc,
> +                   "too many arguments to function %qE; expected
> %i, have %i",
> +                   function, num_expected, num_actual);
> +       inform_declaration (fundecl, function);
>         return error_args ? -1 : (int) parmnum;
>       }
>  
>        if (builtin_type == void_type_node)
>       {
> +       auto_diagnostic_group d;
>         if (warning_at (loc, OPT_Wbuiltin_declaration_mismatch,
>                         "too many arguments to built-in function
> %qE "
>                         "expecting %d", function, parmnum))
> -         inform_declaration (fundecl);
> +         inform_declaration (fundecl, function);
>         builtin_typetail = NULL_TREE;
>       }
>  
>        if (!typetail && parmnum == 0 && !TYPE_NO_NAMED_ARGS_STDARG_P
> (fntype))
>       {
> +       auto_diagnostic_group d;
>         bool warned;
>         if (selector)
>           warned = warning_at (loc, OPT_Wdeprecated_non_prototype,
> @@ -4307,7 +4336,7 @@ convert_arguments (location_t loc,
> vec<location_t> arg_loc, tree fntype,
>                                " for function %qE declared without
> parameters",
>                                function);
>         if (warned)
> -         inform_declaration (fundecl);
> +         inform_declaration (fundecl, function);
>       }
>  
>        if (selector && argnum > 2)
> @@ -4437,8 +4466,33 @@ convert_arguments (location_t loc,
> vec<location_t> arg_loc, tree fntype,
>  
>    if (typetail != NULL_TREE && TREE_VALUE (typetail) !=
> void_type_node)
>      {
> -      error_at (loc, "too few arguments to function %qE", function);
> -      inform_declaration (fundecl);
> +      /* Not enough args.
> +      Determine minimum number of arguments required.  */
> +      int min_expected_num = 0;
> +      bool at_least_p = false;
> +      tree iter = typelist;
> +      while (true)
> +     {
> +       if (!iter)
> +         {
> +           /* Variadic arguments; stop iterating.  */
> +           at_least_p = true;
> +           break;
> +         }
> +       if (iter == void_list_node)
> +         /* End of arguments; stop iterating.  */
> +         break;
> +       ++min_expected_num;
> +       iter = TREE_CHAIN (iter);
> +     }
> +      auto_diagnostic_group d;
> +      int actual_num = vec_safe_length (values);
> +      error_at (loc,
> +             at_least_p
> +             ? G_("too few arguments to function %qE; expected at
> least %i, have %i")
> +             : G_("too few arguments to function %qE; expected
> %i, have %i"),
> +             function, min_expected_num, actual_num);
> +      inform_declaration (fundecl, function);
>        return -1;
>      }
>  
> @@ -4448,10 +4502,11 @@ convert_arguments (location_t loc,
> vec<location_t> arg_loc, tree fntype,
>        for (tree t = builtin_typetail; t; t = TREE_CHAIN (t))
>       ++nargs;
>  
> +      auto_diagnostic_group d;
>        if (warning_at (loc, OPT_Wbuiltin_declaration_mismatch,
>                     "too few arguments to built-in function %qE "
>                     "expecting %u", function, nargs - 1))
> -     inform_declaration (fundecl);
> +     inform_declaration (fundecl, function);
>      }
>  
>    return error_args ? -1 : (int) parmnum;
> diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
> index 964e549a6122..2966931ca8c1 100644
> --- a/gcc/cp/typeck.cc
> +++ b/gcc/cp/typeck.cc
> @@ -59,7 +59,7 @@ 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);
>  static bool maybe_warn_about_returning_address_of_local (tree,
> location_t = UNKNOWN_LOCATION);
> -static void error_args_num (location_t, tree, bool);
> +static void error_args_num (location_t, tree, int, int, bool);
>  static int convert_arguments (tree, vec<tree, va_gc> **, tree, int,
>                                tsubst_flags_t);
>  static bool is_std_move_p (tree);
> @@ -4533,11 +4533,16 @@ cp_build_function_call_vec (tree function,
> vec<tree, va_gc> **params,
>  }
>  
>  /* Subroutine of convert_arguments.
> -   Print an error message about a wrong number of arguments.  */
> +   Print an error message about a wrong number of arguments.
> +   If AT_LEAST_P is true, then EXPECTED_NUM is the minimum number
> +   of expected arguments.  */
>  
>  static void
> -error_args_num (location_t loc, tree fndecl, bool too_many_p)
> +error_args_num (location_t loc, tree fndecl, int expected_num, int
> actual_num,
> +             bool at_least_p)
>  {
> +  gcc_assert (expected_num != actual_num);
> +  const bool too_many_p = actual_num > expected_num;
>    if (fndecl)
>      {
>        auto_diagnostic_group d;
> @@ -4548,22 +4553,28 @@ error_args_num (location_t loc, tree fndecl,
> bool too_many_p)
>                 == DECL_NAME (TYPE_NAME (DECL_CONTEXT (fndecl)))))
>           error_at (loc,
>                     too_many_p
> -                   ? G_("too many arguments to constructor %q#D")
> -                   : G_("too few arguments to constructor %q#D"),
> -                   fndecl);
> +                   ? G_("too many arguments to constructor %q#D;
> expected %i, have %i")
> +                   : (at_least_p
> +                      ? G_("too few arguments to constructor
> %q#D; expected at least %i, have %i")
> +                      : G_("too few arguments to constructor
> %q#D; expected %i, have %i")),
> +                   fndecl, expected_num, actual_num);
>         else
>           error_at (loc,
>                     too_many_p
> -                   ? G_("too many arguments to member function
> %q#D")
> -                   : G_("too few arguments to member function
> %q#D"),
> -                   fndecl);
> +                   ? G_("too many arguments to member function
> %q#D; expected %i, have %i")
> +                   : (at_least_p
> +                      ? G_("too few arguments to member function
> %q#D; expected at least %i, have %i")
> +                      : G_("too few arguments to member function
> %q#D; expected %i, have %i")),
> +                   fndecl, expected_num, actual_num);
>       }
>        else
>       error_at (loc,
>                 too_many_p
> -               ? G_("too many arguments to function %q#D")
> -               : G_("too few arguments to function %q#D"),
> -               fndecl);
> +               ? G_("too many arguments to function %q#D;
> expected %i, have %i")
> +               : (at_least_p
> +                  ? G_("too few arguments to function %q#D;
> expected at least %i, have %i")
> +                  : G_("too few arguments to function %q#D;
> expected %i, have %i")),
> +               fndecl, expected_num, actual_num);
>        if (!DECL_IS_UNDECLARED_BUILTIN (fndecl))
>       inform (DECL_SOURCE_LOCATION (fndecl), "declared here");
>      }
> @@ -4572,12 +4583,19 @@ error_args_num (location_t loc, tree fndecl,
> bool too_many_p)
>        if (c_dialect_objc ()  &&  objc_message_selector ())
>       error_at (loc,
>                 too_many_p
> -               ? G_("too many arguments to method %q#D")
> -               : G_("too few arguments to method %q#D"),
> -               objc_message_selector ());
> +               ? G_("too many arguments to method %q#D; expected
> %i, have %i")
> +               : (at_least_p
> +                  ? G_("too few arguments to method %q#D;
> expected at least %i, have %i")
> +                  : G_("too few arguments to method %q#D;
> expected %i, have %i")),
> +               objc_message_selector (), expected_num,
> actual_num);
>        else
> -     error_at (loc, too_many_p ? G_("too many arguments to
> function")
> -                               : G_("too few arguments to
> function"));
> +     error_at (loc,
> +               too_many_p
> +               ? G_("too many arguments to function; expected %i,
> have %i")
> +               : (at_least_p
> +                  ? G_("too few arguments to function; expected
> at least %i, have %i")
> +                  : G_("too few arguments to function; expected
> %i, have %i")),
> +               expected_num, actual_num);
>      }
>  }
>  
> @@ -4607,6 +4625,10 @@ convert_arguments (tree typelist, vec<tree,
> va_gc> **values, tree fndecl,
>    /* Argument passing is always copy-initialization.  */
>    flags |= LOOKUP_ONLYCONVERTING;
>  
> +  /* Preserve actual number of arguments passed (without counting
> default
> +     args), in case we need to complain about too many/few.  */
> +  int actual_num = vec_safe_length (*values);
> +
>    for (i = 0, typetail = typelist;
>         i < vec_safe_length (*values);
>         i++)
> @@ -4621,7 +4643,10 @@ convert_arguments (tree typelist, vec<tree,
> va_gc> **values, tree fndecl,
>       {
>            if (complain & tf_error)
>              {
> -           error_args_num (input_location, fndecl,
> /*too_many_p=*/true);
> +           /* Too many args.  */
> +           int expected_num = i;
> +           error_args_num (input_location, fndecl, expected_num,
> actual_num,
> +                           false);
>                return i;
>              }
>            else
> @@ -4743,7 +4768,38 @@ convert_arguments (tree typelist, vec<tree,
> va_gc> **values, tree fndecl,
>        if (typetail && typetail != void_list_node)
>       {
>         if (complain & tf_error)
> -         error_args_num (input_location, fndecl,
> /*too_many_p=*/false);
> +         {
> +           /* Not enough args.
> +              Determine minimum number of arguments required.  */
> +           int min_expected_num = 0;
> +           bool at_least_p = false;
> +           tree iter = typelist;
> +           while (true)
> +             {
> +               if (!iter)
> +                 {
> +                   /* Variadic arguments; stop iterating.  */
> +                   at_least_p = true;
> +                   break;
> +                 }
> +               if (iter == void_list_node)
> +                 /* End of arguments; stop iterating.  */
> +                 break;
> +               if (fndecl && TREE_PURPOSE (iter)
> +                   && TREE_CODE (TREE_PURPOSE (iter)) !=
> DEFERRED_PARSE)
> +                 {
> +                   /* Found a default argument; skip this one
> when
> +                      counting minimum required.  */
> +                   at_least_p = true;
> +                   iter = TREE_CHAIN (iter);
> +                   continue;
> +                 }
> +               ++min_expected_num;
> +               iter = TREE_CHAIN (iter);
> +             }
> +           error_args_num (input_location, fndecl,
> +                           min_expected_num, actual_num,
> at_least_p);
> +         }
>         return -1;
>       }
>      }
> diff --git a/gcc/testsuite/c-c++-common/too-few-arguments.c
> b/gcc/testsuite/c-c++-common/too-few-arguments.c
> new file mode 100644
> index 000000000000..633dccfeaf24
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/too-few-arguments.c
> @@ -0,0 +1,38 @@
> +extern void fn_a (void);
> +extern void fn_b (int); /* { dg-message "declared here" } */
> +extern void fn_c (int, int); /* { dg-message "declared here" } */
> +#ifdef __cplusplus
> +extern void fn_d (int, int=42); /* { dg-message "declared here" "" {
> target c++ } } */
> +extern void fn_e (int, int=42, int=1066); /* { dg-message "declared
> here" "" { target c++ } } */
> +#endif
> +extern void fn_f (const char *, ...); /* { dg-message "declared
> here" } */
> +
> +void test_known_fn (void)
> +{
> +  fn_a ();
> +  fn_b ();  /* { dg-error "too few arguments to function
> '\[^\n\r\]*'; expected 1, have 0" } */
> +  fn_c (42);/* { dg-error "too few arguments to function
> '\[^\n\r\]*'; expected 2, have 1" } */
> +#ifdef __cplusplus
> +  fn_d ();  /* { dg-error "too few arguments to function
> '\[^\n\r\]*'; expected at least 1, have 0" "" { target c++ } } */
> +  fn_e ();  /* { dg-error "too few arguments to function
> '\[^\n\r\]*'; expected at least 1, have 0" "" { target c++ } } */
> +#endif
> +  fn_f ();  /* { dg-error "too few arguments to function
> '\[^\n\r\]*'; expected at least 1, have 0" } */
> +}
> +
> +struct foo
> +{
> +  void (*callback_a) (void);
> +  void (*callback_b) (int); /* { dg-message "declared here" "" {
> target c } } */
> +  void (*callback_c) (int, int); /* { dg-message "declared here" ""
> { target c } } */
> +};
> +
> +void test_callback (struct foo *f)
> +{
> +  f->callback_a ();
> +  
> +  f->callback_b (); /* { dg-error "too few arguments to function 'f-
> >callback_b'; expected 1, have 0" "" { target c } } */
> +  /* { dg-error "too few arguments to function; expected 1, have 0"
> "" { target c++ } .-1 } */
> +
> +  f->callback_c (42); /* { dg-error "too few arguments to function
> 'f->callback_c'; expected 2, have 1" "" { target c } } */
> +  /* { dg-error "too few arguments to function; expected 2, have 1"
> "" { target c++ } .-1 } */
> +}
> diff --git a/gcc/testsuite/c-c++-common/too-many-arguments.c
> b/gcc/testsuite/c-c++-common/too-many-arguments.c
> new file mode 100644
> index 000000000000..7f9f8d4870bf
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/too-many-arguments.c
> @@ -0,0 +1,96 @@
> +/* For C, verify that the first excess param is underlined.
> +   For C++ the calls location covers all the params, so we
> +   can't underline individual params.  */
> +/* { dg-additional-options "-fdiagnostics-show-caret" { target c } }
> */
> +
> +extern void fn_a (); /* { dg-message "declared here" } */
> +extern void fn_b (void); /* { dg-message "declared here" } */
> +extern void fn_c (int); /* { dg-message "declared here" } */
> +#ifdef __cplusplus
> +extern void fn_d (int, int=42); /* { dg-message "declared here" "" {
> target c++ } } */
> +#endif
> +
> +void test_known_fn (void)
> +{
> +  fn_a (42); /* { dg-error "too many arguments to function 'fn_a';
> expected 0, have 1" "" { target c } } */
> +  /* { dg-error "too many arguments to function 'void fn_a\\(\\)';
> expected 0, have 1" "" { target c++ } .-1 } */
> +  /* { dg-begin-multiline-output "" }
> +   fn_a (42);
> +   ^~~~  ~~
> +     { dg-end-multiline-output "" { target c } } */
> +  /* { dg-begin-multiline-output "" }
> + extern void fn_a ();
> +             ^~~~
> +     { dg-end-multiline-output "" { target c } } */
> +
> +  fn_b (1776); /* { dg-error "too many arguments to function 'fn_b';
> expected 0, have 1" "" { target c } } */
> +  /* { dg-error "too many arguments to function 'void fn_b\\(\\)';
> expected 0, have 1" "" { target c++ } .-1 } */
> +  /* { dg-begin-multiline-output "" }
> +   fn_b (1776);
> +   ^~~~  ~~~~
> +   { dg-end-multiline-output "" { target c } } */
> +  /* { dg-begin-multiline-output "" }
> + extern void fn_b (void);
> +             ^~~~
> +     { dg-end-multiline-output "" { target c } } */
> +
> +  fn_c (1066, 1649);  /* { dg-error "too many arguments to function
> 'fn_c'; expected 1, have 2" "" { target c } } */
> +  /* { dg-error "too many arguments to function 'void
> fn_c\\(int\\)'; expected 1, have 2" "" { target c++ } .-1 } */
> +  /* { dg-begin-multiline-output "" }
> +   fn_c (1066, 1649);
> +   ^~~~        ~~~~
> +   { dg-end-multiline-output "" { target c } } */
> +  /* { dg-begin-multiline-output "" }
> + extern void fn_c (int);
> +             ^~~~
> +     { dg-end-multiline-output "" { target c } } */
> +
> +#ifdef __cplusplus
> +  fn_d (1066);
> +  fn_d (1066, 1649);
> +  fn_d (1066, 1649, 1776); /* { dg-error "too many arguments to
> function '\[^\n\r\]*'; expected 2, have 3" "" { target c++ } } */
> +#endif
> +}
> +
> +struct foo
> +{
> +  void (*callback_a)(); /* { dg-message "declared here" "" { target
> c } } */
> +  void (*callback_b)(void); /* { dg-message "declared here" "" {
> target c } } */
> +  void (*callback_c)(int); /* { dg-message "declared here" "" {
> target c } } */
> +};
> +
> +void test_callback (struct foo *f)
> +{
> +  f->callback_a (42); /* { dg-error "too many arguments to function
> 'f->callback_a'; expected 0, have 1" "" { target c } } */
> +  /* { dg-error "too many arguments to function; expected 0, have 1"
> "" { target c++ } .-1 } */
> +  /* { dg-begin-multiline-output "" }
> +   f->callback_a (42);
> +   ^              ~~
> +     { dg-end-multiline-output "" { target c } } */
> +  /* { dg-begin-multiline-output "" }
> +   void (*callback_a)();
> +          ^~~~~~~~~~
> +     { dg-end-multiline-output "" { target c } } */
> +  
> +  f->callback_b (1776); /* { dg-error "too many arguments to
> function 'f->callback_b'; expected 0, have 1" "" { target c } } */
> +  /* { dg-error "too many arguments to function; expected 0, have 1"
> "" { target c++ } .-1 } */
> +  /* { dg-begin-multiline-output "" }
> +   f->callback_b (1776);
> +   ^              ~~~~
> +     { dg-end-multiline-output "" { target c } } */
> +  /* { dg-begin-multiline-output "" }
> +   void (*callback_b)(void);
> +          ^~~~~~~~~~
> +     { dg-end-multiline-output "" { target c } } */
> +
> +  f->callback_c (1066, 1649); /* { dg-error "too many arguments to
> function 'f->callback_c'; expected 1, have 2" "" { target c } } */
> +  /* { dg-error "too many arguments to function; expected 1, have 2"
> "" { target c++ } .-1 } */
> +  /* { dg-begin-multiline-output "" }
> +   f->callback_c (1066, 1649);
> +   ^                    ~~~~
> +     { dg-end-multiline-output "" { target c } } */
> +  /* { dg-begin-multiline-output "" }
> +   void (*callback_c)(int);
> +          ^~~~~~~~~~
> +     { dg-end-multiline-output "" { target c } } */
> +}
> diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic169.C
> b/gcc/testsuite/g++.dg/cpp0x/variadic169.C
> index 6858973cd2eb..460bb3b8a193 100644
> --- a/gcc/testsuite/g++.dg/cpp0x/variadic169.C
> +++ b/gcc/testsuite/g++.dg/cpp0x/variadic169.C
> @@ -5,5 +5,5 @@ template<typename ...T> void f(int n = 0, T ...t);
>  
>  int main()
>  {
> -  f<int>();                  // { dg-error "too few arguments" }
> +  f<int>();                  // { dg-error "too few arguments to
> function '\[^\n\r\]*'; expected at least 1, have 0" }
>  }
> diff --git a/gcc/testsuite/g++.dg/modules/macloc-1_c.C
> b/gcc/testsuite/g++.dg/modules/macloc-1_c.C
> index 5865a34687e7..3f980c213814 100644
> --- a/gcc/testsuite/g++.dg/modules/macloc-1_c.C
> +++ b/gcc/testsuite/g++.dg/modules/macloc-1_c.C
> @@ -8,6 +8,6 @@ void gru ()
>    you (1);
>  }
>  
> -// { dg-regexp "\[^\n]*macloc-1_c.C:7:6: error: too many arguments
> to function 'int me@agnes\\(\\)'\nIn module agnes, imported at
> \[^\n]*macloc-1_b.C:8,\nof module edith, imported at \[^\n]*macloc-
> 1_c.C:3:\n\[^\n]*macloc-1_a.C:11:12: note: declared
> here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of macro 'BOB'\n"
> }
> +// { dg-regexp "\[^\n]*macloc-1_c.C:7:6: error: too many arguments
> to function 'int me@agnes\\(\\)'; expected 0, have 1\nIn module
> agnes, imported at \[^\n]*macloc-1_b.C:8,\nof module edith, imported
> at \[^\n]*macloc-1_c.C:3:\n\[^\n]*macloc-1_a.C:11:12: note: declared
> here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of macro 'BOB'\n"
> }
>  
> -// { dg-regexp "\[^\n]*macloc-1_c.C:8:7: error: too many arguments
> to function 'int you@agnes\\(\\)'\nIn module agnes, imported at
> \[^\n]*macloc-1_b.C:8,\nof module edith, imported at \[^\n]*macloc-
> 1_c.C:3:\n\[^\n]*macloc-1_a.C:12:14: note: declared
> here\n\[^\n]*macloc-1_a.C:9:22: note: in definition of macro
> 'KEVIN'\n" }
> +// { dg-regexp "\[^\n]*macloc-1_c.C:8:7: error: too many arguments
> to function 'int you@agnes\\(\\)'; expected 0, have 1\nIn module
> agnes, imported at \[^\n]*macloc-1_b.C:8,\nof module edith, imported
> at \[^\n]*macloc-1_c.C:3:\n\[^\n]*macloc-1_a.C:12:14: note: declared
> here\n\[^\n]*macloc-1_a.C:9:22: note: in definition of macro
> 'KEVIN'\n" }
> diff --git a/gcc/testsuite/g++.dg/modules/macloc-1_d.C
> b/gcc/testsuite/g++.dg/modules/macloc-1_d.C
> index 282a31c4a2d1..56c001fc3f83 100644
> --- a/gcc/testsuite/g++.dg/modules/macloc-1_d.C
> +++ b/gcc/testsuite/g++.dg/modules/macloc-1_d.C
> @@ -9,5 +9,5 @@ void margo ()
>    gru (2);
>  }
>  
> -// { dg-regexp "\[^\n]*macloc-1_d.C:8:6: error: too many arguments
> to function 'int me@agnes\\(\\)'\nIn module agnes, imported at
> \[^\n]*macloc-1_d.C:4:\n\[^\n]*macloc-1_a.C:11:12: note: declared
> here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of macro 'BOB'\n"
> }
> -// { dg-regexp "\[^\n]*macloc-1_d.C:9:7: error: too many arguments
> to function 'void gru@edith\\(\\)'\nIn module edith, imported at
> \[^\n]*macloc-1_d.C:3:\n\[^\n]*macloc-1_b.C:10:20: note: declared
> here\n\[^\n]*macloc-1_b.C:6:19: note: in definition of macro
> 'STUART'\n" }
> +// { dg-regexp "\[^\n]*macloc-1_d.C:8:6: error: too many arguments
> to function 'int me@agnes\\(\\)'; expected 0, have 1\nIn module
> agnes, imported at \[^\n]*macloc-1_d.C:4:\n\[^\n]*macloc-1_a.C:11:12:
> note: declared here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of
> macro 'BOB'\n" }
> +// { dg-regexp "\[^\n]*macloc-1_d.C:9:7: error: too many arguments
> to function 'void gru@edith\\(\\)'; expected 0, have 1\nIn module
> edith, imported at \[^\n]*macloc-1_d.C:3:\n\[^\n]*macloc-1_b.C:10:20:
> note: declared here\n\[^\n]*macloc-1_b.C:6:19: note: in definition of
> macro 'STUART'\n" }

Reply via email to