diff --git a/llvm/lib/Support/YAMLParser.cpp b/llvm/lib/Support/YAMLParser.cpp --- a/llvm/lib/Support/YAMLParser.cpp +++ b/llvm/lib/Support/YAMLParser.cpp @@ -2446,6 +2446,11 @@ return stream.scanner->failed(); } +static SMRange getRangeFromStringRef(StringRef Str) { + return SMRange(SMLoc::getFromPointer(Str.begin()), + SMLoc::getFromPointer(Str.end())); +} + Node *Document::parseBlockNode() { Token T = peekNext(); // Handle properties. @@ -2455,6 +2460,24 @@ switch (T.Kind) { case Token::TK_Alias: getNext(); + // YAML1.2 - 7.1 Alias Nodes + // + // Note that an alias node must not specify any properties or content, as + // these were already specified at the first occurrence of the node. + if (AnchorInfo.Kind == Token::TK_Anchor || TagInfo.Kind == Token::TK_Tag) { + setError("Alias node cannot have any properties", T); + if (AnchorInfo.Kind == Token::TK_Anchor) { + auto Range = getRangeFromStringRef(AnchorInfo.Range); + stream.scanner->printError(Range.Start, SourceMgr::DK_Note, + "anchor declared here", {Range}); + } + if (TagInfo.Kind == Token::TK_Tag) { + auto Range = getRangeFromStringRef(TagInfo.Range); + stream.scanner->printError(Range.Start, SourceMgr::DK_Note, + "tag declared here", {Range}); + } + return nullptr; + } return new (NodeAllocator) AliasNode(stream.CurrentDoc, T.Range.substr(1)); case Token::TK_Anchor: if (AnchorInfo.Kind == Token::TK_Anchor) { diff --git a/llvm/unittests/Support/YAMLParserTest.cpp b/llvm/unittests/Support/YAMLParserTest.cpp --- a/llvm/unittests/Support/YAMLParserTest.cpp +++ b/llvm/unittests/Support/YAMLParserTest.cpp @@ -183,6 +183,12 @@ ExpectParseError("KeyValueNode with null value", "test: '"); } +TEST(YAMLParser, FailsOnAliasProperties) { + ExpectParseError("Alias node cannot have any properties", "&A *B"); + ExpectParseError("Alias node cannot have any properties", "!A *B"); + ExpectParseError("Alias node cannot have any properties", "!A &A *B"); +} + // Checks that the given string can be parsed into an identical string inside // of an array. static void ExpectCanParseString(StringRef String) {