From 2cee1c9d3c261e44e9d2eb1f1d0d16c17e4315df Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Fri, 27 Mar 2015 17:56:39 +0000 Subject: [PATCH] LLParser: Require non-null scope for MDLocation and MDLocalVariable Change `LLParser` to require a non-null `scope:` field for both `MDLocation` and `MDLocalVariable`. There's no need to wait for the verifier for this check. This also allows their `::getImpl()` methods to assert that the incoming scope is non-null. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233394 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AsmParser/LLParser.cpp | 10 +++++++--- lib/IR/DebugInfoMetadata.cpp | 2 ++ test/Assembler/invalid-mdlocalvariable-null-scope.ll | 4 ++++ test/Assembler/invalid-mdlocation-null-scope.ll | 4 ++++ test/CodeGen/Generic/dbg_value.ll | 2 +- test/CodeGen/X86/dbg-changes-codegen.ll | 4 ++-- 6 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 test/Assembler/invalid-mdlocalvariable-null-scope.ll create mode 100644 test/Assembler/invalid-mdlocation-null-scope.ll diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 484a7250e2e..428d80022e2 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -3030,7 +3030,9 @@ struct MDBoolField : public MDFieldImpl { MDBoolField(bool Default = false) : ImplTy(Default) {} }; struct MDField : public MDFieldImpl { - MDField() : ImplTy(nullptr) {} + bool AllowNull; + + MDField(bool AllowNull = true) : ImplTy(nullptr), AllowNull(AllowNull) {} }; struct MDConstant : public MDFieldImpl { MDConstant() : ImplTy(nullptr) {} @@ -3221,6 +3223,8 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDBoolField &Result) { template <> bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDField &Result) { if (Lex.getKind() == lltok::kw_null) { + if (!Result.AllowNull) + return TokError("'" + Name + "' cannot be null"); Lex.Lex(); Result.assign(nullptr); return false; @@ -3343,7 +3347,7 @@ bool LLParser::ParseMDLocation(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(line, LineField, ); \ OPTIONAL(column, ColumnField, ); \ - REQUIRED(scope, MDField, ); \ + REQUIRED(scope, MDField, (/* AllowNull */ false)); \ OPTIONAL(inlinedAt, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -3675,7 +3679,7 @@ bool LLParser::ParseMDGlobalVariable(MDNode *&Result, bool IsDistinct) { bool LLParser::ParseMDLocalVariable(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(tag, DwarfTagField, ); \ - REQUIRED(scope, MDField, ); \ + REQUIRED(scope, MDField, (/* AllowNull */ false)); \ OPTIONAL(name, MDStringField, ); \ OPTIONAL(file, MDField, ); \ OPTIONAL(line, LineField, ); \ diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp index 89ec1bc9a9f..63a0b59f7d5 100644 --- a/lib/IR/DebugInfoMetadata.cpp +++ b/lib/IR/DebugInfoMetadata.cpp @@ -44,6 +44,7 @@ MDLocation *MDLocation::getImpl(LLVMContext &Context, unsigned Line, // Fixup column. adjustColumn(Column); + assert(Scope && "Expected scope"); if (Storage == Uniqued) { if (auto *N = getUniqued(Context.pImpl->MDLocations, @@ -345,6 +346,7 @@ MDLocalVariable *MDLocalVariable::getImpl( // it matches historical behaviour for now. Arg &= (1u << 8) - 1; + assert(Scope && "Expected scope"); assert(isCanonical(Name) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(MDLocalVariable, (Tag, Scope, getString(Name), File, Line, Type, Arg, Flags, InlinedAt)); diff --git a/test/Assembler/invalid-mdlocalvariable-null-scope.ll b/test/Assembler/invalid-mdlocalvariable-null-scope.ll new file mode 100644 index 00000000000..53ee94de79b --- /dev/null +++ b/test/Assembler/invalid-mdlocalvariable-null-scope.ll @@ -0,0 +1,4 @@ +; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s + +; CHECK: :[[@LINE+1]]:30: error: 'scope' cannot be null +!0 = !MDLocalVariable(scope: null) diff --git a/test/Assembler/invalid-mdlocation-null-scope.ll b/test/Assembler/invalid-mdlocation-null-scope.ll new file mode 100644 index 00000000000..e359c9fe424 --- /dev/null +++ b/test/Assembler/invalid-mdlocation-null-scope.ll @@ -0,0 +1,4 @@ +; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s + +; CHECK: :[[@LINE+1]]:25: error: 'scope' cannot be null +!0 = !MDLocation(scope: null) diff --git a/test/CodeGen/Generic/dbg_value.ll b/test/CodeGen/Generic/dbg_value.ll index c5200d7837c..f2f3a3f2c79 100644 --- a/test/CodeGen/Generic/dbg_value.ll +++ b/test/CodeGen/Generic/dbg_value.ll @@ -11,4 +11,4 @@ define void @t(%0*, i32, i32, i32, i32) nounwind { declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnone ; !0 should conform to the format of DIVariable. -!0 = !MDLocalVariable(tag: DW_TAG_arg_variable, name: "a", arg: 0, scope: null) +!0 = !MDLocalVariable(tag: DW_TAG_arg_variable, name: "a", arg: 0, scope: !MDSubprogram()) diff --git a/test/CodeGen/X86/dbg-changes-codegen.ll b/test/CodeGen/X86/dbg-changes-codegen.ll index 6cdfdc25019..e50967dc830 100644 --- a/test/CodeGen/X86/dbg-changes-codegen.ll +++ b/test/CodeGen/X86/dbg-changes-codegen.ll @@ -78,6 +78,6 @@ attributes #2 = { nounwind readnone } !17 = !MDDerivedType(tag: DW_TAG_reference_type, baseType: null) !45 = !MDDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: null) -!62 = !MDLocalVariable(tag: DW_TAG_arg_variable, name: "arg", line: 4, arg: 2, scope: null, type: !17) +!62 = !MDLocalVariable(tag: DW_TAG_arg_variable, name: "arg", line: 4, arg: 2, scope: !MDSubprogram(), type: !17) !64 = !{%struct.Flibble* undef} -!65 = !MDLocalVariable(tag: DW_TAG_arg_variable, name: "this", line: 13, arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: null, type: !45) +!65 = !MDLocalVariable(tag: DW_TAG_arg_variable, name: "this", line: 13, arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !MDSubprogram(), type: !45) -- 2.34.1