public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/108448] New: GCC Elides Assignment to Pointer and memcpy
@ 2023-01-18 18:09 gavin at yzena dot com
  2023-01-18 18:15 ` [Bug c/108448] " pinskia at gcc dot gnu.org
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: gavin at yzena dot com @ 2023-01-18 18:09 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 108448
           Summary: GCC Elides Assignment to Pointer and memcpy
           Product: gcc
           Version: 11.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gavin at yzena dot com
  Target Milestone: ---
              Host: x86_64
            Target: x86_64

I have a stack allocator ("stackpool") that can automatically free all data
allocated after entry to a function. To do this, I pass in a pointer to the
function name to be the marker for the function start.

To debug, I also check the function name on exit.

This last item is segfaulting because the function name pointer is NULL. I ran
it through GDB, and the assignment to the allocated pointer ([1]) is skipped
entirely, but only when not compiling in plain Debug mode (CMake). I tried a
memcpy() ([2]), but it is *also* skipped.

I checked for undefined behavior with UBSan. It didn't catch any. I fully
acknowledge that there could be some, though.

To reproduce, run the following:

```
$ git clone https://git.yzena.com/Yzena/Yc.git
$ cd Yc
$ git config --local include.path ./.gitconfig
$ git submodule update --init --recursive
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_COMPILER=<path/to/gcc>
-DYC_ENABLE_STACKTRACES=ON -DYC_ENABLE_LONG_TESTS=ON -DYC_BUILD_DOCS=OFF ..
$ make -j<ncores>
```

If the build fails, you have successfully reproduced the problem because there
is a program that uses that code used as part of the build (to generate a test
file). The program is `tests/strgen` (produced from `tests/strgen.c`), and the
command-line it runs is something like:

```
$ tests/container/../strgen tests/container/kjvbible.txt
tests/container/kjvbible.c kjvbible_array 1
```

To pre-emptively answer some questions: the function name pointer that is
passed in to `y_stackpool_enterFunc()` (the one with the elided assignment) is
not NULL, and neither is the stackpool.

But again, I wouldn't be surprised if there's some UB somewhere that is giving
GCC the "right" to elide this assignment. I just can't find where because I'm
not as expert in C as the GCC authors.

[1]:
https://git.yzena.com/Yzena/Yc/src/commit/6afdc86bd2c17f98b2f9e97e79e37fdf8c6b7708/src/alloc/stackpool.c#L441

[2]:
https://git.yzena.com/Yzena/Yc/src/commit/c9a855a0b6d9c5758e4d605977bdf571830132a2/src/alloc/stackpool.c#L442-L443

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

* [Bug c/108448] GCC Elides Assignment to Pointer and memcpy
  2023-01-18 18:09 [Bug c/108448] New: GCC Elides Assignment to Pointer and memcpy gavin at yzena dot com
@ 2023-01-18 18:15 ` pinskia at gcc dot gnu.org
  2023-01-18 18:16 ` [Bug middle-end/108448] " pinskia at gcc dot gnu.org
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-01-18 18:15 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2023-01-18
             Status|UNCONFIRMED                 |WAITING

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
https://gcc.gnu.org/bugs/#dontwant
What we do not want
...
* The location (URL) of the package that failed to build (we won't download it,
anyway, since you've already given us what we need to duplicate the bug,
haven't you? :-)

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

* [Bug middle-end/108448] GCC Elides Assignment to Pointer and memcpy
  2023-01-18 18:09 [Bug c/108448] New: GCC Elides Assignment to Pointer and memcpy gavin at yzena dot com
  2023-01-18 18:15 ` [Bug c/108448] " pinskia at gcc dot gnu.org
@ 2023-01-18 18:16 ` pinskia at gcc dot gnu.org
  2023-01-18 18:22 ` gavin at yzena dot com
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-01-18 18:16 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Have you tried -fno-strict-aliasing ? I have a feeling like you have some
aliasing issues in this code ...

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

* [Bug middle-end/108448] GCC Elides Assignment to Pointer and memcpy
  2023-01-18 18:09 [Bug c/108448] New: GCC Elides Assignment to Pointer and memcpy gavin at yzena dot com
  2023-01-18 18:15 ` [Bug c/108448] " pinskia at gcc dot gnu.org
  2023-01-18 18:16 ` [Bug middle-end/108448] " pinskia at gcc dot gnu.org
@ 2023-01-18 18:22 ` gavin at yzena dot com
  2023-01-18 18:29 ` pinskia at gcc dot gnu.org
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: gavin at yzena dot com @ 2023-01-18 18:22 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Gavin Howard <gavin at yzena dot com> ---
> Have you tried -fno-strict-aliasing ? I have a feeling like you have some aliasing issues in this code ...

Just tried it, same thing happens.

