Skip to content

Commit

Permalink
Allow Fingerprint::fromString to fail, returning None on bad input.
Browse files Browse the repository at this point in the history
  • Loading branch information
David Ungar committed Jan 15, 2021
1 parent 2ffa369 commit 7f36ab1
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 25 deletions.
20 changes: 5 additions & 15 deletions include/swift/Basic/Fingerprint.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,12 @@ class Fingerprint final {
explicit Fingerprint(Fingerprint::Core value) : core(value) {}

/// Creates a fingerprint value from the given input string that is known to
/// be a 32-byte hash value.
/// be a 32-byte hash value, i.e. that represent a valid 32-bit hex integer.
///
/// In +asserts builds, strings that violate this invariant will crash. If a
/// fingerprint value is needed to represent an "invalid" state, use a
/// vocabulary type like \c Optional<Fingerprint> instead.
static Fingerprint fromString(llvm::StringRef value);

/// Creates a fingerprint value from the given input string literal.
template <std::size_t N>
explicit Fingerprint(const char (&literal)[N])
: Fingerprint{Fingerprint::fromString({literal, N-1}).core} {
static_assert(N == Fingerprint::DIGEST_LENGTH + 1,
"String literal must be 32 bytes in length!");
}

/// Creates a fingerprint value by consuming the given \c MD5Result from LLVM.
/// Strings that violate this invariant will return a null optional.
static llvm::Optional<Fingerprint> fromString(llvm::StringRef value);

/// Creates a fingerprint value by consuming the given \c MD5Result from LLVM.
explicit Fingerprint(llvm::MD5::MD5Result &&MD5Value)
: core{MD5Value.words()} {}

Expand Down
6 changes: 4 additions & 2 deletions lib/AST/FineGrainedDependencyFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,10 @@ bool Deserializer::readFineGrainedDependencyGraph(SourceFileDepGraph &g,
// FINGERPRINT_NODE must follow a SOURCE_FILE_DEP_GRAPH_NODE.
if (node == nullptr)
llvm::report_fatal_error("Unexpected FINGERPRINT_NODE record");

node->setFingerprint(Fingerprint::fromString(BlobData));
if (auto fingerprint = Fingerprint::fromString(BlobData))
node->setFingerprint(fingerprint.getValue());
else
llvm::report_fatal_error("Unconvertable FINGERPRINT_NODE record");
break;
}

Expand Down
11 changes: 5 additions & 6 deletions lib/Basic/Fingerprint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void swift::simple_display(llvm::raw_ostream &out, const Fingerprint &fp) {
out << fp.getRawValue();
}

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

return fp;
}

Expand Down
5 changes: 4 additions & 1 deletion lib/Serialization/ModuleFileCoreTableInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,10 @@ class ModuleFileSharedCore::DeclFingerprintsTableInfo {
using namespace llvm::support;
auto str = llvm::StringRef{reinterpret_cast<const char *>(data),
Fingerprint::DIGEST_LENGTH};
return Fingerprint::fromString(str);
if (auto fp = Fingerprint::fromString(str))
return fp.getValue();
llvm::errs() << "Unconvertable fingerprint\n";
abort();
}
};

Expand Down
7 changes: 6 additions & 1 deletion tools/swift-dependency-tool/swift-dependency-tool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,12 @@ template <> struct ScalarTraits<swift::Fingerprint> {
os << fp.getRawValue();
}
static StringRef input(StringRef s, void *, swift::Fingerprint &fp) {
fp = swift::Fingerprint::fromString(s);
if (auto convertedFP = swift::Fingerprint::fromString(s))
fp = convertedFP.getValue();
else {
llvm::errs() << "Failed to convert fingerprint '" << s << "'\n";
exit(1);
}
return StringRef();
}
static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
Expand Down

0 comments on commit 7f36ab1

Please sign in to comment.