On Fri, Jan 03, 2025 at 10:46:27PM +0100, Jakub Jelinek wrote:
> Hi!
>
> The following testcase ICEs due to re-entering diagnostics.
> When diagnosing -Wformat-security warning, we try to print instantiation
> context, which calls tsubst with tf_none, but that in the end calls
> cp_build_function_call_vec which calls check_function_arguments which
> diagnoses another warning (again -Wformat-security).
>
> The other check_function_arguments caller, build_over_call, doesn't call
> that function if !(complain & tf_warning), so I think the best fix is
> to do it the same in cp_build_function_call_vec as well.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
LGTM. I was going to say we could also check warn_nonnull etc. before
calling check_function_arguments, as build_over_call does so that we
don't do unnecessary work if we're not going to warn but I see:
/* check_function_restrict sets the DECL_READ_P for arguments
so it must be called unconditionally. */
warned_p |= check_function_restrict (fndecl, fntype, nargs, argarray);
except that I don't see where it actually sets DECL_READ_P...
> 2025-01-03 Jakub Jelinek <[email protected]>
>
> PR c++/117825
> * typeck.cc (cp_build_function_call_vec): Don't call
> check_function_arguments if complain doesn't have tf_warning bit set.
>
> * g++.dg/warn/pr117825.C: New test.
>
> --- gcc/cp/typeck.cc.jj 2025-01-02 11:47:10.437498434 +0100
> +++ gcc/cp/typeck.cc 2025-01-03 18:30:06.530525112 +0100
> @@ -4513,9 +4513,11 @@ cp_build_function_call_vec (tree functio
>
> /* Check for errors in format strings and inappropriately
> null parameters. */
> - bool warned_p = check_function_arguments (input_location, fndecl, fntype,
> - nargs, argarray, NULL,
> - cp_comp_parm_types);
> + bool warned_p
> + = ((complain & tf_warning)
> + && check_function_arguments (input_location, fndecl, fntype,
> + nargs, argarray, NULL,
> + cp_comp_parm_types));
>
> ret = build_cxx_call (function, nargs, argarray, complain, orig_fndecl);
>
> --- gcc/testsuite/g++.dg/warn/pr117825.C.jj 2025-01-03 18:43:07.110516278
> +0100
> +++ gcc/testsuite/g++.dg/warn/pr117825.C 2025-01-03 18:42:29.384048457
> +0100
> @@ -0,0 +1,18 @@
> +// PR c++/117825
> +// { dg-do compile { target c++17 } }
> +// { dg-options "-Wformat -Wformat-security" }
> +
> +__attribute__((format (printf, 1, 2)))
> +int fails (const char *, ...) { return 0; }
> +
> +template <auto func, typename... Args>
> +auto wrap (Args... args) -> decltype (func (args...))
> +{
> + return func (args...); // { dg-warning "format not a string literal
> and no format arguments" }
> +}
> +
> +int
> +main ()
> +{
> + wrap<fails> ("Test!");
> +}
Marek