public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/106119] New: Bogus use-after-free warning triggered by optimizer
@ 2022-06-28 14:28 tom.cosgrove at arm dot com
  2022-06-28 15:37 ` [Bug c/106119] " tom.cosgrove at arm dot com
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: tom.cosgrove at arm dot com @ 2022-06-28 14:28 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106119

            Bug ID: 106119
           Summary: Bogus use-after-free warning triggered by optimizer
           Product: gcc
           Version: 12.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: tom.cosgrove at arm dot com
  Target Milestone: ---

There are a number of bug reports related to -Wuse-after-free - it's not clear
to me if our particular issue has already been captured, so please do close as
duplicate if it has (it seems that the optimiser is moving code around, so
could potentially be a duplicate of
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104215).

Assuming not a duplicate, this should probably be linked to
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104075.


Our self-test code checks to see if two consecutive calloc() calls return the
same value, by storing the pointer value in a uintptr_t integer and comparing
against this value later. When we compile with optimisation (we don't see the
problem with -O0) and with an if-statement later in the code, we get a spurious
use-after-free warning.

We don't get this warning at -O0, or if we remove the if-statement.

We have also confirmed that if we reorder the assignment to the uintptr_t and
the call to free() we consistently DO get the use-after-free warning (as
expected) regardless of optimisation level.


gcc-12 $ uname -a
Linux e120653 5.17.15-1-MANJARO #1 SMP PREEMPT Wed Jun 15 07:09:31 UTC 2022
x86_64 GNU/Linux

gcc-12 $ gcc --version
gcc (GCC) 12.1.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

gcc-12 $ cat foo.c
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

void calloc_self_test( __attribute__ ((unused)) int verbose )
{
    void *buffer1 = calloc( 1, 1 );
    uintptr_t old_buffer1 = (uintptr_t) buffer1;
    free( buffer1 );
    buffer1 = calloc( 1, 1 );
    int same = ( old_buffer1 == (uintptr_t) buffer1 );
    if( verbose )
        printf( "  CALLOC(1 again): passed (%s address)\n",
                same ? "same" : "different" );
    free( buffer1 );
}

No warning at -O0:

gcc-12 $ gcc -O0 -Wall -Wextra -Wformat=2 -Wno-format-nonliteral -o foo -c
foo.c
gcc-12 $

But unexpected warning at -O2:

gcc-12 $ gcc -O2 -Wall -Wextra -Wformat=2 -Wno-format-nonliteral -o foo -c
foo.c
foo.c: In function ‘calloc_self_test’:
foo.c:8:15: warning: pointer ‘buffer1’ may be used after ‘free’
[-Wuse-after-free]
    8 |     uintptr_t old_buffer1 = (uintptr_t) buffer1;
      |               ^~~~~~~~~~~
foo.c:9:5: note: call to ‘free’ here
    9 |     free( buffer1 );
      |     ^~~~~~~~~~~~~~~

Removing the if-statement quashes the warning:

gcc-12 $ perl -ni -e 'print unless /if.*verbose/' foo.c
gcc-12 $ cat foo.c
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

void calloc_self_test( __attribute__ ((unused)) int verbose )
{
    void *buffer1 = calloc( 1, 1 );
    uintptr_t old_buffer1 = (uintptr_t) buffer1;
    free( buffer1 );
    buffer1 = calloc( 1, 1 );
    int same = ( old_buffer1 == (uintptr_t) buffer1 );
        printf( "  CALLOC(1 again): passed (%s address)\n",
                same ? "same" : "different" );
    free( buffer1 );
}

gcc-12 $ gcc -O0 -Wall -Wextra -Wformat=2 -Wno-format-nonliteral -o foo -c
foo.c
gcc-12 $ gcc -O2 -Wall -Wextra -Wformat=2 -Wno-format-nonliteral -o foo -c
foo.c
gcc-12 $


Checking that we always get the error when we swap the assignment and free()
statements:

gcc-12 $ cat bar.c
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

void calloc_self_test( __attribute__ ((unused)) int verbose )
{
    void *buffer1 = calloc( 1, 1 );
    free( buffer1 );
    uintptr_t old_buffer1 = (uintptr_t) buffer1;
    buffer1 = calloc( 1, 1 );
    int same = ( old_buffer1 == (uintptr_t) buffer1 );
    if( verbose )
        printf( "  CALLOC(1 again): passed (%s address)\n",
                same ? "same" : "different" );
    free( buffer1 );
}

gcc-12 $ gcc -O0 -Wall -Wextra -Wformat=2 -Wno-format-nonliteral -o bar -c
bar.c
bar.c: In function ‘calloc_self_test’:
bar.c:9:15: warning: pointer ‘buffer1’ used after ‘free’ [-Wuse-after-free]
    9 |     uintptr_t old_buffer1 = (uintptr_t) buffer1;
      |               ^~~~~~~~~~~
bar.c:8:5: note: call to ‘free’ here
    8 |     free( buffer1 );
      |     ^~~~~~~~~~~~~~~

gcc-12 $ gcc -O2 -Wall -Wextra -Wformat=2 -Wno-format-nonliteral -o bar -c
bar.c
bar.c: In function ‘calloc_self_test’:
bar.c:9:15: warning: pointer ‘buffer1’ used after ‘free’ [-Wuse-after-free]
    9 |     uintptr_t old_buffer1 = (uintptr_t) buffer1;
      |               ^~~~~~~~~~~
bar.c:8:5: note: call to ‘free’ here
    8 |     free( buffer1 );

and we still get the warning (as we would hope) without the if-statement:

gcc-12 $ perl -ni -e 'print unless /if.*verbose/' bar.c
gcc-12 $ cat bar.c
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

void calloc_self_test( __attribute__ ((unused)) int verbose )
{
    void *buffer1 = calloc( 1, 1 );
    free( buffer1 );
    uintptr_t old_buffer1 = (uintptr_t) buffer1;
    buffer1 = calloc( 1, 1 );
    int same = ( old_buffer1 == (uintptr_t) buffer1 );
        printf( "  CALLOC(1 again): passed (%s address)\n",
                same ? "same" : "different" );
    free( buffer1 );
}

gcc-12 $ gcc -O0 -Wall -Wextra -Wformat=2 -Wno-format-nonliteral -o bar -c
bar.c
bar.c: In function ‘calloc_self_test’:
bar.c:9:15: warning: pointer ‘buffer1’ used after ‘free’ [-Wuse-after-free]
    9 |     uintptr_t old_buffer1 = (uintptr_t) buffer1;
      |               ^~~~~~~~~~~
bar.c:8:5: note: call to ‘free’ here
    8 |     free( buffer1 );
      |     ^~~~~~~~~~~~~~~
gcc-12 $ gcc -O2 -Wall -Wextra -Wformat=2 -Wno-format-nonliteral -o bar -c
bar.c
bar.c: In function ‘calloc_self_test’:
bar.c:9:15: warning: pointer ‘buffer1’ used after ‘free’ [-Wuse-after-free]
    9 |     uintptr_t old_buffer1 = (uintptr_t) buffer1;
      |               ^~~~~~~~~~~
bar.c:8:5: note: call to ‘free’ here
    8 |     free( buffer1 );
      |     ^~~~~~~~~~~~~~~

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c/106119] Bogus use-after-free warning triggered by optimizer
  2022-06-28 14:28 [Bug c/106119] New: Bogus use-after-free warning triggered by optimizer tom.cosgrove at arm dot com
@ 2022-06-28 15:37 ` tom.cosgrove at arm dot com
  2022-06-29 13:53 ` tom.cosgrove at arm dot com
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: tom.cosgrove at arm dot com @ 2022-06-28 15:37 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106119

--- Comment #1 from Tom Cosgrove <tom.cosgrove at arm dot com> ---
Note that the command lines just need -Wall, i.e.

gcc-12 $ gcc -O2 -Wall -o foo -c foo.c

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c/106119] Bogus use-after-free warning triggered by optimizer
  2022-06-28 14:28 [Bug c/106119] New: Bogus use-after-free warning triggered by optimizer tom.cosgrove at arm dot com
  2022-06-28 15:37 ` [Bug c/106119] " tom.cosgrove at arm dot com
