Skip to content

Commit acb33cb

Browse files
committed
[llvm] Fix ODRViolations for VersionTuple YAML specializations NFC
It appears for Swift there was confusing errors when trying to parse APINotes, when libAPINotes and libInterfaceStub are linked, they both export symbol `__ZN4llvm4yaml7yamlizeINS_12VersionTupleEEENSt3__19enable_ifIXsr16has_ScalarTraitsIT_EE5valueEvE4typeERNS0_2IOERS5_bRNS0_12EmptyContextE`, and discovered same symbol defined within llvm-ifs. This consolidates the boilerplate into YAMLTraits and defers the specific validation in reading the whole input. fixes: rdar://problem/70450563 Reviewed By: phosek, dblaikie Differential Revision: https://reviews.llvm.org/D89764
1 parent 4aa97e3 commit acb33cb

File tree

5 files changed

+41
-43
lines changed

5 files changed

+41
-43
lines changed

llvm/include/llvm/Support/YAMLTraits.h

+7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/Support/Endian.h"
2121
#include "llvm/Support/Regex.h"
2222
#include "llvm/Support/SourceMgr.h"
23+
#include "llvm/Support/VersionTuple.h"
2324
#include "llvm/Support/YAMLParser.h"
2425
#include "llvm/Support/raw_ostream.h"
2526
#include <cassert>
@@ -1711,6 +1712,12 @@ struct ScalarTraits<Hex64> {
17111712
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
17121713
};
17131714

1715+
template <> struct ScalarTraits<VersionTuple> {
1716+
static void output(const VersionTuple &Value, void *, llvm::raw_ostream &Out);
1717+
static StringRef input(StringRef, void *, VersionTuple &);
1718+
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1719+
};
1720+
17141721
// Define non-member operator>> so that Input can stream in a document list.
17151722
template <typename T>
17161723
inline std::enable_if_t<has_DocumentListTraits<T>::value, Input &>

llvm/lib/InterfaceStub/TBEHandler.cpp

+5-22
Original file line numberDiff line numberDiff line change
@@ -69,28 +69,6 @@ template <> struct ScalarTraits<ELFArchMapper> {
6969
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
7070
};
7171

72-
/// YAML traits for TbeVersion.
73-
template <> struct ScalarTraits<VersionTuple> {
74-
static void output(const VersionTuple &Value, void *,
75-
llvm::raw_ostream &Out) {
76-
Out << Value.getAsString();
77-
}
78-
79-
static StringRef input(StringRef Scalar, void *, VersionTuple &Value) {
80-
if (Value.tryParse(Scalar))
81-
return StringRef("Can't parse version: invalid version format.");
82-
83-
if (Value > TBEVersionCurrent)
84-
return StringRef("Unsupported TBE version.");
85-
86-
// Returning empty StringRef indicates successful parse.
87-
return StringRef();
88-
}
89-
90-
// Don't place quotation marks around version value.
91-
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
92-
};
93-
9472
/// YAML traits for ELFSymbol.
9573
template <> struct MappingTraits<ELFSymbol> {
9674
static void mapping(IO &IO, ELFSymbol &Symbol) {
@@ -149,6 +127,11 @@ Expected<std::unique_ptr<ELFStub>> elfabi::readTBEFromBuffer(StringRef Buf) {
149127
if (std::error_code Err = YamlIn.error())
150128
return createStringError(Err, "YAML failed reading as TBE");
151129

130+
if (Stub->TbeVersion > elfabi::TBEVersionCurrent)
131+
return make_error<StringError>(
132+
"TBE version " + Stub->TbeVersion.getAsString() + " is unsupported.",
133+
std::make_error_code(std::errc::invalid_argument));
134+
152135
return std::move(Stub);
153136
}
154137

llvm/lib/Support/YAMLTraits.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -1102,3 +1102,15 @@ StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
11021102
Val = Num;
11031103
return StringRef();
11041104
}
1105+
1106+
void ScalarTraits<VersionTuple>::output(const VersionTuple &Val, void *,
1107+
llvm::raw_ostream &Out) {
1108+
Out << Val.getAsString();
1109+
}
1110+
1111+
StringRef ScalarTraits<VersionTuple>::input(StringRef Scalar, void *,
1112+
VersionTuple &Val) {
1113+
if (Val.tryParse(Scalar))
1114+
return "invalid version format";
1115+
return StringRef();
1116+
}

llvm/tools/llvm-ifs/llvm-ifs.cpp

+5-21
Original file line numberDiff line numberDiff line change
@@ -104,27 +104,6 @@ template <> struct ScalarEnumerationTraits<IFSSymbolType> {
104104
}
105105
};
106106

107-
template <> struct ScalarTraits<VersionTuple> {
108-
static void output(const VersionTuple &Value, void *,
109-
llvm::raw_ostream &Out) {
110-
Out << Value.getAsString();
111-
}
112-
113-
static StringRef input(StringRef Scalar, void *, VersionTuple &Value) {
114-
if (Value.tryParse(Scalar))
115-
return StringRef("Can't parse version: invalid version format.");
116-
117-
if (Value > IFSVersionCurrent)
118-
return StringRef("Unsupported IFS version.");
119-
120-
// Returning empty StringRef indicates successful parse.
121-
return StringRef();
122-
}
123-
124-
// Don't place quotation marks around version value.
125-
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
126-
};
127-
128107
/// YAML traits for IFSSymbol.
129108
template <> struct MappingTraits<IFSSymbol> {
130109
static void mapping(IO &IO, IFSSymbol &Symbol) {
@@ -210,6 +189,11 @@ static Expected<std::unique_ptr<IFSStub>> readInputFile(StringRef FilePath) {
210189
if (std::error_code Err = YamlIn.error())
211190
return createStringError(Err, "Failed reading Interface Stub File.");
212191

192+
if (Stub->IfsVersion > IFSVersionCurrent)
193+
return make_error<StringError>(
194+
"IFS version " + Stub->IfsVersion.getAsString() + " is unsupported.",
195+
std::make_error_code(std::errc::invalid_argument));
196+
213197
return std::move(Stub);
214198
}
215199

llvm/unittests/InterfaceStub/ELFYAMLTest.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,18 @@ TEST(ElfYamlTextAPI, YAMLUnreadableTBE) {
144144
ASSERT_THAT_ERROR(StubOrErr.takeError(), Failed());
145145
}
146146

147+
TEST(ElfYamlTextAPI, YAMLUnsupportedVersion) {
148+
const char Data[] = "--- !tapi-tbe\n"
149+
"TbeVersion: 9.9.9\n"
150+
"SoName: test.so\n"
151+
"Arch: x86_64\n"
152+
"Symbols: {}\n"
153+
"...\n";
154+
Expected<std::unique_ptr<ELFStub>> StubOrErr = readTBEFromBuffer(Data);
155+
std::string ErrorMessage = toString(StubOrErr.takeError());
156+
EXPECT_EQ("TBE version 9.9.9 is unsupported.", ErrorMessage);
157+
}
158+
147159
TEST(ElfYamlTextAPI, YAMLWritesTBESymbols) {
148160
const char Expected[] =
149161
"--- !tapi-tbe\n"

0 commit comments

Comments
 (0)