I'll try to make a better test case, but in this case, the bug happens deep in
the startup of a custom runtime that touches many files and sets up its own
version of stdio. I'll probably just amalgamate all of the required files
together. I know the policy, but the URL really is the best way to reproduce
easily.

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

* [Bug middle-end/108448] GCC Elides Assignment to Pointer and memcpy
  2023-01-18 18:09 [Bug c/108448] New: GCC Elides Assignment to Pointer and memcpy gavin at yzena dot com
                   ` (2 preceding siblings ...)
  2023-01-18 18:22 ` gavin at yzena dot com
@ 2023-01-18 18:29 ` pinskia at gcc dot gnu.org
  2023-01-18 18:44 ` gavin at yzena dot com
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-01-18 18:29 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Does it work at -O0?
Does -fsanitizer=address -fsanitizer=undefined report anything?

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

* [Bug middle-end/108448] GCC Elides Assignment to Pointer and memcpy
  2023-01-18 18:09 [Bug c/108448] New: GCC Elides Assignment to Pointer and memcpy gavin at yzena dot com
                   ` (3 preceding siblings ...)
  2023-01-18 18:29 ` pinskia at gcc dot gnu.org
@ 2023-01-18 18:44 ` gavin at yzena dot com
  2023-01-19  5:51 ` gavin at yzena dot com
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: gavin at yzena dot com @ 2023-01-18 18:44 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Gavin Howard <gavin at yzena dot com> ---
As mentioned, it works at -O0, and UBSan reports nothing until the segfault.
ASan also reports nothing. Valgrind also reports nothing. They all report
nothing at -O0 and -O2.

I keep my code clean of such things during development, which is one reason I
am so confused.

I'll get the amalgamation to you, but it will take me some hours to do so.

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

* [Bug middle-end/108448] GCC Elides Assignment to Pointer and memcpy
  2023-01-18 18:09 [Bug c/108448] New: GCC Elides Assignment to Pointer and memcpy gavin at yzena dot com
                   ` (4 preceding siblings ...)
  2023-01-18 18:44 ` gavin at yzena dot com
@ 2023-01-19  5:51 ` gavin at yzena dot com
  2023-01-19  6:03 ` pinskia at gcc dot gnu.org
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: gavin at yzena dot com @ 2023-01-19  5:51 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Gavin Howard <gavin at yzena dot com> ---
Created attachment 54302
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54302&action=edit
An Amalgamation to Reproduce

I have managed to make an amalgamation that reproduces the bug. When you unzip
the attachment, you should get `amal.c`.

Run the following:

```
$ gcc -std=c11 -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -D_GNU_SOURCE
-DYC_BUILTIN_128=1 -DYC_ENABLE_STACKTRACES=1 -O2 -g -o amal amal.c
$ ./amal amal.c temp.txt temp 1
```

You should get an assert failure as follows:

```
Assert Failed: pointer is NULL
    Expected:  (stack != ((void *)0))
    Source:    yc/src/concurrency/strucon.c:439
    Function:  y_strucon_handleErrorHelper()

Aborted
```

This file was produced from a source file with the `strgen` main, a function it
needed, and a bunch of `#include` of C files that were needed. The original was
`amalgamation.c`, and I ran the following command on it:

```
$ gcc -Iyc/include -std=c11 -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700
-D_GNU_SOURCE -DYC_BUILTIN_128=1 -E amalgamation.c > amal.c
```

(It was created in the directory above the repo directory.)

This created the `amal.c` file that I have attached.

The line 63558 has the pointer assignment. The next line has the memcpy()
commented out. Either one is elided. You can comment out 63558 and uncomment
the next to test.

If you add ASan and UBSan, like so:

```
$ gcc -std=c11 -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -D_GNU_SOURCE
-DYC_BUILTIN_128=1 -DYC_ENABLE_STACKTRACES=1 -O2 -g -o amal amal.c
```

they report nothing. In fact, they then make the program work.

(The "Encountered end-of-file" is a bug in the original that didn't suppress
EOF as an error; just ignore it because it's not really an error.)

If you run Valgrind on the non-ASan/UBSan build, like so:

```
$ valgrind --error-exitcode=100 --leak-check=full --show-leak-kinds=all
--errors-for-leak-kinds=all --num-callers=500 --child-silent-after-fork=yes
./amal amal.c temp.txt temp 1
```

It also reports nothing until the abort.

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

* [Bug middle-end/108448] GCC Elides Assignment to Pointer and memcpy
  2023-01-18 18:09 [Bug c/108448] New: GCC Elides Assignment to Pointer and memcpy gavin at yzena dot com
                   ` (5 preceding siblings ...)
  2023-01-19  5:51 ` gavin at yzena dot com
@ 2023-01-19  6:03 ` pinskia at gcc dot gnu.org
  2023-01-19 15:29 ` gavin at yzena dot com
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-01-19  6:03 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I do notice some aliasing violations with y_map_index and
y_strucon_handleErrorHelper


 y_vec* stack;
...
      y_map_existsStringKey_v(d->contexts, ("com.yzena.yc.error_handler"),
                              &stack))
