diff --git a/llvm/include/llvm/Support/YAMLTraits.h b/llvm/include/llvm/Support/YAMLTraits.h --- a/llvm/include/llvm/Support/YAMLTraits.h +++ b/llvm/include/llvm/Support/YAMLTraits.h @@ -20,6 +20,7 @@ #include "llvm/Support/Endian.h" #include "llvm/Support/Regex.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Support/VersionTuple.h" #include "llvm/Support/YAMLParser.h" #include "llvm/Support/raw_ostream.h" #include @@ -1711,6 +1712,12 @@ static QuotingType mustQuote(StringRef) { return QuotingType::None; } }; +template <> struct ScalarTraits { + static void output(const VersionTuple &Value, void *, llvm::raw_ostream &Out); + static StringRef input(StringRef, void *, VersionTuple &); + static QuotingType mustQuote(StringRef) { return QuotingType::None; } +}; + // Define non-member operator>> so that Input can stream in a document list. template inline std::enable_if_t::value, Input &> diff --git a/llvm/lib/InterfaceStub/TBEHandler.cpp b/llvm/lib/InterfaceStub/TBEHandler.cpp --- a/llvm/lib/InterfaceStub/TBEHandler.cpp +++ b/llvm/lib/InterfaceStub/TBEHandler.cpp @@ -69,28 +69,6 @@ static QuotingType mustQuote(StringRef) { return QuotingType::None; } }; -/// YAML traits for TbeVersion. -template <> struct ScalarTraits { - static void output(const VersionTuple &Value, void *, - llvm::raw_ostream &Out) { - Out << Value.getAsString(); - } - - static StringRef input(StringRef Scalar, void *, VersionTuple &Value) { - if (Value.tryParse(Scalar)) - return StringRef("Can't parse version: invalid version format."); - - if (Value > TBEVersionCurrent) - return StringRef("Unsupported TBE version."); - - // Returning empty StringRef indicates successful parse. - return StringRef(); - } - - // Don't place quotation marks around version value. - static QuotingType mustQuote(StringRef) { return QuotingType::None; } -}; - /// YAML traits for ELFSymbol. template <> struct MappingTraits { static void mapping(IO &IO, ELFSymbol &Symbol) { @@ -149,6 +127,11 @@ if (std::error_code Err = YamlIn.error()) return createStringError(Err, "YAML failed reading as TBE"); + if (Stub->TbeVersion > elfabi::TBEVersionCurrent) + return make_error( + "TBE version " + Stub->TbeVersion.getAsString() + " is unsupported.", + std::make_error_code(std::errc::invalid_argument)); + return std::move(Stub); } 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 @@ -1102,3 +1102,15 @@ Val = Num; return StringRef(); } + +void ScalarTraits::output(const VersionTuple &Val, void *, + llvm::raw_ostream &Out) { + Out << Val.getAsString(); +} + +StringRef ScalarTraits::input(StringRef Scalar, void *, + VersionTuple &Val) { + if (Val.tryParse(Scalar)) + return "invalid version format"; + return StringRef(); +} diff --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp --- a/llvm/tools/llvm-ifs/llvm-ifs.cpp +++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp @@ -104,27 +104,6 @@ } }; -template <> struct ScalarTraits { - static void output(const VersionTuple &Value, void *, - llvm::raw_ostream &Out) { - Out << Value.getAsString(); - } - - static StringRef input(StringRef Scalar, void *, VersionTuple &Value) { - if (Value.tryParse(Scalar)) - return StringRef("Can't parse version: invalid version format."); - - if (Value > IFSVersionCurrent) - return StringRef("Unsupported IFS version."); - - // Returning empty StringRef indicates successful parse. - return StringRef(); - } - - // Don't place quotation marks around version value. - static QuotingType mustQuote(StringRef) { return QuotingType::None; } -}; - /// YAML traits for IFSSymbol. template <> struct MappingTraits { static void mapping(IO &IO, IFSSymbol &Symbol) { @@ -210,6 +189,11 @@ if (std::error_code Err = YamlIn.error()) return createStringError(Err, "Failed reading Interface Stub File."); + if (Stub->IfsVersion > IFSVersionCurrent) + return make_error( + "IFS version " + Stub->IfsVersion.getAsString() + " is unsupported.", + std::make_error_code(std::errc::invalid_argument)); + return std::move(Stub); } diff --git a/llvm/unittests/InterfaceStub/ELFYAMLTest.cpp b/llvm/unittests/InterfaceStub/ELFYAMLTest.cpp --- a/llvm/unittests/InterfaceStub/ELFYAMLTest.cpp +++ b/llvm/unittests/InterfaceStub/ELFYAMLTest.cpp @@ -144,6 +144,18 @@ ASSERT_THAT_ERROR(StubOrErr.takeError(), Failed()); } +TEST(ElfYamlTextAPI, YAMLUnsupportedVersion) { + const char Data[] = "--- !tapi-tbe\n" + "TbeVersion: 9.9.9\n" + "SoName: test.so\n" + "Arch: x86_64\n" + "Symbols: {}\n" + "...\n"; + Expected> StubOrErr = readTBEFromBuffer(Data); + std::string ErrorMessage = toString(StubOrErr.takeError()); + EXPECT_EQ("TBE version 9.9.9 is unsupported.", ErrorMessage); +} + TEST(ElfYamlTextAPI, YAMLWritesTBESymbols) { const char Expected[] = "--- !tapi-tbe\n"