public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/112409] New: Structure is not initialized as expected
@ 2023-11-06 16:08 freddy77 at gmail dot com
  2023-11-06 16:11 ` [Bug c/112409] " sjames at gcc dot gnu.org
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: freddy77 at gmail dot com @ 2023-11-06 16:08 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 112409
           Summary: Structure is not initialized as expected
           Product: gcc
           Version: 13.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: freddy77 at gmail dot com
  Target Milestone: ---

I was writing a small network utility till I found a weird behaviour computing
TCP checksums. After some debugging I found that the error disappeared with
either -O1 or -O0. So I reduced the program, trying using multiple GCC versions
and it kept happening.

The final program (stripped down) is:


typedef long unsigned int size_t;

typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;

#define ntohs __builtin_bswap16
#define htonl __builtin_bswap32

static inline unsigned
reduce_cksum(unsigned sum)
{
        return (sum >> 16) + (sum & 0xffffu);
}

static unsigned
cksum(const void *pkt, size_t len, unsigned int start)
{
        const uint16_t *data = (const uint16_t *) pkt;
        unsigned sum = start;

        for (; len >= 2; len -= 2)
                sum += *data++;
        if (len)
                sum += ntohs(*((const uint8_t *)data) << 8);
        sum = reduce_cksum(sum);
        sum = reduce_cksum(sum);
        return sum;
}

static unsigned
tcpdump_flow_new(uint32_t saddr, uint32_t daddr)
{
        struct {
                uint32_t saddr, daddr;
                uint8_t zero, proto;
        } pseudo = { htonl(saddr), htonl(daddr), 0, 6 };
        return cksum(&pseudo, 10, 0);
}

int main(void)
{
        unsigned res = tcpdump_flow_new(0x01020304, 0xa1b2c3d4);
        return res;
}


Using -O2 option and Compiler Explorer (but I tried multiple versions locally)
produced this:


main:
  xor edx, edx
  lea rax, [rsp-12]
  lea rsi, [rsp-2]
.L2:
  movzx ecx, WORD PTR [rax]
  add rax, 2
  add edx, ecx
  cmp rax, rsi
  jne .L2
  mov eax, edx
  movzx edx, dx
  shr eax, 16
  add edx, eax
  mov eax, edx
  movzx edx, dx
  shr eax, 16
  add eax, edx
  ret


It's easy to spot that the constants disappeared from the code and program uses
not initialized memory.

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

* [Bug c/112409] Structure is not initialized as expected
  2023-11-06 16:08 [Bug c/112409] New: Structure is not initialized as expected freddy77 at gmail dot com
@ 2023-11-06 16:11 ` sjames at gcc dot gnu.org
  2023-11-06 16:13 ` pinskia at gcc dot gnu.org
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: sjames at gcc dot gnu.org @ 2023-11-06 16:11 UTC (permalink / raw)
  To: gcc-bugs

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

Sam James <sjames at gcc dot gnu.org> changed:

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

--- Comment #1 from Sam James <sjames at gcc dot gnu.org> ---
You have an aliasing violation with uint8_t <-> uint32_t. Works with
-fno-strict-aliasing.

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

* [Bug c/112409] Structure is not initialized as expected
  2023-11-06 16:08 [Bug c/112409] New: Structure is not initialized as expected freddy77 at gmail dot com
  2023-11-06 16:11 ` [Bug c/112409] " sjames at gcc dot gnu.org
@ 2023-11-06 16:13 ` pinskia at gcc dot gnu.org
  2023-11-06 16:13 ` redi at gcc dot gnu.org
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-11-06 16:13 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I have to double check but I am 99% sure this code is undefined due to alias
violations.

Use either memcpy or -fno-strict-aliasing.

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

* [Bug c/112409] Structure is not initialized as expected
  2023-11-06 16:08 [Bug c/112409] New: Structure is not initialized as expected freddy77 at gmail dot com
  2023-11-06 16:11 ` [Bug c/112409] " sjames at gcc dot gnu.org
  2023-11-06 16:13 ` pinskia at gcc dot gnu.org
