Skip to content

Commit b67c16f

Browse files
committed
Verifier: Disallow uses of intrinsic global variables
appendToGlobalCtors implicitly assumes this is the case, since it deletes and recreates without trying to update any uses. This ran into an interesting problem in a few linker tests. During the link, ConstantExpr casts were speculatively created to replace any uses that might need them for replacement. These unused ConstantExprs would hang around and still appear on the use list. It seems like a bug that those stick around, but I'm not sure where those are supposed to be cleaned up. Avoid this by not creating the casts for appending linkage. Delete one of the casts entirely as it breaks no tests. The verifier has enforced a specific type for these since 2011, so I don't see why we would need to handle linking modules with a wrong types. One test does fail without the second cast (Linker/appending-global-proto.ll, added by D95126). This test looks contrived; it's using appending linkage with a regular variable. The LangRef suggests this is illegal (and suggests another missing verifier check).
1 parent b4993be commit b67c16f

File tree

5 files changed

+70
-0
lines changed

5 files changed

+70
-0
lines changed

llvm/lib/IR/Verifier.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,9 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
729729
GV.getName() == "llvm.global_dtors")) {
730730
Check(!GV.hasInitializer() || GV.hasAppendingLinkage(),
731731
"invalid linkage for intrinsic global variable", &GV);
732+
Check(GV.materialized_use_empty(),
733+
"invalid uses of intrinsic global variable", &GV);
734+
732735
// Don't worry about emitting an error for it not being an array,
733736
// visitGlobalValue will complain on appending non-array.
734737
if (ArrayType *ATy = dyn_cast<ArrayType>(GV.getValueType())) {
@@ -755,6 +758,9 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
755758
GV.getName() == "llvm.compiler.used")) {
756759
Check(!GV.hasInitializer() || GV.hasAppendingLinkage(),
757760
"invalid linkage for intrinsic global variable", &GV);
761+
Check(GV.materialized_use_empty(),
762+
"invalid uses of intrinsic global variable", &GV);
763+
758764
Type *GVType = GV.getValueType();
759765
if (ArrayType *ATy = dyn_cast<ArrayType>(GVType)) {
760766
PointerType *PTy = dyn_cast<PointerType>(ATy->getElementType());
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@v = weak global i8 1
2+
@llvm.used = appending global [2 x ptr] [ptr @foo, ptr @v]
3+
4+
define void @foo() {
5+
ret void
6+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; RUN: opt -module-summary %s -o %t.bc
2+
; RUN: opt -module-summary %p/Inputs/funcimport_appending_global_used.ll -o %t2.bc
3+
; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
4+
5+
; Do the import now
6+
; RUN: llvm-link %t.bc -summary-index=%t3.thinlto.bc -import=foo:%t2.bc -S | FileCheck %s
7+
8+
; Test case where the verifier would fail if checking use_empty
9+
; instead of materialized_use_empty on llvm.used.
10+
11+
; CHECK: @llvm.used = appending global [1 x ptr] [ptr @f]
12+
13+
declare void @f()
14+
@llvm.used = appending global [1 x ptr] [ptr @f]
15+
16+
define i32 @main() {
17+
entry:
18+
call void @foo()
19+
ret i32 0
20+
}
21+
22+
declare void @foo()
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
; CHECK: invalid uses of intrinsic global variable
4+
; CHECK-NEXT: ptr @llvm.global_ctors
5+
@llvm.global_ctors = appending global [1 x { i32, ptr, ptr } ] [
6+
{ i32, ptr, ptr } { i32 65535, ptr null, ptr null }
7+
]
8+
9+
; CHECK: invalid uses of intrinsic global variable
10+
; CHECK-NEXT: ptr @llvm.global_dtors
11+
@llvm.global_dtors = appending global [1 x { i32, ptr, ptr } ] [
12+
{ i32, ptr, ptr } { i32 65535, ptr null, ptr null }
13+
]
14+
15+
@ctor_user = global ptr @llvm.global_ctors
16+
@dtor_user = global ptr @llvm.global_dtors

llvm/test/Verifier/used-uses.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
; CHECK: invalid uses of intrinsic global variable
4+
; CHECK-NEXT: ptr @llvm.used
5+
@llvm.used = appending global [1 x ptr] [ptr @foo]
6+
7+
; CHECK: invalid uses of intrinsic global variable
8+
; CHECK-NEXT: ptr @llvm.compiler.used
9+
@llvm.compiler.used = appending global [1 x ptr] [ptr @bar]
10+
11+
define void @foo() {
12+
ret void
13+
}
14+
15+
define void @bar() {
16+
ret void
17+
}
18+
19+
@used_user = global ptr @llvm.used
20+
@compiler_used_user = global ptr @llvm.compiler.used

0 commit comments

Comments
 (0)