Skip to content

Commit 267a57a

Browse files
committed
[llvm-link] Fix for an assertion when linking global with appending linkage
This patch fixes llvm-link assertion when linking external variable declaration with a definition with appending linkage. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D95126
1 parent 596d534 commit 267a57a

File tree

9 files changed

+96
-31
lines changed

9 files changed

+96
-31
lines changed

llvm/lib/Linker/IRMover.cpp

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,38 @@ static void getArrayElements(const Constant *C,
843843
Expected<Constant *>
844844
IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
845845
const GlobalVariable *SrcGV) {
846+
// Check that both variables have compatible properties.
847+
if (DstGV && !DstGV->isDeclaration() && !SrcGV->isDeclaration()) {
848+
if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage())
849+
return stringErr(
850+
"Linking globals named '" + SrcGV->getName() +
851+
"': can only link appending global with another appending "
852+
"global!");
853+
854+
if (DstGV->isConstant() != SrcGV->isConstant())
855+
return stringErr("Appending variables linked with different const'ness!");
856+
857+
if (DstGV->getAlignment() != SrcGV->getAlignment())
858+
return stringErr(
859+
"Appending variables with different alignment need to be linked!");
860+
861+
if (DstGV->getVisibility() != SrcGV->getVisibility())
862+
return stringErr(
863+
"Appending variables with different visibility need to be linked!");
864+
865+
if (DstGV->hasGlobalUnnamedAddr() != SrcGV->hasGlobalUnnamedAddr())
866+
return stringErr(
867+
"Appending variables with different unnamed_addr need to be linked!");
868+
869+
if (DstGV->getSection() != SrcGV->getSection())
870+
return stringErr(
871+
"Appending variables with different section name need to be linked!");
872+
}
873+
874+
// Do not need to do anything if source is a declaration.
875+
if (SrcGV->isDeclaration())
876+
return DstGV;
877+
846878
Type *EltTy = cast<ArrayType>(TypeMap.get(SrcGV->getValueType()))
847879
->getElementType();
848880

@@ -868,37 +900,13 @@ IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
868900
}
869901

870902
uint64_t DstNumElements = 0;
871-
if (DstGV) {
903+
if (DstGV && !DstGV->isDeclaration()) {
872904
ArrayType *DstTy = cast<ArrayType>(DstGV->getValueType());
873905
DstNumElements = DstTy->getNumElements();
874906

875-
if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage())
876-
return stringErr(
877-
"Linking globals named '" + SrcGV->getName() +
878-
"': can only link appending global with another appending "
879-
"global!");
880-
881907
// Check to see that they two arrays agree on type.
882908
if (EltTy != DstTy->getElementType())
883909
return stringErr("Appending variables with different element types!");
884-
if (DstGV->isConstant() != SrcGV->isConstant())
885-
return stringErr("Appending variables linked with different const'ness!");
886-
887-
if (DstGV->getAlignment() != SrcGV->getAlignment())
888-
return stringErr(
889-
"Appending variables with different alignment need to be linked!");
890-
891-
if (DstGV->getVisibility() != SrcGV->getVisibility())
892-
return stringErr(
893-
"Appending variables with different visibility need to be linked!");
894-
895-
if (DstGV->hasGlobalUnnamedAddr() != SrcGV->hasGlobalUnnamedAddr())
896-
return stringErr(
897-
"Appending variables with different unnamed_addr need to be linked!");
898-
899-
if (DstGV->getSection() != SrcGV->getSection())
900-
return stringErr(
901-
"Appending variables with different section name need to be linked!");
902910
}
903911

904912
SmallVector<Constant *, 16> SrcElements;
@@ -928,9 +936,10 @@ IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
928936

929937
Constant *Ret = ConstantExpr::getBitCast(NG, TypeMap.get(SrcGV->getType()));
930938

931-
Mapper.scheduleMapAppendingVariable(*NG,
932-
DstGV ? DstGV->getInitializer() : nullptr,
933-
IsOldStructor, SrcElements);
939+
Mapper.scheduleMapAppendingVariable(
940+
*NG,
941+
(DstGV && !DstGV->isDeclaration()) ? DstGV->getInitializer() : nullptr,
942+
IsOldStructor, SrcElements);
934943

