Skip to content

Commit 7f36ab1

Browse files
author
David Ungar
committed
Allow Fingerprint::fromString to fail, returning None on bad input.
1 parent 2ffa369 commit 7f36ab1

File tree

5 files changed

+24
-25
lines changed

5 files changed

+24
-25
lines changed

include/swift/Basic/Fingerprint.h

+5-15
Original file line numberDiff line numberDiff line change
@@ -71,22 +71,12 @@ class Fingerprint final {
7171
explicit Fingerprint(Fingerprint::Core value) : core(value) {}
7272

7373
/// Creates a fingerprint value from the given input string that is known to
74-
/// be a 32-byte hash value.
74+
/// be a 32-byte hash value, i.e. that represent a valid 32-bit hex integer.
7575
///
76-
/// In +asserts builds, strings that violate this invariant will crash. If a
77-
/// fingerprint value is needed to represent an "invalid" state, use a
78-
/// vocabulary type like \c Optional<Fingerprint> instead.
79-
static Fingerprint fromString(llvm::StringRef value);
80-
81-
/// Creates a fingerprint value from the given input string literal.
82-
template <std::size_t N>
83-
explicit Fingerprint(const char (&literal)[N])
84-
: Fingerprint{Fingerprint::fromString({literal, N-1}).core} {
85-
static_assert(N == Fingerprint::DIGEST_LENGTH + 1,
86-
"String literal must be 32 bytes in length!");
87-
}
88-
89-
/// Creates a fingerprint value by consuming the given \c MD5Result from LLVM.
76+
/// Strings that violate this invariant will return a null optional.
77+
static llvm::Optional<Fingerprint> fromString(llvm::StringRef value);
78+
79+
/// Creates a fingerprint value by consuming the given \c MD5Result from LLVM.
9080
explicit Fingerprint(llvm::MD5::MD5Result &&MD5Value)
9181
: core{MD5Value.words()} {}
9282

lib/AST/FineGrainedDependencyFormat.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,10 @@ bool Deserializer::readFineGrainedDependencyGraph(SourceFileDepGraph &g,
231231
// FINGERPRINT_NODE must follow a SOURCE_FILE_DEP_GRAPH_NODE.
232232
if (node == nullptr)
233233
llvm::report_fatal_error("Unexpected FINGERPRINT_NODE record");
234-
235-
node->setFingerprint(Fingerprint::fromString(BlobData));
234+
if (auto fingerprint = Fingerprint::fromString(BlobData))
235+
node->setFingerprint(fingerprint.getValue());
236+
else
237+
llvm::report_fatal_error("Unconvertable FINGERPRINT_NODE record");
236238
break;
237239
}
238240

lib/Basic/Fingerprint.cpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ void swift::simple_display(llvm::raw_ostream &out, const Fingerprint &fp) {
2929
out << fp.getRawValue();
3030
}
3131

32-
Fingerprint Fingerprint::fromString(StringRef value) {
32+
Optional<Fingerprint> Fingerprint::fromString(StringRef value) {
3333
assert(value.size() == Fingerprint::DIGEST_LENGTH &&
3434
"Only supports 32-byte hash values!");
3535
auto fp = Fingerprint::ZERO();
@@ -41,11 +41,10 @@ Fingerprint Fingerprint::fromString(StringRef value) {
4141
std::istringstream s(value.drop_front(Fingerprint::DIGEST_LENGTH/2).str());
4242
s >> std::hex >> fp.core.second;
4343
}
44-
if (value != fp.getRawValue()) {
45-
llvm::errs() << "Fingerprint conversion failed; perhaps '" << value << "' is not a hex number";
46-
llvm::errs().flush();
47-
exit(1);
48-
}
44+
// If the input string is not valid hex, the conversion above can fail.
45+
if (value != fp.getRawValue())
46+
return None;
47+
4948
return fp;
5049
}
5150

lib/Serialization/ModuleFileCoreTableInfo.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,10 @@ class ModuleFileSharedCore::DeclFingerprintsTableInfo {
602602
using namespace llvm::support;
603603
auto str = llvm::StringRef{reinterpret_cast<const char *>(data),
604604
Fingerprint::DIGEST_LENGTH};
605-
return Fingerprint::fromString(str);
605+
if (auto fp = Fingerprint::fromString(str))
606+
return fp.getValue();
607+
llvm::errs() << "Unconvertable fingerprint\n";
608+
abort();
606609
}
607610
};
608611

tools/swift-dependency-tool/swift-dependency-tool.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,12 @@ template <> struct ScalarTraits<swift::Fingerprint> {
6969
os << fp.getRawValue();
7070
}
7171
static StringRef input(StringRef s, void *, swift::Fingerprint &fp) {
72-
fp = swift::Fingerprint::fromString(s);
72+
if (auto convertedFP = swift::Fingerprint::fromString(s))
73+
fp = convertedFP.getValue();
74+
else {
75+
llvm::errs() << "Failed to convert fingerprint '" << s << "'\n";
76+
exit(1);
77+
}
7378
return StringRef();
7479
}
7580
static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }

0 commit comments

Comments
 (0)