https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94342
--- Comment #6 from Anton <bikineev at google dot com> --- I also don't understand why all the parts of a template instantiation need to be kept in the same COMDAT group. Neither clang nor gcc does it: template <typename T> void Index(int i) { static int VAR1 = i; static int VAR2 = i; } template void Index<int>(int); template void Index<float>(int); This gives: COMDAT group section [ 1] `.group' [void Index<int>(int)] contains 2 sections: [Index] Name [ 14] .text._Z5IndexIiEvi [ 15] .rela.text._Z5IndexIiEvi COMDAT group section [ 2] `.group' [void Index<float>(int)] contains 2 sections: [Index] Name [ 16] .text._Z5IndexIfEvi [ 17] .rela.text._Z5IndexIfEvi COMDAT group section [ 3] `.group' [Index<int>(int)::VAR] contains 1 sections: [Index] Name [ 18] .bss._ZZ5IndexIiEviE3VAR COMDAT group section [ 4] `.group' [guard variable for Index<int>(int)::VAR] contains 1 sections: [Index] Name [ 19] .bss._ZGVZ5IndexIiEviE3VAR COMDAT group section [ 5] `.group' [Index<int>(int)::VAR2] contains 1 sections: [Index] Name [ 20] .bss._ZZ5IndexIiEviE4VAR2 COMDAT group section [ 6] `.group' [guard variable for Index<int>(int)::VAR2] contains 1 sections: [Index] Name [ 21] .bss._ZGVZ5IndexIiEviE4VAR2 COMDAT group section [ 7] `.group' [Index<float>(int)::VAR] contains 1 sections: [Index] Name [ 22] .bss._ZZ5IndexIfEviE3VAR COMDAT group section [ 8] `.group' [guard variable for Index<float>(int)::VAR] contains 1 sections: [Index] Name [ 23] .bss._ZGVZ5IndexIfEviE3VAR COMDAT group section [ 9] `.group' [Index<float>(int)::VAR2] contains 1 sections: [Index] Name [ 24] .bss._ZZ5IndexIfEviE4VAR2 COMDAT group section [ 10] `.group' [guard variable for Index<float>(int)::VAR2] contains 1 sections: [Index] Name [ 25] .bss._ZGVZ5IndexIfEviE4VAR2 I might have misunderstood, but I think that COMDAT groups are orthogonal to section naming.