diff options
author | Filipe Cabecinhas <me@filcab.net> | 2015-06-02 21:25:08 +0000 |
---|---|---|
committer | Filipe Cabecinhas <me@filcab.net> | 2015-06-02 21:25:08 +0000 |
commit | 62431b1d71e20025129f260da0a15a2f55768cc9 (patch) | |
tree | 450df6cb6e26a3ecc684f59a51216dfff24e5805 | |
parent | 436923ce35d669eb462c378f330e878708c8aae0 (diff) | |
download | bcm5719-llvm-62431b1d71e20025129f260da0a15a2f55768cc9.tar.gz bcm5719-llvm-62431b1d71e20025129f260da0a15a2f55768cc9.zip |
[IR/AsmWriter] Output escape sequences if the first character isdigit()
If the first character in a metadata attachment's name is a digit, it has
to be output using an escape sequence, otherwise it's not valid text IR.
Removed an over-zealous assert from LLVMContext which didn't allow this.
The rule should only apply to text IR. Actual names can have any sequence
of non-NUL bytes.
Also added some documentation on accepted names.
Bug found with AFL fuzz.
llvm-svn: 238867
-rw-r--r-- | llvm/docs/LangRef.rst | 5 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContext.cpp | 3 | ||||
-rw-r--r-- | llvm/test/Assembler/metadata.ll | 7 |
4 files changed, 23 insertions, 9 deletions
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 397d5fe3756..0996820f724 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -834,6 +834,11 @@ Named metadata is a collection of metadata. :ref:`Metadata nodes <metadata>` (but not metadata strings) are the only valid operands for a named metadata. +#. Named metadata are represented as a string of characters with the + metadata prefix. The rules for metadata names are the same as for + identifiers, but quoted names are not allowed. ``"\xx"`` type escapes + are still valid, which allows any character to be part of a name. + Syntax:: ; Some unnamed metadata nodes, which are referenced by the named metadata. diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 86bcd658185..715aad8b03a 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2215,9 +2215,8 @@ void AssemblyWriter::printModule(const Module *M) { } } -void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) { - Out << '!'; - StringRef Name = NMD->getName(); +static void printMetadataIdentifier(StringRef Name, + formatted_raw_ostream &Out) { if (Name.empty()) { Out << "<empty name> "; } else { @@ -2235,6 +2234,11 @@ void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) { Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F); } } +} + +void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) { + Out << '!'; + printMetadataIdentifier(NMD->getName(), Out); Out << " = !{"; for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { if (i) @@ -3006,9 +3010,10 @@ void AssemblyWriter::printMetadataAttachments( for (const auto &I : MDs) { unsigned Kind = I.first; Out << Separator; - if (Kind < MDNames.size()) - Out << "!" << MDNames[Kind]; - else + if (Kind < MDNames.size()) { + Out << "!"; + printMetadataIdentifier(MDNames[Kind], Out); + } else Out << "!<unknown kind #" << Kind << ">"; Out << ' '; WriteAsOperandInternal(Out, I.second, &TypePrinter, &Machine, TheModule); diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp index e8bf442b3e1..7bcd829f9f5 100644 --- a/llvm/lib/IR/LLVMContext.cpp +++ b/llvm/lib/IR/LLVMContext.cpp @@ -242,9 +242,6 @@ void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) { /// Return a unique non-zero ID for the specified metadata kind. unsigned LLVMContext::getMDKindID(StringRef Name) const { - assert(!std::isdigit(Name.front()) && - "Named metadata may not start with a digit"); - // If this is new, assign it its ID. return pImpl->CustomMDKindNames.insert( std::make_pair( diff --git a/llvm/test/Assembler/metadata.ll b/llvm/test/Assembler/metadata.ll index 8d5e91fb332..052ac1b5097 100644 --- a/llvm/test/Assembler/metadata.ll +++ b/llvm/test/Assembler/metadata.ll @@ -22,6 +22,13 @@ define void @test3() !bar !3 { unreachable, !bar !4 } +; CHECK-LABEL: define void @test_attachment_name() { +; CHECK: unreachable, !\342abc !4 +define void @test_attachment_name() { + ;; Escape the first character when printing text IR, since it's a digit + unreachable, !\34\32abc !4 +} + !0 = !DILocation(line: 662302, column: 26, scope: !1) !1 = !DISubprogram(name: "foo") !2 = distinct !{} |