summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r--llvm/lib/IR/Verifier.cpp64
1 files changed, 50 insertions, 14 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 64d7575b8a1..165f745b506 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -432,8 +432,7 @@ private:
// Module-level debug info verification...
void verifyTypeRefs();
template <class MapTy>
- void verifyBitPieceExpression(const DbgInfoIntrinsic &I,
- const MapTy &TypeRefs);
+ void verifyDIExpression(const DbgInfoIntrinsic &I, const MapTy &TypeRefs);
void visitUnresolvedTypeRef(const MDString *S, const MDNode *N);
};
} // End anonymous namespace
@@ -3854,15 +3853,34 @@ static uint64_t getVariableSize(const DILocalVariable &V, const MapTy &Map) {
}
template <class MapTy>
-void Verifier::verifyBitPieceExpression(const DbgInfoIntrinsic &I,
- const MapTy &TypeRefs) {
+void Verifier::verifyDIExpression(const DbgInfoIntrinsic &I,
+ const MapTy &TypeRefs) {
DILocalVariable *V;
DIExpression *E;
+ const Value *Arg;
+ uint64_t ArgumentTypeSizeInBits = 0;
if (auto *DVI = dyn_cast<DbgValueInst>(&I)) {
+ Arg = DVI->getValue();
+ if (Arg)
+ ArgumentTypeSizeInBits =
+ M->getDataLayout().getTypeAllocSizeInBits(Arg->getType());
V = dyn_cast_or_null<DILocalVariable>(DVI->getRawVariable());
E = dyn_cast_or_null<DIExpression>(DVI->getRawExpression());
} else {
auto *DDI = cast<DbgDeclareInst>(&I);
+ // For declare intrinsics, get the total size of the alloca, to allow
+ // case where the variable may span more than one element.
+ Arg = DDI->getAddress();
+ if (Arg)
+ Arg = Arg->stripPointerCasts();
+ const AllocaInst *AI = dyn_cast_or_null<AllocaInst>(Arg);
+ if (AI) {
+ // We can only say something about constant size allocations
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
+ ArgumentTypeSizeInBits =
+ CI->getLimitedValue() *
+ M->getDataLayout().getTypeAllocSizeInBits(AI->getAllocatedType());
+ }
V = dyn_cast_or_null<DILocalVariable>(DDI->getRawVariable());
E = dyn_cast_or_null<DIExpression>(DDI->getRawExpression());
}
@@ -3871,10 +3889,6 @@ void Verifier::verifyBitPieceExpression(const DbgInfoIntrinsic &I,
if (!V || !E || !E->isValid())
return;
- // Nothing to do if this isn't a bit piece expression.
- if (!E->isBitPiece())
- return;
-
// The frontend helps out GDB by emitting the members of local anonymous
// unions as artificial local variables with shared storage. When SROA splits
// the storage for artificial local variables that are smaller than the entire
@@ -3890,11 +3904,33 @@ void Verifier::verifyBitPieceExpression(const DbgInfoIntrinsic &I,
if (!VarSize)
return;
- unsigned PieceSize = E->getBitPieceSize();
- unsigned PieceOffset = E->getBitPieceOffset();
- Assert(PieceSize + PieceOffset <= VarSize,
- "piece is larger than or outside of variable", &I, V, E);
- Assert(PieceSize != VarSize, "piece covers entire variable", &I, V, E);
+ if (E->isBitPiece()) {
+ unsigned PieceSize = E->getBitPieceSize();
+ unsigned PieceOffset = E->getBitPieceOffset();
+ Assert(PieceSize + PieceOffset <= VarSize,
+ "piece is larger than or outside of variable", &I, V, E);
+ Assert(PieceSize != VarSize, "piece covers entire variable", &I, V, E);
+ return;
+ }
+
+ if (!ArgumentTypeSizeInBits)
+ return; // We were unable to determine the size of the argument
+
+ if (E->getNumElements() == 0) {
+ // In the case where the expression is empty, verify the size of the
+ // argument. Doing this in the general case would require looking through
+ // any dereferences that may be in the expression.
+ Assert(ArgumentTypeSizeInBits == VarSize,
+ "size of passed value (" + std::to_string(ArgumentTypeSizeInBits) +
+ ") does not match size of declared variable (" +
+ std::to_string(VarSize) + ")",
+ &I, Arg, V, V->getType(), E);
+ } else if (E->getElement(0) == dwarf::DW_OP_deref) {
+ Assert(ArgumentTypeSizeInBits == M->getDataLayout().getPointerSizeInBits(),
+ "the operation of the expression is a deref, but the passed value "
+ "is not pointer sized",
+ &I, Arg, V, V->getType(), E);
+ }
}
void Verifier::visitUnresolvedTypeRef(const MDString *S, const MDNode *N) {
@@ -3927,7 +3963,7 @@ void Verifier::verifyTypeRefs() {
for (const BasicBlock &BB : F)
for (const Instruction &I : BB)
if (auto *DII = dyn_cast<DbgInfoIntrinsic>(&I))
- verifyBitPieceExpression(*DII, TypeRefs);
+ verifyDIExpression(*DII, TypeRefs);
// Return early if all typerefs were resolved.
if (UnresolvedTypeRefs.empty())
OpenPOWER on IntegriCloud