@ 2022-06-29 13:53 ` tom.cosgrove at arm dot com
  2022-07-11 22:07 ` [Bug tree-optimization/106119] [12/13 Regression] " pinskia at gcc dot gnu.org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: tom.cosgrove at arm dot com @ 2022-06-29 13:53 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106119

--- Comment #2 from Tom Cosgrove <tom.cosgrove at arm dot com> ---
Further addendum:

If you use a `void *` to save the value of the pointer, you don't get the
warning!

See https://gcc.godbolt.org/z/fof8a747z


i.e. this code does not generate the warning:

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

void calloc_self_test( __attribute__ ((unused)) int verbose )
{
    void *buffer1 = calloc( 1, 1 );
    void *old_buffer1 = buffer1;
    free( buffer1 );
    buffer1 = calloc( 1, 1 );
    int same = ( old_buffer1 == buffer1 );
    if( verbose )
        printf( "  CALLOC(1 again): passed (%s address)\n",
                same ? "same" : "different" );
    free( buffer1 );
}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106119] [12/13 Regression] Bogus use-after-free warning triggered by optimizer
  2022-06-28 14:28 [Bug c/106119] New: Bogus use-after-free warning triggered by optimizer tom.cosgrove at arm dot com
  2022-06-28 15:37 ` [Bug c/106119] " tom.cosgrove at arm dot com
  2022-06-29 13:53 ` tom.cosgrove at arm dot com
@ 2022-07-11 22:07 ` pinskia at gcc dot gnu.org
  2022-07-25 15:50 ` rguenth at gcc dot gnu.org
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-07-11 22:07 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106119

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Bogus use-after-free        |[12/13 Regression] Bogus
                   |warning triggered by        |use-after-free warning
                   |optimizer                   |triggered by optimizer
   Target Milestone|---                         |12.2
          Component|c                           |tree-optimization

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106119] [12/13 Regression] Bogus use-after-free warning triggered by optimizer
  2022-06-28 14:28 [Bug c/106119] New: Bogus use-after-free warning triggered by optimizer tom.cosgrove at arm dot com
                   ` (2 preceding siblings ...)
  2022-07-11 22:07 ` [Bug tree-optimization/106119] [12/13 Regression] " pinskia at gcc dot gnu.org