@ 2023-11-06 16:13 ` redi at gcc dot gnu.org
  2023-11-06 16:15 ` redi at gcc dot gnu.org
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2023-11-06 16:13 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Frediano Ziglio from comment #0)
> static unsigned
> cksum(const void *pkt, size_t len, unsigned int start)
> {
> 	const uint16_t *data = (const uint16_t *) pkt;
> 	unsigned sum = start;
> 
> 	for (; len >= 2; len -= 2)
> 		sum += *data++;

Right, this is undefined behaviour, because you're reading uint16_t values from
an object that is not a uint16_t.

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

* [Bug c/112409] Structure is not initialized as expected
  2023-11-06 16:08 [Bug c/112409] New: Structure is not initialized as expected freddy77 at gmail dot com
                   ` (2 preceding siblings ...)
  2023-11-06 16:13 ` redi at gcc dot gnu.org
@ 2023-11-06 16:15 ` redi at gcc dot gnu.org
  2023-11-06 16:16 ` freddy77 at gmail dot com
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2023-11-06 16:15 UTC (permalink / raw)
  To: gcc-bugs

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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

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

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
There's a reason that the bug reporting guidelines *and* the banner at the top
of the bug creation form ask you to try -fno-strict-aliasing, and it's easy to
see that the constants are not removed if you use that option. Like the
guidelines and the banner say, if -fno-strict-aliasing makes a difference, your
code is probably not correct.

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

* [Bug c/112409] Structure is not initialized as expected
  2023-11-06 16:08 [Bug c/112409] New: Structure is not initialized as expected freddy77 at gmail dot com
                   ` (3 preceding siblings ...)
  2023-11-06 16:15 ` redi at gcc dot gnu.org
@ 2023-11-06 16:16 ` freddy77 at gmail dot com
  2023-11-06 16:18 ` redi at gcc dot gnu.org
  2023-11-06 17:37 ` freddy77 at gmail dot com
  6 siblings, 0 replies; 8+ messages in thread
From: freddy77 at gmail dot com @ 2023-11-06 16:16 UTC (permalink / raw)
  To: gcc-bugs

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

Frediano Ziglio <freddy77 at gmail dot com> changed:

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

--- Comment #5 from Frediano Ziglio <freddy77 at gmail dot com> ---
But the pointer "passes" through a "void*" conversion, so there should be no
aliasing. Or am I missing something?
So what's the standard C way to avoid this (without using specific compiler
options) ?

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

* [Bug c/112409] Structure is not initialized as expected
  2023-11-06 16:08 [Bug c/112409] New: Structure is not initialized as expected freddy77 at gmail dot com
                   ` (4 preceding siblings ...)
  2023-11-06 16:16 ` freddy77 at gmail dot com
@ 2023-11-06 16:18 ` redi at gcc dot gnu.org
  2023-11-06 17:37 ` freddy77 at gmail dot com
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2023-11-06 16:18 UTC (permalink / raw)
  To: gcc-bugs

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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

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

--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Frediano Ziglio from comment #5)
> But the pointer "passes" through a "void*" conversion, so there should be no
> aliasing. Or am I missing something?

That's not how aliasing works. You can't just cast to void* to change the
effective type of that struct and magically make it valid to read uint16_t
values from it.

> So what's the standard C way to avoid this (without using specific compiler
> options) ?

memcpy

GCC will also allow you to use a union, but the union has to be visible in the
code that performs the type punning.

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

* [Bug c/112409] Structure is not initialized as expected
  2023-11-06 16:08 [Bug c/112409] New: Structure is not initialized as expected freddy77 at gmail dot com
                   ` (5 preceding siblings ...)
  2023-11-06 16:18 ` redi at gcc dot gnu.org
@ 2023-11-06 17:37 ` freddy77 at gmail dot com
  6 siblings, 0 replies; 8+ messages in thread
From: freddy77 at gmail dot com @ 2023-11-06 17:37 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Frediano Ziglio <freddy77 at gmail dot com> ---
Sorry for the noise, thanks for the informations.

I didn't notice banner on top. I went back and I notice it, pretty small and it
looks like a lot of other website banners for technical disruptions or cookies.

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

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

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-06 16:08 [Bug c/112409] New: Structure is not initialized as expected freddy77 at gmail dot com
2023-11-06 16:11 ` [Bug c/112409] " sjames at gcc dot gnu.org
2023-11-06 16:13 ` pinskia at gcc dot gnu.org
2023-11-06 16:13 ` redi at gcc dot gnu.org
2023-11-06 16:15 ` redi at gcc dot gnu.org
2023-11-06 16:16 ` freddy77 at gmail dot com
2023-11-06 16:18 ` redi at gcc dot gnu.org
2023-11-06 17:37 ` freddy77 at gmail 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).