summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2017-08-30 16:49:21 +0000
committerAdrian Prantl <aprantl@apple.com>2017-08-30 16:49:21 +0000
commit8550e88eb796dc512253b1e2c359dd607189c239 (patch)
tree9ac99de609cfa25b17261593dbe61e81ff60476c /llvm/lib
parentafce0baacd6a10e891518d3f584600de366a5e0b (diff)
downloadbcm5719-llvm-8550e88eb796dc512253b1e2c359dd607189c239.tar.gz
bcm5719-llvm-8550e88eb796dc512253b1e2c359dd607189c239.zip
Verifier: Verify the correctness of fragment expressions attached to globals.
llvm-svn: 312139
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/Verifier.cpp30
1 files changed, 22 insertions, 8 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index e28644a081c..e62daeeb539 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -507,6 +507,10 @@ private:
void verifySiblingFuncletUnwinds();
void verifyFragmentExpression(const DbgInfoIntrinsic &I);
+ template <typename ValueOrMetadata>
+ void verifyFragmentExpression(const DIVariable &V,
+ DIExpression::FragmentInfo Fragment,
+ ValueOrMetadata *Desc);
void verifyFnArgs(const DbgInfoIntrinsic &I);
/// Module-level debug info verification...
@@ -1178,8 +1182,11 @@ void Verifier::visitDIExpression(const DIExpression &N) {
void Verifier::visitDIGlobalVariableExpression(
const DIGlobalVariableExpression &GVE) {
AssertDI(GVE.getVariable(), "missing variable");
- if (auto *Expr = GVE.getExpression())
+ if (auto *Expr = GVE.getExpression()) {
visitDIExpression(*Expr);
+ if (auto Fragment = Expr->getFragmentInfo())
+ verifyFragmentExpression(*GVE.getVariable(), *Fragment, &GVE);
+ }
}
void Verifier::visitDIObjCProperty(const DIObjCProperty &N) {
@@ -4488,7 +4495,7 @@ void Verifier::visitDbgIntrinsic(StringRef Kind, DbgIntrinsicTy &DII) {
verifyFnArgs(DII);
}
-static uint64_t getVariableSize(const DILocalVariable &V) {
+static uint64_t getVariableSize(const DIVariable &V) {
// Be careful of broken types (checked elsewhere).
const Metadata *RawType = V.getRawType();
while (RawType) {
@@ -4527,7 +4534,7 @@ void Verifier::verifyFragmentExpression(const DbgInfoIntrinsic &I) {
if (!V || !E || !E->isValid())
return;
- // Nothing to do if this isn't a bit piece expression.
+ // Nothing to do if this isn't a DW_OP_LLVM_fragment expression.
auto Fragment = E->getFragmentInfo();
if (!Fragment)
return;
@@ -4541,17 +4548,24 @@ void Verifier::verifyFragmentExpression(const DbgInfoIntrinsic &I) {
if (V->isArtificial())
return;
+ verifyFragmentExpression(*V, *Fragment, &I);
+}
+
+template <typename ValueOrMetadata>
+void Verifier::verifyFragmentExpression(const DIVariable &V,
+ DIExpression::FragmentInfo Fragment,
+ ValueOrMetadata *Desc) {
// If there's no size, the type is broken, but that should be checked
// elsewhere.
- uint64_t VarSize = getVariableSize(*V);
+ uint64_t VarSize = getVariableSize(V);
if (!VarSize)
return;
- unsigned FragSize = Fragment->SizeInBits;
- unsigned FragOffset = Fragment->OffsetInBits;
+ unsigned FragSize = Fragment.SizeInBits;
+ unsigned FragOffset = Fragment.OffsetInBits;
AssertDI(FragSize + FragOffset <= VarSize,
- "fragment is larger than or outside of variable", &I, V, E);
- AssertDI(FragSize != VarSize, "fragment covers entire variable", &I, V, E);
+ "fragment is larger than or outside of variable", Desc, &V);
+ AssertDI(FragSize != VarSize, "fragment covers entire variable", Desc, &V);
}
void Verifier::verifyFnArgs(const DbgInfoIntrinsic &I) {
OpenPOWER on IntegriCloud