aboutsummaryrefslogtreecommitdiffstats
path: root/lib/IR
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR')
-rw-r--r--lib/IR/Verifier.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp
index 69cb5dc..f7aa79c 100644
--- a/lib/IR/Verifier.cpp
+++ b/lib/IR/Verifier.cpp
@@ -449,6 +449,29 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) {
}
}
+ if (GV.hasName() && (GV.getName() == "llvm.used")) {
+ Assert1(!GV.hasInitializer() || GV.hasAppendingLinkage(),
+ "invalid linkage for intrinsic global variable", &GV);
+ Type *GVType = GV.getType()->getElementType();
+ if (ArrayType *ATy = dyn_cast<ArrayType>(GVType)) {
+ PointerType *PTy = dyn_cast<PointerType>(ATy->getElementType());
+ Assert1(PTy, "wrong type for intrinsic global variable", &GV);
+ if (GV.hasInitializer()) {
+ Constant *Init = GV.getInitializer();
+ ConstantArray *InitArray = dyn_cast<ConstantArray>(Init);
+ Assert1(InitArray, "wrong initalizer for intrinsic global variable",
+ Init);
+ for (unsigned i = 0, e = InitArray->getNumOperands(); i != e; ++i) {
+ Value *V = Init->getOperand(i)->stripPointerCasts();
+ // stripPointerCasts strips aliases, so we only need to check for
+ // variables and functions.
+ Assert1(isa<GlobalVariable>(V) || isa<Function>(V),
+ "invalid llvm.used member", V);
+ }
+ }
+ }
+ }
+
visitGlobalValue(GV);
}