https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101774
Bug ID: 101774 Summary: using-declaration and typedef alter name for linkage purposes of unnamed struct Product: gcc Version: 12.0 Status: UNCONFIRMED Keywords: link-failure, wrong-code Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- namespace MyISA { typedef struct { } VecReg; } void foo(MyISA::VecReg &); class A { MyISA::VecReg v; public: void test(); }; using MyISA::VecReg; typedef MyISA::VecReg VecReg; void A::test() { foo(v); } GCC compiles this with a call to _Z3fooR6VecReg but the correct mangled name is _Z3fooRN5MyISA6VecRegE (as emitted by Clang and EDG). If you define the function in another TU: namespace MyISA { typedef struct { } VecReg; } void foo(MyISA::VecReg &) { } And try to link them, it fails: /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/crt1.o: in function `_start': (.text+0x24): undefined reference to `main' /usr/bin/ld: /tmp/cc43wYEx.o: in function `A::test()': link.C:(.text+0x14): undefined reference to `foo(VecReg&)' collect2: error: ld returned 1 exit status For the wrong name to be used the using-declaration *and* the typedef must both be present: using MyISA::VecReg; typedef MyISA::VecReg VecReg; If either of those is removed, then the correct mangled name is used.