935944
// Replace any uses of the two global variables with uses of the new
936945
// global.
@@ -983,8 +992,7 @@ Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV,
983992
DGV = nullptr;
984993

985994
// Handle the ultra special appending linkage case first.
986-
assert(!DGV || SGV->hasAppendingLinkage() == DGV->hasAppendingLinkage());
987-
if (SGV->hasAppendingLinkage())
995+
if (SGV->hasAppendingLinkage() || (DGV && DGV->hasAppendingLinkage()))
988996
return linkAppendingVarProto(cast_or_null<GlobalVariable>(DGV),
989997
cast<GlobalVariable>(SGV));
990998

llvm/lib/Linker/LinkModules.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
248248
}
249249

250250
// We always have to add Src if it has appending linkage.
251-
if (Src.hasAppendingLinkage()) {
251+
if (Src.hasAppendingLinkage() || Dest.hasAppendingLinkage()) {
252252
LinkFromSrc = true;
253253
return false;
254254
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@var = appending global [1 x i8* ] undef
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
; RUN: not llvm-link %s %p/Inputs/appending-global.ll -S -o - 2>&1 | FileCheck %s
2+
; RUN: not llvm-link %p/Inputs/appending-global.ll %s -S -o - 2>&1 | FileCheck %s
3+
4+
; Negative test to check that global variable with appending linkage can only be
5+
; linked with another global variable with appending linkage.
6+
7+
; CHECK: can only link appending global with another appending global
8+
9+
@var = global i8* undef
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
; RUN: not llvm-link %s %p/Inputs/appending-global.ll -S -o - 2>&1 | FileCheck %s
2+
; RUN: not llvm-link %p/Inputs/appending-global.ll %s -S -o - 2>&1 | FileCheck %s
3+
4+
; Negative test to check that global variables with appending linkage and
5+
; different constness cannot be linked.
6+
7+
; CHECK: Appending variables linked with different const'ness
8+
9+
@var = appending constant [1 x i8* ] undef
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
; RUN: not llvm-link %s %p/Inputs/appending-global.ll -S -o - 2>&1 | FileCheck %s
2+
; RUN: not llvm-link %p/Inputs/appending-global.ll %s -S -o - 2>&1 | FileCheck %s
3+
4+
; Negative test to check that global variables with appending linkage and
5+
; different element types cannot be linked.
6+
7+
; CHECK: Appending variables with different element types
8+
9+
@var = appending global [1 x i32* ] undef
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
; RUN: not llvm-link %s %p/Inputs/appending-global.ll -S -o - 2>&1 | FileCheck %s
2+
; RUN: not llvm-link %p/Inputs/appending-global.ll %s -S -o - 2>&1 | FileCheck %s
3+
4+
; Negative test to check that global variables with appending linkage and
5+
; different visibility cannot be linked.
6+
7+
; CHECK: Appending variables with different visibility need to be linked
8+
9+
@var = appending hidden global [1 x i32* ] undef
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
; RUN: not llvm-link %s %p/Inputs/appending-global.ll -S -o - 2>&1 | FileCheck %s
2+
; RUN: not llvm-link %p/Inputs/appending-global.ll %s -S -o - 2>&1 | FileCheck %s
3+
4+
; Negative test to check that global variables with appending linkage and
5+
; different sections cannot be linked.
6+
7+
; CHECK: Appending variables with different section name need to be linked
8+
9+
@var = appending global [1 x i32* ] undef, section "dummy"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
; RUN: llvm-link %s %p/Inputs/appending-global.ll -S -o - | FileCheck %s
2+
; RUN: llvm-link %p/Inputs/appending-global.ll %s -S -o - | FileCheck %s
3+
4+
; Checks that we can link global variable with appending linkage with the
5+
; existing external declaration.
6+
7+
; CHECK-DAG: @var = appending global [1 x i8*] undef
8+
; CHECK-DAG: @use = global [1 x i8*] [i8* bitcast ([1 x i8*]* @var to i8*)]
9+
10+
@var = external global i8*
11+
@use = global [1 x i8*] [i8* bitcast (i8** @var to i8*)]

0 commit comments

Comments
 (0)