public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/100804] New: storage order swapped with specific opt
@ 2021-05-27 18:23 george.thopas at gmail dot com
  2021-05-27 19:29 ` [Bug c/100804] " pinskia at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: george.thopas at gmail dot com @ 2021-05-27 18:23 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 100804
           Summary: storage order swapped with specific opt
           Product: gcc
           Version: 11.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: george.thopas at gmail dot com
  Target Milestone: ---

/* 
    Target: x86_64-pc-linux-gnu gcc versie 10.2.0 (Gentoo 10.2.0-r4 p5) 

    failing:
    $ gcc -Wall -Wextra -O2 test.c && ./a.out
    Aborted

    passing:
    $ gcc -Wall -Wextra -O3 test.c && ./a.out
    $ gcc -Wall -Wextra -O1 test.c && ./a.out
    $ gcc -Wall -Wextra -O0 test.c && ./a.out

    no fallout with -fno-strict-aliasing -fwrapv    
    problem goes away with adding either 
    -fno-code-hoisting,
    -fno-guess-branch-probability,

    The example includes an unused string structure which seems to affect 
    the problem. The odd thing is that it is never used in this code

    Removing the untaken else path makes the problem go away too 

    Thanks

*/
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

#define BE   __attribute__((scalar_storage_order("big-endian")))

struct _str {
    char str[10];
};
typedef struct _str t_str;

struct _le {
    char  is_val;
    union {
        int   val;
        t_str str;
    } data;
};

typedef struct _le t_le;

union _be_data {
    int   val;
    t_str str;
} BE;

typedef union _be_data t_be_data;

struct _be {
    char      is_val;
    t_be_data data;
} BE;

typedef struct _be t_be;

void validate(t_be * in)
{
    t_le chk = { is_val:1, data: { val:0x12345678 } };
    t_le out = { };

    out.is_val = in->is_val;
    if (out.is_val)
        out.data.val = in->data.val;
    else
        out.data.str = in->data.str;

    if (out.data.val != chk.data.val)
        abort();
}

int main(void)
{
    t_be val = { is_val:1, data: { val:0x12345678 } };
    validate(&val);
    return 0;
}

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

* [Bug c/100804] storage order swapped with specific opt
  2021-05-27 18:23 [Bug c/100804] New: storage order swapped with specific opt george.thopas at gmail dot com
@ 2021-05-27 19:29 ` pinskia at gcc dot gnu.org
  2021-05-27 21:38 ` george.thopas at gmail dot com
  2021-05-27 23:16 ` ebotcazou at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-05-27 19:29 UTC (permalink / raw)
  To: gcc-bugs

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

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

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

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
This is an exact dup of bug 100653.

*** This bug has been marked as a duplicate of bug 100653 ***

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

* [Bug c/100804] storage order swapped with specific opt
  2021-05-27 18:23 [Bug c/100804] New: storage order swapped with specific opt george.thopas at gmail dot com
  2021-05-27 19:29 ` [Bug c/100804] " pinskia at gcc dot gnu.org
@ 2021-05-27 21:38 ` george.thopas at gmail dot com
  2021-05-27 23:16 ` ebotcazou at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: george.thopas at gmail dot com @ 2021-05-27 21:38 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from George Thopas <george.thopas at gmail dot com> ---
After looking at the updated documentation and trying the an update kernel with
warning it still leaves some things open. 

The updated documentation says:

"Moreover, the use of type punning or aliasing to toggle the storage order
is not supported; that is to say, if a given scalar object can be accessed
through distinct types that assign a different storage order to it, then the
behaviour is undefined"

- In my example the new warning fires on a struct only having chars. I don't
see how that is applicable here or how a char array could have a different
storage
order in either big or little endian.  

- Regardless of that fact. That field is also never accessed in my example code 
Al 2 fields of the structs actually read are consistently be (in)
and the one written is (out) le.  The ones compare are of the same type. 

Thanks again

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

* [Bug c/100804] storage order swapped with specific opt
  2021-05-27 18:23 [Bug c/100804] New: storage order swapped with specific opt george.thopas at gmail dot com
  2021-05-27 19:29 ` [Bug c/100804] " pinskia at gcc dot gnu.org
  2021-05-27 21:38 ` george.thopas at gmail dot com
@ 2021-05-27 23:16 ` ebotcazou at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: ebotcazou at gcc dot gnu.org @ 2021-05-27 23:16 UTC (permalink / raw)
  To: gcc-bugs

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

Eric Botcazou <ebotcazou at gcc dot gnu.org> changed:

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

--- Comment #3 from Eric Botcazou <ebotcazou at gcc dot gnu.org> ---
> - In my example the new warning fires on a struct only having chars. I don't
> see how that is applicable here or how a char array could have a different
> storage order in either big or little endian.  

The scalar storage order is a binary property of structures and unions, i.e.
it's either little- or big-endian and there is no third state.

> - Regardless of that fact. That field is also never accessed in my example
> code 
> Al 2 fields of the structs actually read are consistently be (in)
> and the one written is (out) le.  The ones compare are of the same type. 

What the restriction says is that every single scalar in memory must *always*
be accessible with the same storage order in the entire program; if there are
two possible accesses with different storage order, even if not executed, then
the behavior is undefined.  That's clearly the case for:

union _be_data {
    int   val;
    t_str str;
} BE;

since t_str has little-endian scalar storage order.

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

end of thread, other threads:[~2021-05-27 23:16 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-27 18:23 [Bug c/100804] New: storage order swapped with specific opt george.thopas at gmail dot com
2021-05-27 19:29 ` [Bug c/100804] " pinskia at gcc dot gnu.org
2021-05-27 21:38 ` george.thopas at gmail dot com
2021-05-27 23:16 ` ebotcazou 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).