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  <ja...@redhat.com>
> 
>       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

Reply via email to