On Wed, 23 Feb 2022, Jakub Jelinek wrote:

> Hi!
> 
> The first two testcases show different ways how e.g. the glibc
> _FORTIFY_SOURCE wrappers are implemented, and on Winfinite-recursion-3.c
> the new -Winfinite-recursion warning emits a false positive warning.
> 
> It is a false positive because when a builtin with 2 names is called
> through the __builtin_ name (but not all builtins have a name prefixed
> exactly like that) from extern inline function with gnu_inline semantics,
> it doesn't mean the compiler will ever attempt to use the user inline
> wrapper for the call, the __builtin_ just does what the builtin function
> is expected to do and either expands into some compiler generated code,
> or if the compiler decides to emit a call it will use an actual definition
> of the function, but that is not the extern inline gnu_inline function
> which is never emitted out of line.
> Compared to that, in Winfinite-recursion-5.c the extern inline gnu_inline
> wrapper calls the builtin by the same name as the function's name and in
> that case it is infinite recursion, we actuall try to inline the recursive
> call and also error because the recursion is infinite during inlining;
> without always_inline we wouldn't error but it is still infinite recursion,
> the user has no control on how many recursive calls we actually inline.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2022-02-22  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR c/104633
>       * gimple-warn-recursion.cc (pass_warn_recursion::find_function_exit):
>       Don't warn about calls to corresponding builtin from extern inline
>       gnu_inline wrappers.
> 
>       * gcc.dg/Winfinite-recursion-3.c: New test.
>       * gcc.dg/Winfinite-recursion-4.c: New test.
>       * gcc.dg/Winfinite-recursion-5.c: New test.
> 
> --- gcc/gimple-warn-recursion.cc.jj   2022-01-18 11:58:59.619981528 +0100
> +++ gcc/gimple-warn-recursion.cc      2022-02-22 13:19:43.592644576 +0100
> @@ -112,13 +112,25 @@ pass_warn_recursion::find_function_exit
>         if (!strcmp (name, "siglongjmp"))
>           return true;
>  
> -       if (m_built_in && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
> +       if (m_built_in
> +           && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
>             && m_built_in == DECL_FUNCTION_CODE (fndecl))
>           {
> -           /* The call is being made from the definition of a built-in
> -              (e.g., in a replacement of one) to itself.  */
> -           m_calls->safe_push (stmt);
> -           return false;
> +           const char *cname
> +             = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
> +           /* Don't warn about gnu_inline extern inline function
> +              like strcpy calling __builtin_strcpy, that is fine,
> +              if some call is made (the builtin isn't expanded inline),
> +              a call is made to the external definition.  */
> +           if (!(DECL_DECLARED_INLINE_P (current_function_decl)
> +                 && DECL_EXTERNAL (current_function_decl))
> +               || strcmp (name, cname) == 0)
> +             {
> +               /* The call is being made from the definition of a built-in
> +                  (e.g., in a replacement of one) to itself.  */
> +               m_calls->safe_push (stmt);
> +               return false;
> +             }
>           }
>       }
>  
> --- gcc/testsuite/gcc.dg/Winfinite-recursion-3.c.jj   2022-02-22 
> 13:28:10.345579876 +0100
> +++ gcc/testsuite/gcc.dg/Winfinite-recursion-3.c      2022-02-22 
> 13:25:16.760999396 +0100
> @@ -0,0 +1,18 @@
> +/* PR c/104633 */
> +/* { dg-do compile } */
> +/* { dg-options "-Winfinite-recursion" } */
> +
> +typedef __SIZE_TYPE__ size_t;
> +int memcmp (const void *, const void *, size_t);
> +
> +extern inline __attribute__((always_inline, gnu_inline)) int
> +memcmp (const void *p, const void *q, size_t size)   /* { dg-bogus "infinite 
> recursion detected" } */
> +{
> +  return __builtin_memcmp (p, q, size);                      /* { dg-bogus 
> "recursive call" } */
> +}
> +
> +int
> +foo (const void *p, const void *q, size_t size)
> +{
> +  return memcmp (p, q, size);
> +}
> --- gcc/testsuite/gcc.dg/Winfinite-recursion-4.c.jj   2022-02-22 
> 13:28:13.604534458 +0100
> +++ gcc/testsuite/gcc.dg/Winfinite-recursion-4.c      2022-02-22 
> 13:25:22.552918640 +0100
> @@ -0,0 +1,19 @@
> +/* PR c/104633 */
> +/* { dg-do compile } */
> +/* { dg-options "-Winfinite-recursion" } */
> +
> +typedef __SIZE_TYPE__ size_t;
> +int memcmp (const void *, const void *, size_t);
> +__typeof (memcmp) __memcmp_alias __asm ("memcmp");
> +
> +extern inline __attribute__((always_inline, gnu_inline)) int
> +memcmp (const void *p, const void *q, size_t size)   /* { dg-bogus "infinite 
> recursion detected" } */
> +{
> +  return __memcmp_alias (p, q, size);                        /* { dg-bogus 
> "recursive call" } */
> +}
> +
> +int
> +foo (const void *p, const void *q, size_t size)
> +{
> +  return memcmp (p, q, size);
> +}
> --- gcc/testsuite/gcc.dg/Winfinite-recursion-5.c.jj   2022-02-22 
> 13:28:16.690491449 +0100
> +++ gcc/testsuite/gcc.dg/Winfinite-recursion-5.c      2022-02-22 
> 13:27:13.024378761 +0100
> @@ -0,0 +1,18 @@
> +/* PR c/104633 */
> +/* { dg-do compile } */
> +/* { dg-options "-Winfinite-recursion" } */
> +
> +typedef __SIZE_TYPE__ size_t;
> +int memcmp (const void *, const void *, size_t);
> +
> +extern inline __attribute__((always_inline, gnu_inline)) int
> +memcmp (const void *p, const void *q, size_t size)   /* { dg-warning 
> "infinite recursion detected" } */
> +{                                                    /* { dg-error "inlining 
> failed in call to" "" { target *-*-* } .-1 } */
> +  return memcmp (p, q, size);                                /* { dg-message 
> "recursive call" } */
> +}                                                    /* { dg-message "called 
> from here" "" { target *-*-* } .-1 } */
> +
> +int
> +foo (const void *p, const void *q, size_t size)
> +{
> +  return memcmp (p, q, size);
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)

Reply via email to