diff --git a/llvm/lib/Support/YAMLTraits.cpp b/llvm/lib/Support/YAMLTraits.cpp --- a/llvm/lib/Support/YAMLTraits.cpp +++ b/llvm/lib/Support/YAMLTraits.cpp @@ -435,6 +435,11 @@ // Copy string to permanent storage KeyStr = StringStorage.str().copy(StringAllocator); } + if (mapHNode->Mapping.count(KeyStr)) + // From YAML spec: "The content of a mapping node is an unordered set of + // key/value node pairs, with the restriction that each of the keys is + // unique." + setError(KeyNode, Twine("duplicated mapping key '") + KeyStr + "'"); auto ValueHNode = createHNodes(Value); if (EC) break; diff --git a/llvm/unittests/Support/YAMLIOTest.cpp b/llvm/unittests/Support/YAMLIOTest.cpp --- a/llvm/unittests/Support/YAMLIOTest.cpp +++ b/llvm/unittests/Support/YAMLIOTest.cpp @@ -105,6 +105,16 @@ EXPECT_TRUE(!!yin.error()); } +TEST(YAMLIO, TestMapDuplicatedKeysRead) { + auto testDiagnostic = [](const llvm::SMDiagnostic &Error, void *) { + EXPECT_EQ(Error.getMessage(), "duplicated mapping key 'foo'"); + }; + FooBar doc; + Input yin("{foo: 3, bar: 5, foo: 4}", nullptr, testDiagnostic); + yin >> doc; + EXPECT_TRUE(!!yin.error()); +} + // // Test the reading of a yaml sequence of mappings //