public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/110292] New: undefined value due to strict aliasing without warning
@ 2023-06-16 20:55 yann at droneaud dot fr
  2023-06-16 21:03 ` [Bug c/110292] " yann at droneaud dot fr
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: yann at droneaud dot fr @ 2023-06-16 20:55 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 110292
           Summary: undefined value due to strict aliasing without warning
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yann at droneaud dot fr
  Target Milestone: ---

The following code (reduced with some help from cvise) doesn't trigger any
warning from GCC 13+

    $ cat test.c
    #include <stdint.h>

    struct a {
      uint8_t b:6;
    };

    struct c {
      uint64_t d:6;
    };

    void e(uint64_t *f, uint64_t *g) {
      struct c *h = (struct c *)f;
      struct a i[8] = { [7] = { h -> d } };
      __builtin___memcpy_chk (g, i, sizeof(i),
         __builtin_object_size (g, 0));
    }

    int main(void) {
      uint64_t j = 0;
      uint64_t k;
      e(&j, &k);
      if (k)
        __builtin_trap();

      return 0;
    }

But compiled under Fedora 39 (Rawhide, gcc 13.1.1-2, x86_64), it aborts,
because j location on the stack is not set to 0 before its address is being
passed to e() ... 

    $ gcc -Wall -Wextra -O2 test.c -o test
    $ ./test
    Aborted (core dumped)

Even if it doesn't abort (because the stack is cleared), there's a problem and
valgrind reports:

    $ gcc -Wall -Wextra -O2 -g3 test.c -o test
    $ valgrind --track-origins=yes ./test 
    ==63110== Memcheck, a memory error detector
    ==63110== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
    ==63110== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright
info
    ==63110== Command: ./test
    ==63110== 
    ==63110== Conditional jump or move depends on uninitialised value(s)
    ==63110==    at 0x401047: main (test.c:22)
    ==63110==  Uninitialised value was created by a stack allocation
    ==63110==    at 0x401030: main (test.c:18)
   ...

And, as one could see, line 18 doesn't match any of the variables that are
allocated.

Below, the assembly compiled by GCC:
    $ gcc -Wall -Wextra -O2 -g3 test.c -S
    $ cat test.s
    e:
        movzbl  (%rdi), %eax
        andl    $63, %eax
        salq    $56, %rax
        movq    %rax, (%rsi)
        ret
    main:
        subq    $16, %rsp
        leaq    8(%rsp), %rsi
        movq    %rsp, %rdi
        call    e
        cmpq    $0, 8(%rsp)
        jne     .L5
        xorl    %eax, %eax
        addq    $16, %rsp
        ret
    .L5:
        ud2

Code available at https://godbolt.org/z/b8sn314K9

Is it an aliasing issue in the code and GCC doesn't reports a warning ? Or
worse ?

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

* [Bug c/110292] undefined value due to strict aliasing without warning
  2023-06-16 20:55 [Bug c/110292] New: undefined value due to strict aliasing without warning yann at droneaud dot fr
@ 2023-06-16 21:03 ` yann at droneaud dot fr
  2023-06-16 21:07 ` pinskia at gcc dot gnu.org
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: yann at droneaud dot fr @ 2023-06-16 21:03 UTC (permalink / raw)
  To: gcc-bugs

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

Yann Droneaud <yann at droneaud dot fr> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |yann at droneaud dot fr

--- Comment #1 from Yann Droneaud <yann at droneaud dot fr> ---
And it should be noted that using -fsanitize=undefined is making the issue
vanish as 0 is written into j location on the stack ...

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

* [Bug c/110292] undefined value due to strict aliasing without warning
  2023-06-16 20:55 [Bug c/110292] New: undefined value due to strict aliasing without warning yann at droneaud dot fr
  2023-06-16 21:03 ` [Bug c/110292] " yann at droneaud dot fr
@ 2023-06-16 21:07 ` pinskia at gcc dot gnu.org
  2023-06-16 21:27 ` [Bug middle-end/110292] " pinskia at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-06-16 21:07 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
aliasing violations are known not to be warned about nor have a runtime
sanitizer either.

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

* [Bug middle-end/110292] undefined value due to strict aliasing without warning
  2023-06-16 20:55 [Bug c/110292] New: undefined value due to strict aliasing without warning yann at droneaud dot fr
  2023-06-16 21:03 ` [Bug c/110292] " yann at droneaud dot fr
  2023-06-16 21:07 ` pinskia at gcc dot gnu.org
