#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N);
#include "llvm/IR/Metadata.def"
void visitDIScope(const DIScope &N);
- void visitDIDerivedTypeBase(const DIDerivedTypeBase &N);
void visitDIVariable(const DIVariable &N);
void visitDILexicalBlockBase(const DILexicalBlockBase &N);
void visitDITemplateParameter(const DITemplateParameter &N);
void visitExtractValueInst(ExtractValueInst &EVI);
void visitInsertValueInst(InsertValueInst &IVI);
void visitLandingPadInst(LandingPadInst &LPI);
- void visitCatchBlockInst(CatchBlockInst &CBI);
- void visitCatchEndBlockInst(CatchEndBlockInst &CEBI);
- void visitCleanupBlockInst(CleanupBlockInst &CBI);
- void visitTerminateBlockInst(TerminateBlockInst &TBI);
void VerifyCallSite(CallSite CS);
void verifyMustTailCall(CallInst &CI);
"invalid tag", &N);
}
-void Verifier::visitDIDerivedTypeBase(const DIDerivedTypeBase &N) {
+void Verifier::visitDIDerivedType(const DIDerivedType &N) {
// Common scope checks.
visitDIScope(N);
- Assert(isScopeRef(N, N.getScope()), "invalid scope", &N, N.getScope());
- Assert(isTypeRef(N, N.getBaseType()), "invalid base type", &N,
- N.getBaseType());
-
- // FIXME: Sink this into the subclass verifies.
- if (!N.getFile() || N.getFile()->getFilename().empty()) {
- // Check whether the filename is allowed to be empty.
- uint16_t Tag = N.getTag();
- Assert(
- Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type ||
- Tag == dwarf::DW_TAG_pointer_type ||
- Tag == dwarf::DW_TAG_ptr_to_member_type ||
- Tag == dwarf::DW_TAG_reference_type ||
- Tag == dwarf::DW_TAG_rvalue_reference_type ||
- Tag == dwarf::DW_TAG_restrict_type ||
- Tag == dwarf::DW_TAG_array_type ||
- Tag == dwarf::DW_TAG_enumeration_type ||
- Tag == dwarf::DW_TAG_subroutine_type ||
- Tag == dwarf::DW_TAG_inheritance || Tag == dwarf::DW_TAG_friend ||
- Tag == dwarf::DW_TAG_structure_type ||
- Tag == dwarf::DW_TAG_member || Tag == dwarf::DW_TAG_typedef,
- "derived/composite type requires a filename", &N, N.getFile());
- }
-}
-
-void Verifier::visitDIDerivedType(const DIDerivedType &N) {
- // Common derived type checks.
- visitDIDerivedTypeBase(N);
-
Assert(N.getTag() == dwarf::DW_TAG_typedef ||
N.getTag() == dwarf::DW_TAG_pointer_type ||
N.getTag() == dwarf::DW_TAG_ptr_to_member_type ||
Assert(isTypeRef(N, N.getExtraData()), "invalid pointer to member type", &N,
N.getExtraData());
}
+
+ Assert(isScopeRef(N, N.getScope()), "invalid scope", &N, N.getScope());
+ Assert(isTypeRef(N, N.getBaseType()), "invalid base type", &N,
+ N.getBaseType());
}
static bool hasConflictingReferenceFlags(unsigned Flags) {
}
void Verifier::visitDICompositeType(const DICompositeType &N) {
- // Common derived type checks.
- visitDIDerivedTypeBase(N);
+ // Common scope checks.
+ visitDIScope(N);
Assert(N.getTag() == dwarf::DW_TAG_array_type ||
N.getTag() == dwarf::DW_TAG_structure_type ||
N.getTag() == dwarf::DW_TAG_union_type ||
N.getTag() == dwarf::DW_TAG_enumeration_type ||
- N.getTag() == dwarf::DW_TAG_subroutine_type ||
N.getTag() == dwarf::DW_TAG_class_type,
"invalid tag", &N);
+ Assert(isScopeRef(N, N.getScope()), "invalid scope", &N, N.getScope());
+ Assert(isTypeRef(N, N.getBaseType()), "invalid base type", &N,
+ N.getBaseType());
+
Assert(!N.getRawElements() || isa<MDTuple>(N.getRawElements()),
"invalid composite elements", &N, N.getRawElements());
Assert(isTypeRef(N, N.getRawVTableHolder()), "invalid vtable holder", &N,
&N);
if (auto *Params = N.getRawTemplateParams())
visitTemplateParams(N, *Params);
+
+ if (N.getTag() == dwarf::DW_TAG_class_type ||
+ N.getTag() == dwarf::DW_TAG_union_type) {
+ Assert(N.getFile() && !N.getFile()->getFilename().empty(),
+ "class/union requires a filename", &N, N.getFile());
+ }
}
void Verifier::visitDISubroutineType(const DISubroutineType &N) {
"invalid tag", &N);
Assert(N.getRawScope() && isa<DILocalScope>(N.getRawScope()),
"local variable requires a valid scope", &N, N.getRawScope());
+ Assert(bool(N.getArg()) == (N.getTag() == dwarf::DW_TAG_arg_variable),
+ "local variable should have arg iff it's a DW_TAG_arg_variable", &N);
}
void Verifier::visitDIExpression(const DIExpression &N) {
I->getKindAsEnum() == Attribute::Cold ||
I->getKindAsEnum() == Attribute::OptimizeNone ||
I->getKindAsEnum() == Attribute::JumpTable ||
- I->getKindAsEnum() == Attribute::Convergent) {
+ I->getKindAsEnum() == Attribute::Convergent ||
+ I->getKindAsEnum() == Attribute::ArgMemOnly) {
if (!isFunction) {
CheckFailed("Attribute '" + I->getAsString() +
"' only applies to functions!", V);
const Instruction &CI = *CS.getInstruction();
- Assert(!CS.doesNotAccessMemory() && !CS.onlyReadsMemory(),
- "gc.statepoint must read and write memory to preserve "
+ Assert(!CS.doesNotAccessMemory() && !CS.onlyReadsMemory() &&
+ !CS.onlyAccessesArgMemory(),
+ "gc.statepoint must read and write all memory to preserve "
"reordering restrictions required by safepoint semantics",
&CI);
void Verifier::visitInvokeInst(InvokeInst &II) {
VerifyCallSite(&II);
- // Verify that there is an exception block instruction is the first non-PHI
+ // Verify that there is a landingpad instruction as the first non-PHI
// instruction of the 'unwind' destination.
- Assert(
- II.getUnwindDest()->isEHBlock(),
- "The unwind destination does not have an exception handling instruction!",
- &II);
+ Assert(II.getUnwindDest()->isLandingPad(),
+ "The unwind destination does not have a landingpad instruction!", &II);
visitTerminatorInst(II);
}
visitInstruction(LPI);
}
-void Verifier::visitCatchBlockInst(CatchBlockInst &CBI) {
- BasicBlock *BB = CBI.getParent();
-
- Function *F = BB->getParent();
- Assert(F->hasPersonalityFn(),
- "CatchBlockInst needs to be in a function with a personality.", &CBI);
-
- // The catchblock instruction must be the first non-PHI instruction in the
- // block.
- Assert(BB->getFirstNonPHI() == &CBI,
- "CatchBlockInst not the first non-PHI instruction in the block.",
- &CBI);
-
- visitTerminatorInst(CBI);
-}
-
-void Verifier::visitCatchEndBlockInst(CatchEndBlockInst &CEBI) {
- BasicBlock *BB = CEBI.getParent();
-
- Function *F = BB->getParent();
- Assert(F->hasPersonalityFn(),
- "CatchEndBlockInst needs to be in a function with a personality.",
- &CEBI);
-
- // The catchendblock instruction must be the first non-PHI instruction in the
- // block.
- Assert(BB->getFirstNonPHI() == &CEBI,
- "CatchEndBlockInst not the first non-PHI instruction in the block.",
- &CEBI);
-
- visitTerminatorInst(CEBI);
-}
-
-void Verifier::visitCleanupBlockInst(CleanupBlockInst &CBI) {
- BasicBlock *BB = CBI.getParent();
-
- Function *F = BB->getParent();
- Assert(F->hasPersonalityFn(),
- "CleanupBlockInst needs to be in a function with a personality.", &CBI);
-
- // The cleanupblock instruction must be the first non-PHI instruction in the
- // block.
- Assert(BB->getFirstNonPHI() == &CBI,
- "CleanupBlockInst not the first non-PHI instruction in the block.",
- &CBI);
-
- visitInstruction(CBI);
-}
-
-void Verifier::visitTerminateBlockInst(TerminateBlockInst &TBI) {
- BasicBlock *BB = TBI.getParent();
-
- Function *F = BB->getParent();
- Assert(F->hasPersonalityFn(),
- "TerminateBlockInst needs to be in a function with a personality.",
- &TBI);
-
- // The terminateblock instruction must be the first non-PHI instruction in the
- // block.
- Assert(BB->getFirstNonPHI() == &TBI,
- "TerminateBlockInst not the first non-PHI instruction in the block.",
- &TBI);
-
- visitTerminatorInst(TBI);
-}
-
void Verifier::verifyDominatesUse(Instruction &I, unsigned i) {
Instruction *Op = cast<Instruction>(I.getOperand(i));
// If the we have an invalid invoke, don't try to compute the dominance.