https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108566
--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Note this is using a GCC extension so this might not be as important. clang mangles the symbol as: _Z5dummyIXtl8wrapper1IdEtlNS1_Ut_Edi9RightNametlNS2_Ut_ELd405ec00000000000EEEEEEvv Which does demangle to: void dummy<wrapper1<double>{wrapper1<double>::{unnamed type#1}{.RightName={unnamed type#1}::{unnamed type#1}{(double)[405ec00000000000]}}}>() If you change it to: ``` template<typename T> struct wrapper1 { union { struct { double hh; double hh1; }; }; }; template<auto tparam> void dummy(){} void uses() { dummy<wrapper1<double>{123.0, 123.0}>(); } ``` clang mangles the symbol as: _Z5dummyIXtl8wrapper1IdEtlNS1_Ut_Edi2hhtlNS2_Ut_ELd405ec00000000000ELd405ec00000000000EEEEEEvv Which demangles as: void dummy<wrapper1<double>{wrapper1<double>::{unnamed type#1}{.hh={unnamed type#1}::{unnamed type#1}{(double)[405ec00000000000], (double)[405ec00000000000]}}}>() But takes the name of the struct from the first field ... Which might be what GCC is trying to do but it fails. Here is a more complex test (wrapper1 does not need to be a template to get the crash): struct wrapper1 { union { struct { union { double hh; double hh1; }; }; }; }; template<auto tparam> void dummy(){} void uses() { dummy<wrapper1{123.0}>(); } clang's mangled named: _Z5dummyIXtl8wrapper1tlNS0_Ut_Edi2hhtlNS1_Ut_EtlNS2_Ut_Edi2hhLd405ec00000000000EEEEEEEvv Which demangles as: void dummy<wrapper1{wrapper1::{unnamed type#1}{.hh={unnamed type#1}::{unnamed type#1}{wrapper1::{unnamed type#1}::{unnamed type#1}{.hh=((double)[405ec00000000000])}}}}>() Notice the use of the first field's name.