https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77316
--- Comment #4 from Roland Dreier <rbd at debian dot org> --- Discovered this is due to abi-compat, I think. gcc 6 works because abi-compat went from 2 (gcc 5.4) to 8, and the significant break is 6 -> 7: $ g++ -Wabi=6 --std=c++11 -c b.cpp b.cpp: In instantiation of ‘vec<A>::vec(A) [with A = alloc<std::nullptr_t>]’: b.cpp:5:46: required from ‘void vec<A>::operator=(vec<A>) [with A = alloc<std::nullptr_t>; vec<A> = vec<alloc<std::nullptr_t> >]’ b.cpp:16:6: required from here b.cpp:4:3: warning: the mangled name of ‘vec<A>::vec(A) [with A = alloc<std::nullptr_t>]’ changed between -fabi-version=6 (_ZN3vecI5allocIDnEEC1ES2_) and -fabi-version=9 (_ZN3vecI5allocIDnEEC1ES1_) [-Wabi] vec(A) {} ^ b.cpp:4:3: warning: the mangled name of ‘vec<A>::vec(A) [with A = alloc<std::nullptr_t>]’ changed between -fabi-version=6 (_ZN3vecI5allocIDnEEC2ES2_) and -fabi-version=9 (_ZN3vecI5allocIDnEEC2ES1_) [-Wabi] b.cpp:5:8: warning: the mangled name of ‘void vec<A>::operator=(vec<A>) [with A = alloc<std::nullptr_t>; vec<A> = vec<alloc<std::nullptr_t> >]’ changed between -fabi-version=6 (_ZN3vecI5allocIDnEEaSES3_) and -fabi-version=9 (_ZN3vecI5allocIDnEEaSES2_) [-Wabi] void operator=(vec) { vec a(get_allocator()); } ^ So gcc is generating a backward-compatible symbol that happens to collide with a different symbol in the current ABI. Not sure I see a way for this to be fixed, but it's a really unfortunate booby-trap. I guess I can work around it by just building with -Wabi=7 and/or -fabi-compat-version=0.