...

y_map_existsStringKey_v takes a void* and passes it to:
 ret = (y_map_index(m, &str,
# 896 "yc/src/container/map.c" 3 4
                            ((void *)0)
# 896 "yc/src/container/map.c"
                                , val_ptr) != ((y_usize) -1));


While y_map_index's last argument is y_uchar** and you do the store as y_uchar*
inside y_map_index:
   *val_ptr = ((m)->map[(arrayIdx)] + (itemIdx) * (m->esize));

------ CUT -----

I suspect cmake didn't add -fno-strict-aliasing really.

Can you try:
   *(void**)val_ptr = ((m)->map[(arrayIdx)] + (itemIdx) * (m->esize));


Note GCC extends aliasing here where "void*" is treated similarly as a
character type with respect to aliasing.

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

* [Bug middle-end/108448] GCC Elides Assignment to Pointer and memcpy
  2023-01-18 18:09 [Bug c/108448] New: GCC Elides Assignment to Pointer and memcpy gavin at yzena dot com
                   ` (6 preceding siblings ...)
  2023-01-19  6:03 ` pinskia at gcc dot gnu.org
@ 2023-01-19 15:29 ` gavin at yzena dot com
  2023-01-19 15:36 ` gavin at yzena dot com
  2023-01-23 22:33 ` gavin at yzena dot com
  9 siblings, 0 replies; 11+ messages in thread
From: gavin at yzena dot com @ 2023-01-19 15:29 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from Gavin Howard <gavin at yzena dot com> ---
Created attachment 54310
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54310&action=edit
Amalgamation with License Header

Not important for the bug, but I reuploaded the amalgamation with its proper
license header. Sorry; need to do this for legal reasons.

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

* [Bug middle-end/108448] GCC Elides Assignment to Pointer and memcpy
  2023-01-18 18:09 [Bug c/108448] New: GCC Elides Assignment to Pointer and memcpy gavin at yzena dot com
                   ` (7 preceding siblings ...)
  2023-01-19 15:29 ` gavin at yzena dot com
@ 2023-01-19 15:36 ` gavin at yzena dot com
  2023-01-23 22:33 ` gavin at yzena dot com
  9 siblings, 0 replies; 11+ messages in thread
From: gavin at yzena dot com @ 2023-01-19 15:36 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #9 from Gavin Howard <gavin at yzena dot com> ---
> I suspect cmake didn't add -fno-strict-aliasing really.

It did. I ran the build under `intercept-build` and looked at the
`compile_commands.json` output. It had the `-fno-strict-aliasing` for every
file.

Anyway, I do not like your solution since it has a `void**`, the legality of
which is dubious, but I tried it in `amal.c`, both with and without strict
aliasing. (And I know it had `-fno-strict-aliasing` because I did the
command-line by hand.)

Both times still resulted in the failure. I even tried changing the `val_ptr`
argument to be a `y_uchar*`, since that aliases everything, and it still
failed, with and without strict aliasing.

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

* [Bug middle-end/108448] GCC Elides Assignment to Pointer and memcpy
  2023-01-18 18:09 [Bug c/108448] New: GCC Elides Assignment to Pointer and memcpy gavin at yzena dot com
                   ` (8 preceding siblings ...)
  2023-01-19 15:36 ` gavin at yzena dot com
@ 2023-01-23 22:33 ` gavin at yzena dot com
  9 siblings, 0 replies; 11+ messages in thread
From: gavin at yzena dot com @ 2023-01-23 22:33 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #10 from Gavin Howard <gavin at yzena dot com> ---
I have confirmed that the GCC bug (if it is a bug) also exists in 12.2.1, at
least using the amal.c I have attached.

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

end of thread, other threads:[~2023-01-23 22:33 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-18 18:09 [Bug c/108448] New: GCC Elides Assignment to Pointer and memcpy gavin at yzena dot com
2023-01-18 18:15 ` [Bug c/108448] " pinskia at gcc dot gnu.org
2023-01-18 18:16 ` [Bug middle-end/108448] " pinskia at gcc dot gnu.org
2023-01-18 18:22 ` gavin at yzena dot com
2023-01-18 18:29 ` pinskia at gcc dot gnu.org
2023-01-18 18:44 ` gavin at yzena dot com
2023-01-19  5:51 ` gavin at yzena dot com
2023-01-19  6:03 ` pinskia at gcc dot gnu.org
2023-01-19 15:29 ` gavin at yzena dot com
2023-01-19 15:36 ` gavin at yzena dot com
2023-01-23 22:33 ` gavin at yzena dot com

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).