Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -256,7 +256,11 @@ // dedup'ed section groups by their signatures. For the -r, we want to pass // through all SHT_GROUP sections without merging them because merging them // creates broken section contents. - if (IS->Type == SHT_GROUP) { + // We also do not merge any SHF_GROUP sections with any others. If we would do + // that we either end up with multiple SHT_GROUP sections containing the + // same output section or with situation when SHF_GROUP section is merged with + // regular section with the same name. Both cases are semantically incorrect. + if (IS->Type == SHT_GROUP || (IS->Flags & SHF_GROUP)) { addSection(IS, OutsecName, nullptr); return; } Index: test/ELF/relocatable-comdat2.s =================================================================== --- test/ELF/relocatable-comdat2.s +++ test/ELF/relocatable-comdat2.s @@ -0,0 +1,35 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld -r %t.o -o %t +# RUN: llvm-readobj -elf-section-groups -s %t | FileCheck %s + +## Check .foo was not merged. +# CHECK: Sections [ +# CHECK: Name: .foo +# CHECK: Name: .foo +# CHECK: Name: .foo + +# CHECK: Groups { +# CHECK-NEXT: Group { +# CHECK-NEXT: Name: .group +# CHECK-NEXT: Index: 2 +# CHECK-NEXT: Type: COMDAT +# CHECK-NEXT: Signature: bar +# CHECK-NEXT: Section(s) in group [ +# CHECK-NEXT: .foo (3) +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: Group { +# CHECK-NEXT: Name: .group +# CHECK-NEXT: Index: 4 +# CHECK-NEXT: Type: COMDAT +# CHECK-NEXT: Signature: zed +# CHECK-NEXT: Section(s) in group [ +# CHECK-NEXT: .foo (5) +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: } + +.section .foo,"axG",@progbits,bar,comdat +.section .foo,"axG",@progbits,zed,comdat +.section .foo,"ax",@progbits