https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91529
Bug ID: 91529 Summary: -fmerge-all-constants leads to corrupt output without inlining Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: fiesh at zefix dot tv Target Milestone: --- (Filed this as C++ but don't think that's the right component.) The following code compiles to a program that behaves as follows: * Compiled with "g++ -std=c++17 -fmerge-all-constants": segfault * Compiled with "g++ -std=c++17 -fmerge-all-constants -O1 -fno-inline": segfault * Compiled with "g++ -std=c++17 -fmerge-all-constants -O1": success * Compiled with "g++ -std=c++17": success It seems that for gcc-7, the program always succeeds, but for gcc-8, gcc-9, and trunk, this behavior shows up. It was reduced from what I believe is valid code using std::variant. template <unsigned long> struct e { }; template <long f> e<f> h; template <typename...> class ad; long bi; struct i { static constexpr bool bm = 0; }; template <typename...> union ap { }; template <typename ag, typename... ah> union ap<ag, ah...> { constexpr ap(e<0>) : aq() {} template <unsigned long af> constexpr ap(e<af>) : bt(h<af - 1>) { } ag aq; ap<ah...> bt; }; template <bool, typename...> struct as; template <typename... bv> struct as<false, bv...> { template <unsigned long af> constexpr as(e<af>) : av(h<af>), aw(af) { } void j() { aw = bi; } ~as() { j(); } ap<bv...> av; int aw; }; template <typename... bv> using az = as<i::bm, bv...>; template <int, typename... bv> struct k : az<bv...> { using bb = az<bv...>; bb::bb; }; template <typename... bv> using ce = k<0, bv...>; template <int, typename... bv> struct m : ce<bv...> { using bb = ce<bv...>; bb::bb; }; template <typename... bv> using be = m<0, bv...>; template <int, typename... bv> struct p : be<bv...> { using bb = be<bv...>; bb::bb; }; template <typename... bv> using bg = p<0, bv...>; template <int, typename... bv> struct q : bg<bv...> { using bb = bg<bv...>; bb::bb; }; template <typename... bv> using ck = q<0, bv...>; template <typename... bv> struct r : ck<bv...> { using bb = ck<bv...>; template <unsigned long af> constexpr r(e<af> s) : bb(s) { } }; template <typename, typename> struct l; template <typename g, typename... bv> struct l<g, ad<bv...>> { static constexpr long c = 1; }; template <typename... bv> class ad : r<bv...> { using bb = r<bv...>; template <typename g> static constexpr long l = l<g, ad>::c; public: template <typename g> constexpr ad(g) : ad(h<l<g>>) { } template <unsigned long af> constexpr ad(e<af>) : bb(h<af>) { } }; template <int> struct n { double d = 1.; }; using ch = ad<int, n<1>>; main() { ch const o{n<0>()}; }