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

            Bug ID: 93298
           Summary: GCC 10.0 non-current union member access
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msl0000023508 at gmail dot com
  Target Milestone: ---

I'm not sure whether this test program is valid, but here it is:

$ cat test-case.c 
extern int printf(const char *, ...);

union {
        unsigned int m1;
        unsigned short int m2;
} a;
unsigned int *const b = &a.m1;
unsigned short *c = &a.m2;

int main() {
        int i;
        for(i = 0; i < 5; i++) {
                *b = 0;
                (*c)++;
        }
        printf("%u\n", a.m1);
        printf("%hu\n", a.m2);
        return 0;
}
$ gcc-10-20200110 -v
Using built-in specs.
COLLECT_GCC=gcc-10-20200110
COLLECT_LTO_WRAPPER=/opt/gcc-10-20200110/bin/../lib/gcc/x86_64-unknown-freebsd11/10.0.0/lto-wrapper
Target: x86_64-unknown-freebsd11
Configured with: ../gcc-10-20200110/configure --build=x86_64-unknown-freebsd11
--prefix=/usr/local --sysconfdir=/etc --localstatedir=/var
--libexecdir='/usr/local/lib' --enable-version-specific-runtime-libs
--disable-rpath --with-system-zlib
--enable-languages=c,c++,objc,obj-c++,fortran,lto --enable-plugin
--enable-initfini-array --enable-gnu-indirect-function
--program-suffix=-10-20200110
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.0.0 20200110 (experimental) (GCC) 
$ gcc-10-20200110 -Wall -Wextra -O2 test-case.c 
$ ./a.out 
0
5
$ gcc-10-20200110 -Wall -Wextra -O1 test-case.c
$ ./a.out
1
1


I has been read C90 and C99 for information of reading non-current member in an
union; it seems the value would be 'unspecified' by the C99.
While C90 says:
> if a member of a union object is accessed after a value has been stored in a 
> different member of the object, the behavior is implementation-defined.

I tried to use C90 mode to compile the program, but got same result:

$ gcc-10-20200110 -Wall -Wextra -std=c90 -O2 test-case.c
$ ./a.out
0
5
$ gcc-10-20200110 -Wall -Wextra -std=c90 -O1 test-case.c
$ ./a.out
1
1
$ gcc-10-20200110 -Wall -Wextra -std=c90 -Os test-case.c
$ ./a.out
0
5

Reply via email to