summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp2
-rw-r--r--llvm/lib/IR/DebugInfo.cpp61
-rw-r--r--llvm/lib/IR/Verifier.cpp31
-rw-r--r--llvm/test/Assembler/invalid-mdcompileunit-null-file.ll4
-rw-r--r--llvm/test/Assembler/metadata-null-operands.ll12
5 files changed, 46 insertions, 64 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index dc348e4d4b7..6e79960e3db 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -3506,7 +3506,7 @@ bool LLParser::ParseMDFile(MDNode *&Result, bool IsDistinct) {
bool LLParser::ParseMDCompileUnit(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(language, DwarfLangField, ); \
- REQUIRED(file, MDField, ); \
+ REQUIRED(file, MDField, (/* AllowNull */ false)); \
OPTIONAL(producer, MDStringField, ); \
OPTIONAL(isOptimized, MDBoolField, ); \
OPTIONAL(flags, MDStringField, ); \
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index bc40907ba18..4e5b5f1f975 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -220,15 +220,7 @@ void DIDescriptor::replaceAllUsesWith(MDNode *D) {
Node->replaceAllUsesWith(D);
}
-bool DICompileUnit::Verify() const {
- if (!isCompileUnit())
- return false;
-
- // Don't bother verifying the compilation directory or producer string
- // as those could be empty.
- return !getFilename().empty();
-}
-
+bool DICompileUnit::Verify() const { return isCompileUnit(); }
bool DIObjCProperty::Verify() const { return isObjCProperty(); }
/// \brief Check if a value can be a reference to a type.
@@ -264,61 +256,18 @@ bool DIType::Verify() const {
auto *N = dyn_cast_or_null<MDType>(DbgNode);
if (!N)
return false;
- if (!isScopeRef(N->getScope()))
- return false;
-
- // DIType is abstract, it should be a BasicType, a DerivedType or
- // a CompositeType.
- if (isBasicType())
- return DIBasicType(DbgNode).Verify();
-
- // FIXME: Sink this into the various subclass verifies.
- if (getFilename().empty()) {
- // Check whether the filename is allowed to be empty.
- uint16_t Tag = getTag();
- if (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)
- return false;
- }
if (isCompositeType())
return DICompositeType(DbgNode).Verify();
- if (isDerivedType())
- return DIDerivedType(DbgNode).Verify();
- return false;
-}
-
-bool DIBasicType::Verify() const {
- return dyn_cast_or_null<MDBasicType>(DbgNode);
+ return true;
}
-bool DIDerivedType::Verify() const {
- auto *N = dyn_cast_or_null<MDDerivedTypeBase>(DbgNode);
- if (!N)
- return false;
- if (getTag() == dwarf::DW_TAG_ptr_to_member_type) {
- auto *D = dyn_cast<MDDerivedType>(N);
- if (!D)
- return false;
- if (!isTypeRef(D->getExtraData()))
- return false;
- }
- return isTypeRef(N->getBaseType());
-}
+bool DIBasicType::Verify() const { return isBasicType(); }
+bool DIDerivedType::Verify() const { return isDerivedType(); }
bool DICompositeType::Verify() const {
auto *N = dyn_cast_or_null<MDCompositeTypeBase>(DbgNode);
- return N && isTypeRef(N->getBaseType()) && isTypeRef(N->getVTableHolder()) &&
- !(isLValueReference() && isRValueReference());
+ return N && !(isLValueReference() && isRValueReference());
}
bool DISubprogram::Verify() const {
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index e5488593b8f..4bf24211963 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -752,6 +752,26 @@ void Verifier::visitMDDerivedTypeBase(const MDDerivedTypeBase &N) {
Assert(isScopeRef(N.getScope()), "invalid scope", &N, N.getScope());
Assert(isTypeRef(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::visitMDDerivedType(const MDDerivedType &N) {
@@ -770,6 +790,10 @@ void Verifier::visitMDDerivedType(const MDDerivedType &N) {
N.getTag() == dwarf::DW_TAG_inheritance ||
N.getTag() == dwarf::DW_TAG_friend,
"invalid tag", &N);
+ if (N.getTag() == dwarf::DW_TAG_ptr_to_member_type) {
+ Assert(isTypeRef(N.getExtraData()), "invalid pointer to member type",
+ &N, N.getExtraData());
+ }
}
void Verifier::visitMDCompositeType(const MDCompositeType &N) {
@@ -809,6 +833,13 @@ void Verifier::visitMDFile(const MDFile &N) {
void Verifier::visitMDCompileUnit(const MDCompileUnit &N) {
Assert(N.getTag() == dwarf::DW_TAG_compile_unit, "invalid tag", &N);
+ // Don't bother verifying the compilation directory or producer string
+ // as those could be empty.
+ Assert(N.getRawFile() && isa<MDFile>(N.getRawFile()),
+ "invalid file", &N, N.getRawFile());
+ Assert(!N.getFile()->getFilename().empty(), "invalid filename", &N,
+ N.getFile());
+
if (auto *Array = N.getRawEnumTypes()) {
Assert(isa<MDTuple>(Array), "invalid enum list", &N, Array);
for (Metadata *Op : N.getEnumTypes()->operands()) {
diff --git a/llvm/test/Assembler/invalid-mdcompileunit-null-file.ll b/llvm/test/Assembler/invalid-mdcompileunit-null-file.ll
new file mode 100644
index 00000000000..613948f24ef
--- /dev/null
+++ b/llvm/test/Assembler/invalid-mdcompileunit-null-file.ll
@@ -0,0 +1,4 @@
+; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+; CHECK: <stdin>:[[@LINE+1]]:27: error: 'file' cannot be null
+!0 = !MDCompileUnit(file: null)
diff --git a/llvm/test/Assembler/metadata-null-operands.ll b/llvm/test/Assembler/metadata-null-operands.ll
index acae1d4be99..7e27eba45fe 100644
--- a/llvm/test/Assembler/metadata-null-operands.ll
+++ b/llvm/test/Assembler/metadata-null-operands.ll
@@ -1,13 +1,11 @@
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
; RUN: verify-uselistorder %s
-; Don't crash on null operands. (If/when we add a verify check for these, we
-; should disable the verifier for this test and remove this comment; the test
-; is still important.)
-!named = !{!0, !1}
+; Don't crash on null operands. When we add a verify check for this, also
+; require non-null in the assembler and rework this test to check for that ala
+; test/Assembler/invalid-mdcompileunit-null-file.ll.
+!named = !{!0}
!0 = !MDDerivedType(tag: DW_TAG_pointer_type, baseType: null)
-!1 = !MDCompileUnit(language: DW_LANG_C, file: null)
-; CHECK: !named = !{!0, !1}
+; CHECK: !named = !{!0}
; CHECK: !0 = !MDDerivedType({{.*}}baseType: null{{.*}})
-; CHECK: !1 = !MDCompileUnit({{.*}}file: null{{.*}})
OpenPOWER on IntegriCloud