mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
Verifier: Verify the correctness of fragment expressions attached to globals.
llvm-svn: 312139
This commit is contained in:
parent
f4c0ab8f37
commit
22f5d07f74
@ -507,6 +507,10 @@ private:
|
|||||||
void verifySiblingFuncletUnwinds();
|
void verifySiblingFuncletUnwinds();
|
||||||
|
|
||||||
void verifyFragmentExpression(const DbgInfoIntrinsic &I);
|
void verifyFragmentExpression(const DbgInfoIntrinsic &I);
|
||||||
|
template <typename ValueOrMetadata>
|
||||||
|
void verifyFragmentExpression(const DIVariable &V,
|
||||||
|
DIExpression::FragmentInfo Fragment,
|
||||||
|
ValueOrMetadata *Desc);
|
||||||
void verifyFnArgs(const DbgInfoIntrinsic &I);
|
void verifyFnArgs(const DbgInfoIntrinsic &I);
|
||||||
|
|
||||||
/// Module-level debug info verification...
|
/// Module-level debug info verification...
|
||||||
@ -1178,8 +1182,11 @@ void Verifier::visitDIExpression(const DIExpression &N) {
|
|||||||
void Verifier::visitDIGlobalVariableExpression(
|
void Verifier::visitDIGlobalVariableExpression(
|
||||||
const DIGlobalVariableExpression &GVE) {
|
const DIGlobalVariableExpression &GVE) {
|
||||||
AssertDI(GVE.getVariable(), "missing variable");
|
AssertDI(GVE.getVariable(), "missing variable");
|
||||||
if (auto *Expr = GVE.getExpression())
|
if (auto *Expr = GVE.getExpression()) {
|
||||||
visitDIExpression(*Expr);
|
visitDIExpression(*Expr);
|
||||||
|
if (auto Fragment = Expr->getFragmentInfo())
|
||||||
|
verifyFragmentExpression(*GVE.getVariable(), *Fragment, &GVE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Verifier::visitDIObjCProperty(const DIObjCProperty &N) {
|
void Verifier::visitDIObjCProperty(const DIObjCProperty &N) {
|
||||||
@ -4488,7 +4495,7 @@ void Verifier::visitDbgIntrinsic(StringRef Kind, DbgIntrinsicTy &DII) {
|
|||||||
verifyFnArgs(DII);
|
verifyFnArgs(DII);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t getVariableSize(const DILocalVariable &V) {
|
static uint64_t getVariableSize(const DIVariable &V) {
|
||||||
// Be careful of broken types (checked elsewhere).
|
// Be careful of broken types (checked elsewhere).
|
||||||
const Metadata *RawType = V.getRawType();
|
const Metadata *RawType = V.getRawType();
|
||||||
while (RawType) {
|
while (RawType) {
|
||||||
@ -4527,7 +4534,7 @@ void Verifier::verifyFragmentExpression(const DbgInfoIntrinsic &I) {
|
|||||||
if (!V || !E || !E->isValid())
|
if (!V || !E || !E->isValid())
|
||||||
return;
|
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();
|
auto Fragment = E->getFragmentInfo();
|
||||||
if (!Fragment)
|
if (!Fragment)
|
||||||
return;
|
return;
|
||||||
@ -4541,17 +4548,24 @@ void Verifier::verifyFragmentExpression(const DbgInfoIntrinsic &I) {
|
|||||||
if (V->isArtificial())
|
if (V->isArtificial())
|
||||||
return;
|
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
|
// If there's no size, the type is broken, but that should be checked
|
||||||
// elsewhere.
|
// elsewhere.
|
||||||
uint64_t VarSize = getVariableSize(*V);
|
uint64_t VarSize = getVariableSize(V);
|
||||||
if (!VarSize)
|
if (!VarSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned FragSize = Fragment->SizeInBits;
|
unsigned FragSize = Fragment.SizeInBits;
|
||||||
unsigned FragOffset = Fragment->OffsetInBits;
|
unsigned FragOffset = Fragment.OffsetInBits;
|
||||||
AssertDI(FragSize + FragOffset <= VarSize,
|
AssertDI(FragSize + FragOffset <= VarSize,
|
||||||
"fragment is larger than or outside of variable", &I, V, E);
|
"fragment is larger than or outside of variable", Desc, &V);
|
||||||
AssertDI(FragSize != VarSize, "fragment covers entire variable", &I, V, E);
|
AssertDI(FragSize != VarSize, "fragment covers entire variable", Desc, &V);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Verifier::verifyFnArgs(const DbgInfoIntrinsic &I) {
|
void Verifier::verifyFnArgs(const DbgInfoIntrinsic &I) {
|
||||||
|
19
test/Verifier/fragment.ll
Normal file
19
test/Verifier/fragment.ll
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
; RUN: not opt -S <%s 2>&1| FileCheck %s
|
||||||
|
|
||||||
|
; CHECK: fragment is larger than or outside of variable
|
||||||
|
; CHECK: !DIGlobalVariableExpression(var: ![[VAR:[0-9]+]],
|
||||||
|
; CHECK-SAME: expr: !DIExpression(DW_OP_LLVM_fragment, 0, 64))
|
||||||
|
; CHECK: ![[VAR]] = !DIGlobalVariable(name: "g"
|
||||||
|
|
||||||
|
@g = common global i32 0, align 4, !dbg !0
|
||||||
|
|
||||||
|
!llvm.dbg.cu = !{!1}
|
||||||
|
!llvm.module.flags = !{!6, !7}
|
||||||
|
|
||||||
|
!0 = !DIGlobalVariableExpression(var: !3, expr: !DIExpression(DW_OP_LLVM_fragment, 0, 64))
|
||||||
|
!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, emissionKind: FullDebug)
|
||||||
|
!2 = !DIFile(filename: "a.c", directory: "/")
|
||||||
|
!3 = !DIGlobalVariable(name: "g", scope: !1, file: !2, line: 1, type: !5, isLocal: false, isDefinition: true)
|
||||||
|
!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||||
|
!6 = !{i32 2, !"Dwarf Version", i32 4}
|
||||||
|
!7 = !{i32 2, !"Debug Info Version", i32 3}
|
Loading…
Reference in New Issue
Block a user