@ 2023-06-16 21:27 ` pinskia at gcc dot gnu.org
  2023-06-16 21:29 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-06-16 21:27 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |WONTFIX

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
So this is IPA modref in action.

  loads:
      Base 0: alias set 1
        Ref 0: alias set 1
          access: Parm 0 param offset:0 offset:0 size:6 max_size:6
  stores:
      Base 0: alias set 0
        Ref 0: alias set 0
          access: Parm 1 param offset:0 offset:0 size:-1 max_size:64



So we know that e only does a store to the second argument (via aliasing set 0
which is the is the root of all aliasing sets) and loads from the first
argument with an aliasing set of 1( in this case it is the aliasing set that is
contained for struct c).

So when DSE comes a long, it removes the store to j as it not used by the e
function as it is in the non-conflicting aliasing set of e.

Note casting does not change aliasing sets even.

In that main could have been:
```
    int main(void) {
      struct c t = {0};
      uint64_t k;
      e((uint64_t*)&t, &k);
      if (k)
        __builtin_trap();

      return 0;
    }
```
And that would have been valid and well defined code.

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

* [Bug middle-end/110292] undefined value due to strict aliasing without warning
  2023-06-16 20:55 [Bug c/110292] New: undefined value due to strict aliasing without warning yann at droneaud dot fr
                   ` (2 preceding siblings ...)
  2023-06-16 21:27 ` [Bug middle-end/110292] " pinskia at gcc dot gnu.org
@ 2023-06-16 21:29 ` pinskia at gcc dot gnu.org
  2023-06-17  5:46 ` yann at droneaud dot fr
  2023-06-17  6:47 ` xry111 at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-06-16 21:29 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|WONTFIX                     |INVALID

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Note -Wstrict-aliasing=1 actually does warn:
<source>: In function 'e':
<source>:13:29: warning: dereferencing type-punned pointer might break
strict-aliasing rules [-Wstrict-aliasing]
   13 |       struct c *h = (struct c *)f;
      |                             ^

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

* [Bug middle-end/110292] undefined value due to strict aliasing without warning
  2023-06-16 20:55 [Bug c/110292] New: undefined value due to strict aliasing without warning yann at droneaud dot fr
                   ` (3 preceding siblings ...)
  2023-06-16 21:29 ` pinskia at gcc dot gnu.org
@ 2023-06-17  5:46 ` yann at droneaud dot fr
  2023-06-17  6:47 ` xry111 at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: yann at droneaud dot fr @ 2023-06-17  5:46 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Yann Droneaud <yann at droneaud dot fr> ---
Hi,

Thanks a lot for the quick analysis of my issue.

(In reply to Andrew Pinski from comment #4)
> Note -Wstrict-aliasing=1 actually does warn:

OK, and -Wall enables -Wstrict-aliasing which defaults to -Wstrict-aliasing=3,
I'm sorry I haven't tried to use lower values ...

https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wstrict-aliasing

(In reply to Andrew Pinski from comment #2)
> aliasing violations are known not to be warned about nor have a runtime
> sanitizer either.

Is there any other tool that would reliably detect such issues ?

Regards

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

* [Bug middle-end/110292] undefined value due to strict aliasing without warning
  2023-06-16 20:55 [Bug c/110292] New: undefined value due to strict aliasing without warning yann at droneaud dot fr
                   ` (4 preceding siblings ...)
  2023-06-17  5:46 ` yann at droneaud dot fr
@ 2023-06-17  6:47 ` xry111 at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: xry111 at gcc dot gnu.org @ 2023-06-17  6:47 UTC (permalink / raw)
  To: gcc-bugs

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

Xi Ruoyao <xry111 at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |xry111 at gcc dot gnu.org

--- Comment #6 from Xi Ruoyao <xry111 at gcc dot gnu.org> ---
(In reply to Yann Droneaud from comment #5)
> Hi,
> 
> Thanks a lot for the quick analysis of my issue.
> 
> (In reply to Andrew Pinski from comment #4)
> > Note -Wstrict-aliasing=1 actually does warn:
> 
> OK, and -Wall enables -Wstrict-aliasing which defaults to
> -Wstrict-aliasing=3,
> I'm sorry I haven't tried to use lower values ...

The problem is -Wstrict-aliasing=1 may produce many false positives, as it's
documented.

> https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wstrict-
> aliasing
> 
> (In reply to Andrew Pinski from comment #2)
> > aliasing violations are known not to be warned about nor have a runtime
> > sanitizer either.
> 
> Is there any other tool that would reliably detect such issues ?

Such issues are obviously impossible to be detected reliably at compile time
(because doing so will need to solve the halting problem).  At runtime LLVM
guys are developing a type sanitizer:
https://discourse.llvm.org/t/reviving-typesanitizer-a-sanitizer-to-catch-type-based-aliasing-violations

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

end of thread, other threads:[~2023-06-17  6:47 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-16 20:55 [Bug c/110292] New: undefined value due to strict aliasing without warning yann at droneaud dot fr
2023-06-16 21:03 ` [Bug c/110292] " yann at droneaud dot fr
2023-06-16 21:07 ` pinskia at gcc dot gnu.org
2023-06-16 21:27 ` [Bug middle-end/110292] " pinskia at gcc dot gnu.org
2023-06-16 21:29 ` pinskia at gcc dot gnu.org
2023-06-17  5:46 ` yann at droneaud dot fr
2023-06-17  6:47 ` xry111 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).