[llvm-branch-commits] [llvm] 267a57a - [llvm-link] Fix for an assertion when linking global with appending linkage

Sergey Dmitriev via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Jan 23 00:35:03 PST 2021


Author: Sergey Dmitriev
Date: 2021-01-23T00:10:42-08:00
New Revision: 267a57a64572cffbb74599878bdcc9f3b678ffa3

URL: https://github.com/llvm/llvm-project/commit/267a57a64572cffbb74599878bdcc9f3b678ffa3
DIFF: https://github.com/llvm/llvm-project/commit/267a57a64572cffbb74599878bdcc9f3b678ffa3.diff

LOG: [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

Added: 
    llvm/test/Linker/Inputs/appending-global.ll
    llvm/test/Linker/appending-global-err1.ll
    llvm/test/Linker/appending-global-err2.ll
    llvm/test/Linker/appending-global-err3.ll
    llvm/test/Linker/appending-global-err4.ll
    llvm/test/Linker/appending-global-err5.ll
    llvm/test/Linker/appending-global-proto.ll

Modified: 
    llvm/lib/Linker/IRMover.cpp
    llvm/lib/Linker/LinkModules.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp
index 5eeba0c0c3e7..6a2f84bb48a0 100644
--- a/llvm/lib/Linker/IRMover.cpp
+++ b/llvm/lib/Linker/IRMover.cpp
@@ -843,6 +843,38 @@ static void getArrayElements(const Constant *C,
 Expected<Constant *>
 IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
                                 const GlobalVariable *SrcGV) {
+  // Check that both variables have compatible properties.
+  if (DstGV && !DstGV->isDeclaration() && !SrcGV->isDeclaration()) {
+    if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage())
+      return stringErr(
+          "Linking globals named '" + SrcGV->getName() +
+          "': can only link appending global with another appending "
+          "global!");
+
+    if (DstGV->isConstant() != SrcGV->isConstant())
+      return stringErr("Appending variables linked with 
diff erent const'ness!");
+
+    if (DstGV->getAlignment() != SrcGV->getAlignment())
+      return stringErr(
+          "Appending variables with 
diff erent alignment need to be linked!");
+
+    if (DstGV->getVisibility() != SrcGV->getVisibility())
+      return stringErr(
+          "Appending variables with 
diff erent visibility need to be linked!");
+
+    if (DstGV->hasGlobalUnnamedAddr() != SrcGV->hasGlobalUnnamedAddr())
+      return stringErr(
+          "Appending variables with 
diff erent unnamed_addr need to be linked!");
+
+    if (DstGV->getSection() != SrcGV->getSection())
+      return stringErr(
+          "Appending variables with 
diff erent section name need to be linked!");
+  }
+
+  // Do not need to do anything if source is a declaration.
+  if (SrcGV->isDeclaration())
+    return DstGV;
+
   Type *EltTy = cast<ArrayType>(TypeMap.get(SrcGV->getValueType()))
                     ->getElementType();
 
@@ -868,37 +900,13 @@ IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
   }
 
   uint64_t DstNumElements = 0;
-  if (DstGV) {
+  if (DstGV && !DstGV->isDeclaration()) {
     ArrayType *DstTy = cast<ArrayType>(DstGV->getValueType());
     DstNumElements = DstTy->getNumElements();
 
-    if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage())
-      return stringErr(
-          "Linking globals named '" + SrcGV->getName() +
-          "': can only link appending global with another appending "
-          "global!");
-
     // Check to see that they two arrays agree on type.
     if (EltTy != DstTy->getElementType())
       return stringErr("Appending variables with 
diff erent element types!");
-    if (DstGV->isConstant() != SrcGV->isConstant())
-      return stringErr("Appending variables linked with 
diff erent const'ness!");
-
-    if (DstGV->getAlignment() != SrcGV->getAlignment())
-      return stringErr(
-          "Appending variables with 
diff erent alignment need to be linked!");
-
-    if (DstGV->getVisibility() != SrcGV->getVisibility())
-      return stringErr(
-          "Appending variables with 
diff erent visibility need to be linked!");
-
-    if (DstGV->hasGlobalUnnamedAddr() != SrcGV->hasGlobalUnnamedAddr())
-      return stringErr(
-          "Appending variables with 
diff erent unnamed_addr need to be linked!");
-
-    if (DstGV->getSection() != SrcGV->getSection())
-      return stringErr(
-          "Appending variables with 
diff erent section name need to be linked!");
   }
 
   SmallVector<Constant *, 16> SrcElements;
@@ -928,9 +936,10 @@ IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
 
   Constant *Ret = ConstantExpr::getBitCast(NG, TypeMap.get(SrcGV->getType()));
 
-  Mapper.scheduleMapAppendingVariable(*NG,
-                                      DstGV ? DstGV->getInitializer() : nullptr,
-                                      IsOldStructor, SrcElements);
+  Mapper.scheduleMapAppendingVariable(
+      *NG,
+      (DstGV && !DstGV->isDeclaration()) ? DstGV->getInitializer() : nullptr,
+      IsOldStructor, SrcElements);
 
   // Replace any uses of the two global variables with uses of the new
   // global.
@@ -983,8 +992,7 @@ Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV,
     DGV = nullptr;
 
   // Handle the ultra special appending linkage case first.
-  assert(!DGV || SGV->hasAppendingLinkage() == DGV->hasAppendingLinkage());
-  if (SGV->hasAppendingLinkage())
+  if (SGV->hasAppendingLinkage() || (DGV && DGV->hasAppendingLinkage()))
     return linkAppendingVarProto(cast_or_null<GlobalVariable>(DGV),
                                  cast<GlobalVariable>(SGV));
 

diff  --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp
index 35d6290e901b..98793c587388 100644
--- a/llvm/lib/Linker/LinkModules.cpp
+++ b/llvm/lib/Linker/LinkModules.cpp
@@ -248,7 +248,7 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
   }
 
   // We always have to add Src if it has appending linkage.
-  if (Src.hasAppendingLinkage()) {
+  if (Src.hasAppendingLinkage() || Dest.hasAppendingLinkage()) {
     LinkFromSrc = true;
     return false;
   }

diff  --git a/llvm/test/Linker/Inputs/appending-global.ll b/llvm/test/Linker/Inputs/appending-global.ll
new file mode 100644
index 000000000000..bd95c41e178d
--- /dev/null
+++ b/llvm/test/Linker/Inputs/appending-global.ll
@@ -0,0 +1 @@
+ at var = appending global [1 x i8* ] undef

diff  --git a/llvm/test/Linker/appending-global-err1.ll b/llvm/test/Linker/appending-global-err1.ll
new file mode 100644
index 000000000000..8bc626d8ef72
--- /dev/null
+++ b/llvm/test/Linker/appending-global-err1.ll
@@ -0,0 +1,9 @@
+; RUN: not llvm-link %s %p/Inputs/appending-global.ll -S -o - 2>&1 | FileCheck %s
+; RUN: not llvm-link %p/Inputs/appending-global.ll %s -S -o - 2>&1 | FileCheck %s
+
+; Negative test to check that global variable with appending linkage can only be
+; linked with another global variable with appending linkage.
+
+; CHECK: can only link appending global with another appending global
+
+ at var = global i8* undef

diff  --git a/llvm/test/Linker/appending-global-err2.ll b/llvm/test/Linker/appending-global-err2.ll
new file mode 100644
index 000000000000..19818a07fcbd
--- /dev/null
+++ b/llvm/test/Linker/appending-global-err2.ll
@@ -0,0 +1,9 @@
+; RUN: not llvm-link %s %p/Inputs/appending-global.ll -S -o - 2>&1 | FileCheck %s
+; RUN: not llvm-link %p/Inputs/appending-global.ll %s -S -o - 2>&1 | FileCheck %s
+
+; Negative test to check that global variables with appending linkage and
+; 
diff erent constness cannot be linked.
+
+; CHECK: Appending variables linked with 
diff erent const'ness
+
+ at var = appending constant [1 x i8* ] undef

diff  --git a/llvm/test/Linker/appending-global-err3.ll b/llvm/test/Linker/appending-global-err3.ll
new file mode 100644
index 000000000000..7f5ba2b31716
--- /dev/null
+++ b/llvm/test/Linker/appending-global-err3.ll
@@ -0,0 +1,9 @@
+; RUN: not llvm-link %s %p/Inputs/appending-global.ll -S -o - 2>&1 | FileCheck %s
+; RUN: not llvm-link %p/Inputs/appending-global.ll %s -S -o - 2>&1 | FileCheck %s
+
+; Negative test to check that global variables with appending linkage and
+; 
diff erent element types cannot be linked.
+
+; CHECK: Appending variables with 
diff erent element types
+
+ at var = appending global [1 x i32* ] undef

diff  --git a/llvm/test/Linker/appending-global-err4.ll b/llvm/test/Linker/appending-global-err4.ll
new file mode 100644
index 000000000000..4416e3cebf5d
--- /dev/null
+++ b/llvm/test/Linker/appending-global-err4.ll
@@ -0,0 +1,9 @@
+; RUN: not llvm-link %s %p/Inputs/appending-global.ll -S -o - 2>&1 | FileCheck %s
+; RUN: not llvm-link %p/Inputs/appending-global.ll %s -S -o - 2>&1 | FileCheck %s
+
+; Negative test to check that global variables with appending linkage and
+; 
diff erent visibility cannot be linked.
+
+; CHECK: Appending variables with 
diff erent visibility need to be linked
+
+ at var = appending hidden global [1 x i32* ] undef

diff  --git a/llvm/test/Linker/appending-global-err5.ll b/llvm/test/Linker/appending-global-err5.ll
new file mode 100644
index 000000000000..fefbee387c0d
--- /dev/null
+++ b/llvm/test/Linker/appending-global-err5.ll
@@ -0,0 +1,9 @@
+; RUN: not llvm-link %s %p/Inputs/appending-global.ll -S -o - 2>&1 | FileCheck %s
+; RUN: not llvm-link %p/Inputs/appending-global.ll %s -S -o - 2>&1 | FileCheck %s
+
+; Negative test to check that global variables with appending linkage and
+; 
diff erent sections cannot be linked.
+
+; CHECK: Appending variables with 
diff erent section name need to be linked
+
+ at var = appending global [1 x i32* ] undef, section "dummy"

diff  --git a/llvm/test/Linker/appending-global-proto.ll b/llvm/test/Linker/appending-global-proto.ll
new file mode 100644
index 000000000000..0234c052798b
--- /dev/null
+++ b/llvm/test/Linker/appending-global-proto.ll
@@ -0,0 +1,11 @@
+; RUN: llvm-link %s %p/Inputs/appending-global.ll -S -o - | FileCheck %s
+; RUN: llvm-link %p/Inputs/appending-global.ll %s -S -o - | FileCheck %s
+
+; Checks that we can link global variable with appending linkage with the
+; existing external declaration.
+
+; CHECK-DAG: @var = appending global [1 x i8*] undef
+; CHECK-DAG: @use = global [1 x i8*] [i8* bitcast ([1 x i8*]* @var to i8*)]
+
+ at var = external global i8*
+ at use = global [1 x i8*] [i8* bitcast (i8** @var to i8*)]


        


More information about the llvm-branch-commits mailing list