Created attachment 55039 [details] preprocessed_source Hi! I was compiling some reduced version of some nasty code I found in a project, to see what GCC has to say about it. I'm not sure if it has defined behavior or not, according to strict-aliasing rules. That code managed to get GCC on its knees :) $ cat flexi.c #include <stddef.h> #include <stdlib.h> #include <stdio.h> #include <string.h> union u { char base[0]; ptrdiff_t off; }; struct s { int x; union u u[0]; }; int main(void) { char *p; struct s *s; s = malloc(sizeof(struct s) + sizeof(union u) * 2 + sizeof("foo") + sizeof("bar")); p = (void *) s + sizeof(struct s) + sizeof(union u) * 2; s->u[0].off = p - s->u[0].base; p = stpcpy(p, "foo") + 1; s->u[1].off = p - s->u[1].base; p = stpcpy(p, "bar") + 1; puts(s->u[0].base + s->u[0].off); puts(s->u[1].base + s->u[1].off); } $ gcc-12 -Wall -Wextra -Werror -fanalyzer -O3 flexi.c $ ./a.out foo bar $ gcc-13 -Wall -Wextra -Werror -fanalyzer -O3 flexi.c -freport-bug during IPA pass: analyzer flexi.c: In function ‘main’: flexi.c:34:36: internal compiler error: in make, at analyzer/store.cc:132 34 | puts(s->u[1].base + s->u[1].off); | ~~~~~~~^~~~ 0xcec8a5 ana::binding_key::make(ana::store_manager*, ana::region const*) ../../src/gcc/analyzer/store.cc:132 0xcf9533 ana::binding_cluster::get_binding(ana::store_manager*, ana::region const*) const ../../src/gcc/analyzer/store.cc:1567 0xcf95eb ana::binding_cluster::get_binding_recursive(ana::store_manager*, ana::region const*) const ../../src/gcc/analyzer/store.cc:1604 0xd05e49 ana::binding_cluster::get_any_binding(ana::store_manager*, ana::region const*) const ../../src/gcc/analyzer/store.cc:1627 0xcd45f7 ana::region_model::get_store_value(ana::region const*, ana::region_model_context*) const ../../src/gcc/analyzer/region-model.cc:2407 0xcd4e72 ana::region_model::get_rvalue(ana::path_var, ana::region_model_context*) const ../../src/gcc/analyzer/region-model.cc:2297 0xcd6a5c ana::region_model::on_assignment(gassign const*, ana::region_model_context*) ../../src/gcc/analyzer/region-model.cc:1156 0xcdc2da ana::exploded_node::on_stmt(ana::exploded_graph&, ana::supernode const*, gimple const*, ana::program_state*, ana::uncertainty_t*, ana::path_context*) ../../src/gcc/analyzer/engine.cc:1471 0xcdc877 ana::exploded_graph::process_node(ana::exploded_node*) ../../src/gcc/analyzer/engine.cc:4063 0xcdd8b9 ana::exploded_graph::process_worklist() ../../src/gcc/analyzer/engine.cc:3466 0xcddc57 ana::impl_run_checkers(ana::logger*) ../../src/gcc/analyzer/engine.cc:6125 0xcde4ff ana::run_checkers() ../../src/gcc/analyzer/engine.cc:6213 0xcde54b execute ../../src/gcc/analyzer/analyzer-pass.cc:87 Please submit a full bug report, with preprocessed source. Please include the complete backtrace with any bug report. See <file:///usr/share/doc/gcc-13/README.Bugs> for instructions. Preprocessed source stored into /tmp/ccZKUz79.out file, please attach this to your bugreport. You'll find attached the file produced by GCC, as per its own instructions.
Please use this: Reported-by: Alejandro Colomar <alx@nginx.com>
Here's a simplified version that will cause the same internal compiler error. This one will probably cause less brain damage to readers, as it has significantly less magic. $ cat flexi2.c #include <stddef.h> #include <stdlib.h> #include <stdio.h> #include <string.h> struct s { int x; ptrdiff_t off[0]; }; int main(void) { char *p; struct s *s; s = malloc(sizeof(struct s) + sizeof(ptrdiff_t) * 2 + sizeof("foo") + sizeof("bar")); p = (void *) s + sizeof(struct s) + sizeof(ptrdiff_t) * 2; s->off[0] = p - (char *) s; p = stpcpy(p, "foo") + 1; s->off[1] = p - (char *) s; p = stpcpy(p, "bar") + 1; puts((char *) s + s->off[0]); puts((char *) s + s->off[1]); } $ gcc-12 -Wall -Wextra -Werror -fanalyzer -O3 flexi2.c $ ./a.out foo bar $ gcc-13 -Wall -Wextra -Werror -O3 flexi2.c $ ./a.out foo bar $ gcc-13 -Wall -Wextra -Werror -fanalyzer -O3 flexi2.c during IPA pass: analyzer flexi2.c: In function ‘main’: flexi2.c:29:33: internal compiler error: in make, at analyzer/store.cc:132 29 | puts((char *) s + s->off[1]); | ~~~~~~^~~ 0xcec8a5 ana::binding_key::make(ana::store_manager*, ana::region const*) ../../src/gcc/analyzer/store.cc:132 0xcf9533 ana::binding_cluster::get_binding(ana::store_manager*, ana::region const*) const ../../src/gcc/analyzer/store.cc:1567 0xcf95eb ana::binding_cluster::get_binding_recursive(ana::store_manager*, ana::region const*) const ../../src/gcc/analyzer/store.cc:1604 0xd05e49 ana::binding_cluster::get_any_binding(ana::store_manager*, ana::region const*) const ../../src/gcc/analyzer/store.cc:1627 0xcd45f7 ana::region_model::get_store_value(ana::region const*, ana::region_model_context*) const ../../src/gcc/analyzer/region-model.cc:2407 0xcd4e72 ana::region_model::get_rvalue(ana::path_var, ana::region_model_context*) const ../../src/gcc/analyzer/region-model.cc:2297 0xcd6a5c ana::region_model::on_assignment(gassign const*, ana::region_model_context*) ../../src/gcc/analyzer/region-model.cc:1156 0xcdc2da ana::exploded_node::on_stmt(ana::exploded_graph&, ana::supernode const*, gimple const*, ana::program_state*, ana::uncertainty_t*, ana::path_context*) ../../src/gcc/analyzer/engine.cc:1471 0xcdc877 ana::exploded_graph::process_node(ana::exploded_node*) ../../src/gcc/analyzer/engine.cc:4063 0xcdd8b9 ana::exploded_graph::process_worklist() ../../src/gcc/analyzer/engine.cc:3466 0xcddc57 ana::impl_run_checkers(ana::logger*) ../../src/gcc/analyzer/engine.cc:6125 0xcde4ff ana::run_checkers() ../../src/gcc/analyzer/engine.cc:6213 0xcde54b execute ../../src/gcc/analyzer/analyzer-pass.cc:87 Please submit a full bug report, with preprocessed source (by using -freport-bug). Please include the complete backtrace with any bug report. See <file:///usr/share/doc/gcc-13/README.Bugs> for instructions. I didn't attach the preprocessed source of this simplified example, since I guess it would be repetitive with the previous one.
Hmm, I should have used offsetof(3) in a few placed to avoid issues due to padding, but I was lucky :).
(In reply to Alejandro Colomar from comment #3) > Hmm, I should have used offsetof(3) in a few placed to avoid issues due to > padding, but I was lucky :). Oh, no, I didn't need it. I got it right. Never mind.
Thanks for filing this bug report. (In reply to Alejandro Colomar from comment #2) > Here's a simplified version that will cause the same internal compiler error. Trunk (GCC 14): ok: https://godbolt.org/z/4cjf6Khh3 GCC 13.2: ICE: https://godbolt.org/z/K4j97a4eb GCC 12.3: ok: https://godbolt.org/z/1jfz8YTPj ...so it seems like this is fixed on trunk (for GCC 14) but still affects GCC 13.
Thanks for fixing it! Would you mind showing which commit fixed this? I'm curious about it. I searched in the git log, but nothing mentioned this bug number. Now I can come to my original intent, which is asking if this code is supported by GCC, as in Does this code have defined behavior under GCC? Does it need and -f flags to be defined? Or is it just undefined behavior? I ask because this code exists in a real project.
GCC 13.3 is being released, retargeting bugs to GCC 13.4.