> Am 10.01.2026 um 09:33 schrieb Jakub Jelinek <[email protected]>:
> 
> Hi!
> 
> While gimple_call_combined_fn already do call
> gimple_builtin_call_types_compatible_p and for most of builtins ensures
> the right types of arguments, for type generic builtins it does not,
> from POV of that function those functions are rettype (...).
> Now, while the FE does some number of argument checking for the type
> generic builtins, as the testcase below shows, it can be gamed.
> 
> So, this patch checks the number of arguments for type generic builtins
> and does nothing if they have unexpected number of arguments.
> Also for the returns arg verifies it can access the first argument.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

LGTM 

Richard 

> 2026-01-10  Jakub Jelinek  <[email protected]>
> 
>    PR tree-optimization/123431
>    * gimple-range-op.cc (gimple_range_op_handler::maybe_builtin_call):
>    Punt if type-generic builtins with a single argument don't have
>    exactly one argument.  For returns_arg punt if call doesn't have
>    at least one argument.
> 
>    * gcc.dg/pr123431.c: New test.
> 
> --- gcc/gimple-range-op.cc.jj    2026-01-02 09:56:10.182336262 +0100
> +++ gcc/gimple-range-op.cc    2026-01-09 15:00:01.166808500 +0100
> @@ -1410,6 +1410,8 @@ gimple_range_op_handler::maybe_builtin_c
>   switch (func)
>     {
>     case CFN_BUILT_IN_CONSTANT_P:
> +      if (gimple_call_num_args (call) != 1)
> +    return;
>       m_op1 = gimple_call_arg (call, 0);
>       if (irange::supports_p (TREE_TYPE (m_op1)))
>    m_operator = &op_cfn_constant_p;
> @@ -1420,21 +1422,29 @@ gimple_range_op_handler::maybe_builtin_c
>       break;
> 
>     CASE_FLT_FN (CFN_BUILT_IN_SIGNBIT):
> +      if (gimple_call_num_args (call) != 1)
> +    return;
>       m_op1 = gimple_call_arg (call, 0);
>       m_operator = &op_cfn_signbit;
>       break;
> 
>     CASE_FLT_FN (CFN_BUILT_IN_ISINF):
> +      if (gimple_call_num_args (call) != 1)
> +    return;
>       m_op1 = gimple_call_arg (call, 0);
>       m_operator = &op_cfn_isinf;
>       break;
> 
>     case CFN_BUILT_IN_ISFINITE:
> +      if (gimple_call_num_args (call) != 1)
> +    return;
>       m_op1 = gimple_call_arg (call, 0);
>       m_operator = &op_cfn_isfinite;
>       break;
> 
>     case CFN_BUILT_IN_ISNORMAL:
> +      if (gimple_call_num_args (call) != 1)
> +    return;
>       m_op1 = gimple_call_arg (call, 0);
>       m_operator = &op_cfn_isnormal;
>       break;
> @@ -1565,7 +1575,9 @@ gimple_range_op_handler::maybe_builtin_c
>     default:
>       {
>    unsigned arg;
> -    if (gimple_call_fnspec (call).returns_arg (&arg) && arg == 0)
> +    if (gimple_call_fnspec (call).returns_arg (&arg)
> +        && arg == 0
> +        && gimple_call_num_args (call) > 0)
>      {
>        m_op1 = gimple_call_arg (call, 0);
>        m_operator = &op_cfn_pass_through_arg1;
> --- gcc/testsuite/gcc.dg/pr123431.c.jj    2026-01-09 15:10:58.084406597 +0100
> +++ gcc/testsuite/gcc.dg/pr123431.c    2026-01-09 15:10:20.589057380 +0100
> @@ -0,0 +1,19 @@
> +/* PR tree-optimization/123431 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +extern void foo (int);
> +
> +extern inline __attribute__((always_inline)) void
> +bar (int x, ...)
> +{
> +  if (__builtin_constant_p (__builtin_va_arg_pack ()))
> +    foo (x);
> +}
> +
> +void
> +baz (int x)
> +{
> +  bar (1, 2);
> +  bar (3, x);
> +}
> 
>    Jakub
> 

Reply via email to