https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116098
--- Comment #15 from Laria Chabowski <laria at laria dot me> --- (In reply to Andrew Pinski from comment #14) > Fixed so far on the trunk. Thank you! That fixed the test cases I provided. However, when I tested it against the code where I stumbled upon this, I still got an unexpected result. Essentially the same idea: A function truthy() that switches over the type enum, returns the bool value if it's bool or always false if the type is nil or true in all other cases. Then, inverting it and saving and reading it as a value struct again, some garbage comes out and when using the resulting bool in a ternary, the opposite of the expected happens. I've reduced that code to this: ======= BEGIN test.c ======= int puts(const char *); struct Value { enum value_type { VALUE_NIL, VALUE_BOOLEAN, VALUE_MAGIC, } type; union { _Bool boolean; void *p[2]; }; }; static struct Value s_item_mem; static void set_bool(_Bool b) { s_item_mem = (struct Value) { .type = VALUE_BOOLEAN, .boolean = b, }; } static void set_magic(void) { s_item_mem = (struct Value) { .type = VALUE_MAGIC, .p[0] = (void *)0x7fff0123456789a0, // just something that vaguely looks // like a pointer. In the original, // this was a valid pointer returned // from malloc. But since this // reduced code never reads from // here it shouldn't matter that // it's not an actual address. }; } static struct Value val_get(void) { // returning s_item_mem immediately makes the bug go away struct Value value = s_item_mem; return value; } static _Bool truthy(void) { // Inlinig val_get makes the bug go away struct Value value = val_get(); switch (value.type) { case VALUE_NIL: // Removing this case makes the bug go away return 0; case VALUE_BOOLEAN: return value.boolean; default: return 1; } } int main(void) { set_magic(); // sets type to VALUE_MAGIC set_bool(!truthy()); // truthy should take default case, so // set_bool(!1) -> set_bool(0) _Bool b = truthy(); // Should be 0 now puts(b ? "true" : "false"); // Should print false, prints true return b ? 0 : 1; // Exit code should be 1, is 161 } ======= END test.c ======= I built it with: gcc -Wall -Werror -Wextra -pedantic -O2 -fno-strict-aliasing -fwrapv \ -fno-aggressive-loop-optimizations test.c Happens both with the GCC installed on my Fedora 40 machine: $ gcc -v Using built-in specs. COLLECT_GCC=/usr/bin/gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/14/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-redhat-linux Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,m2,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-libstdcxx-backtrace --with-libstdcxx-zoneinfo=/usr/share/zoneinfo --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-14.2.1-20240801/obj-x86_64-redhat-linux/isl-install --enable-offload-targets=nvptx-none,amdgcn-amdhsa --enable-offload-defaulted --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 14.2.1 20240801 (Red Hat 14.2.1-1) (GCC) And with the one I built a couple of days ago from the git trunk, that includes the fix (HEAD was at ce5f2dc45038c9806088132cc923b13719f48732 when I built it. git log from here includes the commit ceda727dafba6 with the fix): $ ~/local/gcc/usr/local/bin/x86_64-linux-gcc -v Using built-in specs. COLLECT_GCC=/home/laria/local/gcc/usr/local/bin/x86_64-linux-gcc COLLECT_LTO_WRAPPER=/home/laria/local/gcc/usr/local/bin/../libexec/gcc/x86_64-linux/15.0.0/lto-wrapper Target: x86_64-linux Configured with: ../configure --target=x86_64-linux --disable-multilib Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 15.0.0 20240903 (experimental) (GCC) Also reproducible on godbolt.org, which apparently uses this version for trunk: g++ (Compiler-Explorer-Build-gcc-1735917cee41fe680d9dd3c0c26b45520c17413a-binutils-2.42) 15.0.0 20240906 (experimental) Please let me know if I can provide any more info.