From 85dc7b4f3901164a03284a178fcdccc2cf56eb2f Mon Sep 17 00:00:00 2001 From: Alex Kirchhoff Date: Thu, 12 Oct 2023 15:42:30 -0700 Subject: [PATCH] [YAMLTraits] Fix std::optional input on empty documents When the input document is non-empty, `mapOptional` works as expected, setting `std::optional` to `std::nullopt` when the field is not present. When the input document is empty, we hit a special case inside of `Input::preflightKey` that results in `UseDefault = false`, which results in the `std::optional` erroneously being set to a non-nullopt value. `preflightKey` is changed to set `UseDefault = true` in this case to make the behavior consistent between empty and non-empty documents. --- llvm/lib/Support/YAMLTraits.cpp | 2 ++ llvm/unittests/Support/YAMLIOTest.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/llvm/lib/Support/YAMLTraits.cpp b/llvm/lib/Support/YAMLTraits.cpp index 9325a09faaea022..4aaf59be2ce502f 100644 --- a/llvm/lib/Support/YAMLTraits.cpp +++ b/llvm/lib/Support/YAMLTraits.cpp @@ -156,6 +156,8 @@ bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault, if (!CurrentNode) { if (Required) EC = make_error_code(errc::invalid_argument); + else + UseDefault = true; return false; } diff --git a/llvm/unittests/Support/YAMLIOTest.cpp b/llvm/unittests/Support/YAMLIOTest.cpp index 90c09ed7f79ee34..745d743b2b24498 100644 --- a/llvm/unittests/Support/YAMLIOTest.cpp +++ b/llvm/unittests/Support/YAMLIOTest.cpp @@ -2392,6 +2392,7 @@ TEST(YAMLIO, TestMalformedMapFailsGracefully) { struct OptionalTest { std::vector Numbers; + std::optional MaybeNumber; }; struct OptionalTestSeq { @@ -2405,6 +2406,7 @@ namespace yaml { struct MappingTraits { static void mapping(IO& IO, OptionalTest &OT) { IO.mapOptional("Numbers", OT.Numbers); + IO.mapOptional("MaybeNumber", OT.MaybeNumber); } }; @@ -2466,6 +2468,7 @@ TEST(YAMLIO, TestEmptyStringSucceedsForMapWithOptionalFields) { Input yin(""); yin >> doc; EXPECT_FALSE(yin.error()); + EXPECT_FALSE(doc.MaybeNumber.has_value()); } TEST(YAMLIO, TestEmptyStringSucceedsForSequence) {