@ 2022-07-25 15:50 ` rguenth at gcc dot gnu.org
  2022-10-17 12:31 ` rguenth at gcc dot gnu.org
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-07-25 15:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106119

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P2
   Last reconfirmed|                            |2022-07-25
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot gnu.org
             Status|UNCONFIRMED                 |ASSIGNED
             Blocks|                            |104075
     Ever confirmed|0                           |1

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
I think we've seen similar issues.  We diagnose

old_buffer1_9 = (long unsigned int) buffer1_7;

so the exceptions for equality compares of the pointer does not trigger.
That is by design (but not all people agree here).

Now, that optimization causes code-motion cannot be avoided so I think the
diagnostic is bad and we should _not_ warn about value uses.  That's something
we can somewhat easily do - but diagnosing at -O0 but not at -O2 seems hard.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104075
[Bug 104075] bogus/missing -Wuse-after-free

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106119] [12/13 Regression] Bogus use-after-free warning triggered by optimizer
  2022-06-28 14:28 [Bug c/106119] New: Bogus use-after-free warning triggered by optimizer tom.cosgrove at arm dot com
                   ` (3 preceding siblings ...)
  2022-07-25 15:50 ` rguenth at gcc dot gnu.org
@ 2022-10-17 12:31 ` rguenth at gcc dot gnu.org
  2022-12-15  0:37 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-10-17 12:31 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106119

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |NEW
           Assignee|rguenth at gcc dot gnu.org         |unassigned at gcc dot gnu.org
                 CC|                            |rguenth at gcc dot gnu.org

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106119] [12/13 Regression] Bogus use-after-free warning triggered by optimizer
  2022-06-28 14:28 [Bug c/106119] New: Bogus use-after-free warning triggered by optimizer tom.cosgrove at arm dot com
                   ` (4 preceding siblings ...)
  2022-10-17 12:31 ` rguenth at gcc dot gnu.org
@ 2022-12-15  0:37 ` pinskia at gcc dot gnu.org
  2023-05-08 12:24 ` [Bug tree-optimization/106119] [12/13/14 " rguenth at gcc dot gnu.org
  2024-03-15  1:23 ` [Bug tree-optimization/106119] [12 " law at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-15  0:37 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106119

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |tony@develop-help.com

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 108115 has been marked as a duplicate of this bug. ***

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106119] [12/13/14 Regression] Bogus use-after-free warning triggered by optimizer
  2022-06-28 14:28 [Bug c/106119] New: Bogus use-after-free warning triggered by optimizer tom.cosgrove at arm dot com
                   ` (5 preceding siblings ...)
  2022-12-15  0:37 ` pinskia at gcc dot gnu.org
@ 2023-05-08 12:24 ` rguenth at gcc dot gnu.org
  2024-03-15  1:23 ` [Bug tree-optimization/106119] [12 " law at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: rguenth at gcc dot gnu.org @ 2023-05-08 12:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106119

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|12.3                        |12.4

--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
GCC 12.3 is being released, retargeting bugs to GCC 12.4.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106119] [12 Regression] Bogus use-after-free warning triggered by optimizer
  2022-06-28 14:28 [Bug c/106119] New: Bogus use-after-free warning triggered by optimizer tom.cosgrove at arm dot com
                   ` (6 preceding siblings ...)
  2023-05-08 12:24 ` [Bug tree-optimization/106119] [12/13/14 " rguenth at gcc dot gnu.org
@ 2024-03-15  1:23 ` law at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: law at gcc dot gnu.org @ 2024-03-15  1:23 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106119

Jeffrey A. Law <law at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[12/13/14 Regression] Bogus |[12 Regression] Bogus
                   |use-after-free warning      |use-after-free warning
                   |triggered by optimizer      |triggered by optimizer
                 CC|                            |law at gcc dot gnu.org

--- Comment #7 from Jeffrey A. Law <law at gcc dot gnu.org> ---
Works with gcc-13 and the trunk.  Adjusting regression markers.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-03-15  1:23 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-28 14:28 [Bug c/106119] New: Bogus use-after-free warning triggered by optimizer tom.cosgrove at arm dot com
2022-06-28 15:37 ` [Bug c/106119] " tom.cosgrove at arm dot com
2022-06-29 13:53 ` tom.cosgrove at arm dot com
2022-07-11 22:07 ` [Bug tree-optimization/106119] [12/13 Regression] " pinskia at gcc dot gnu.org
2022-07-25 15:50 ` rguenth at gcc dot gnu.org
2022-10-17 12:31 ` rguenth at gcc dot gnu.org
2022-12-15  0:37 ` pinskia at gcc dot gnu.org
2023-05-08 12:24 ` [Bug tree-optimization/106119] [12/13/14 " rguenth at gcc dot gnu.org
2024-03-15  1:23 ` [Bug tree-optimization/106119] [12 " law at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).