https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105356
Bug ID: 105356 Summary: Segfault in compiled program caused by premature ternary clause evaluation Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: junk at sigpwr dot com Target Milestone: --- Created attachment 52854 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52854&action=edit .i file for poc Seeing a segfault in what I believe to be valid C, related to premature evaluation of one of the branches of a ternary expression. Works on GCC8, fails on GCC9+. Godbolt version: https://godbolt.org/z/1sTG67n8W Works on: 8.5 Segfaults on: 9.4 10.3 11.2 trunk $ x86_64-unknown-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu-gcc COLLECT_LTO_WRAPPER=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu/libexec/gcc/x86_64-unknown-linux-gnu/11.2.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: /home/danielnelson/toolchain_ng/x86_new/.build/x86_64-unknown-linux-gnu/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-build_pc-linux-gnu --target=x86_64-unknown-linux-gnu --prefix=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu --exec_prefix=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu --with-sysroot=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot --enable-languages=c,c++,fortran,go --with-pkgversion='crosstool-NG 1.25.0_rc1' --enable-__cxa_atexit --enable-libmudflap --disable-libgomp --enable-libssp --enable-libquadmath --enable-libquadmath-support --disable-libsanitizer --enable-libmpx --disable-libstdcxx-verbose --with-gmp=/home/danielnelson/toolchain_ng/x86_new/.build/x86_64-unknown-linux-gnu/buildtools --with-mpfr=/home/danielnelson/toolchain_ng/x86_new/.build/x86_64-unknown-linux-gnu/buildtools --with-mpc=/home/danielnelson/toolchain_ng/x86_new/.build/x86_64-unknown-linux-gnu/buildtools --with-isl=/home/danielnelson/toolchain_ng/x86_new/.build/x86_64-unknown-linux-gnu/buildtools --disable-lto --without-zstd --enable-threads=posix --enable-target-optspace --disable-plugin --disable-nls --with-system-zlib --disable-multilib --with-local-prefix=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot --enable-long-long Thread model: posix Supported LTO compression algorithms: zlib gcc version 11.2.0 (crosstool-NG 1.25.0_rc1) Command line: x86_64-unknown-linux-gnu-gcc --sysroot=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot -O2 -static --save-temps -o test poc.c No errors in GCC output. C file contents: typedef long unsigned int size_t; struct hmap_node { size_t hash; struct hmap_node *next; }; struct hmap { struct hmap_node **buckets; struct hmap_node *one; size_t mask; size_t n; }; struct parent { char *name; struct hmap children; }; struct child { char *name; struct hmap_node hmap_node; }; static inline struct hmap_node * hmap_next__(const struct hmap *hmap, size_t start) { size_t i; for (i = start; i <= hmap->mask; i++) { struct hmap_node *node = hmap->buckets[i]; if (node) { return node; } } return ((void *)0); } static inline struct hmap_node * hmap_first(const struct hmap *hmap) { return hmap_next__(hmap, 0); } static inline struct hmap_node * hmap_next(const struct hmap *hmap, const struct hmap_node *node) { return (node->next ? node->next : hmap_next__(hmap, (node->hash & hmap->mask) + 1)); } void parent_set_children(struct parent *prnt) { struct child *child, *next_child; size_t i; for (((child) = ((typeof(child)) (void *) ((char *) (hmap_first(&prnt->children)) - __builtin_offsetof ( typeof(*(child)) , hmap_node))), 1); (&(child)->hmap_node != ((void *)0) ? ((next_child) = ((typeof(next_child)) (void *) ((char *) (hmap_next(&prnt->children, &(child)->hmap_node)) - __builtin_offsetof ( typeof(*(next_child)) , hmap_node))), 1) : 0); (child) = (next_child)) { asm volatile("nop\r\n"); } } struct parent m; int main(int argc, char** argv) { m.name = "foo"; m.children.buckets = &m.children.one; parent_set_children(&m); return 0; }