Skip to content

Commit 0c99379

Browse files
author
David Ungar
authored
Merge pull request #35405 from davidungar/fingerprint-assert
2 parents b263e99 + dbe4b6d commit 0c99379

34 files changed

+109
-69
lines changed

include/swift/Basic/Fingerprint.h

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -71,22 +71,16 @@ 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+
/// For mocking only:
80+
/// Aborts if unconvertible, returns None for an empty string.
81+
static llvm::Optional<Fingerprint> mockFromString(llvm::StringRef value);
82+
83+
/// Creates a fingerprint value by consuming the given \c MD5Result from LLVM.
9084
explicit Fingerprint(llvm::MD5::MD5Result &&MD5Value)
9185
: core{MD5Value.words()} {}
9286

lib/AST/FineGrainedDependencyFormat.cpp

Lines changed: 4 additions & 2 deletions
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(Twine("Unconvertable FINGERPRINT_NODE record: '") + BlobData + "'" );
236238
break;
237239
}
238240

lib/Basic/Fingerprint.cpp

Lines changed: 23 additions & 2 deletions
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,14 +41,35 @@ 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 the input string is not valid hex, the conversion above can fail.
45+
if (value != fp.getRawValue())
46+
return None;
47+
4448
return fp;
4549
}
4650

51+
Optional<Fingerprint> Fingerprint::mockFromString(llvm::StringRef value) {
52+
auto contents = value.str();
53+
const auto n = value.size();
54+
if (n == 0 || n > Fingerprint::DIGEST_LENGTH)
55+
return None;
56+
// Insert at start so that "1" and "10" are distinct
57+
contents.insert(0, Fingerprint::DIGEST_LENGTH - n, '0');
58+
auto fingerprint = fromString(contents);
59+
if (!fingerprint) {
60+
llvm::errs() << "unconvertable fingerprint from switdeps ':"
61+
<< contents << "'\n";
62+
abort();
63+
}
64+
return fingerprint;
65+
}
66+
67+
68+
4769
llvm::SmallString<Fingerprint::DIGEST_LENGTH> Fingerprint::getRawValue() const {
4870
llvm::SmallString<Fingerprint::DIGEST_LENGTH> Str;
4971
llvm::raw_svector_ostream Res(Str);
5072
Res << llvm::format_hex_no_prefix(core.first, 16);
5173
Res << llvm::format_hex_no_prefix(core.second, 16);
52-
assert(*this == Fingerprint::fromString(Str));
5374
return Str;
5475
}

lib/Serialization/ModuleFile.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,12 @@ void ModuleFile::collectBasicSourceFileInfo(
986986

987987
BasicSourceFileInfo info;
988988
info.FilePath = filePath;
989-
info.InterfaceHash = Fingerprint::fromString(fpStr);
989+
if (auto fingerprint = Fingerprint::fromString(fpStr))
990+
info.InterfaceHash = fingerprint.getValue();
991+
else {
992+
llvm::errs() << "Unconvertable fingerprint '" << fpStr << "'\n";
993+
abort();
994+
}
990995
info.LastModified =
991996
llvm::sys::TimePoint<>(std::chrono::nanoseconds(timestamp));
992997
info.FileSize = fileSize;

lib/Serialization/ModuleFileCoreTableInfo.h

Lines changed: 4 additions & 1 deletion
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 '" << str << "'\n";
608+
abort();
606609
}
607610
};
608611

test/Driver/Dependencies/Inputs/chained-private-after-fine/main.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ allNodes:
66
aspect: interface
77
context: ''
88
name: main.swiftdeps
9-
fingerprint: afterachangewasmadetoswiftsource
9+
fingerprint: 88888888888888888888888888888888
1010
sequenceNumber: 0
1111
defsIDependUpon: [ 2, 4 ]
1212
isProvides: true
@@ -15,7 +15,7 @@ allNodes:
1515
aspect: implementation
1616
context: ''
1717
name: main.swiftdeps
18-
fingerprint: afterachangewasmadetoswiftsource
18+
fingerprint: 88888888888888888888888888888888
1919
sequenceNumber: 1
2020
defsIDependUpon: [ ]
2121
isProvides: true
Binary file not shown.

test/Driver/Dependencies/Inputs/fail-interface-hash-fine/bad.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ allNodes:
66
aspect: interface
77
context: ''
88
name: bad.swiftdeps
9-
fingerprint: afterachangewasmadetoswiftsource
9+
fingerprint: 22222222222222222222222222222222
1010
sequenceNumber: 0
1111
defsIDependUpon: [ 2 ]
1212
isProvides: true
@@ -15,7 +15,7 @@ allNodes:
1515
aspect: implementation
1616
context: ''
1717
name: bad.swiftdeps
18-
fingerprint: afterachangewasmadetoswiftsource
18+
fingerprint: 22222222222222222222222222222222
1919
sequenceNumber: 1
2020
defsIDependUpon: [ ]
2121
isProvides: true
Binary file not shown.

test/Driver/Dependencies/Inputs/fail-interface-hash-fine/depends-on-bad.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ allNodes:
66
aspect: interface
77
context: ''
88
name: dependsonbad.swiftdeps
9-
fingerprint: afterachangewasmadetoswiftsource
9+
fingerprint: 22222222222222222222222222222222
1010
sequenceNumber: 0
1111
defsIDependUpon: [ 2 ]
1212
isProvides: true
@@ -15,7 +15,7 @@ allNodes:
1515
aspect: implementation
1616
context: ''
1717
name: dependsonbad.swiftdeps
18-
fingerprint: afterachangewasmadetoswiftsource
18+
fingerprint: 22222222222222222222222222222222
1919
sequenceNumber: 1
2020
defsIDependUpon: [ ]
2121
isProvides: true
Binary file not shown.

test/Driver/Dependencies/Inputs/fail-interface-hash-fine/depends-on-main.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ allNodes:
66
aspect: interface
77
context: ''
88
name: dependsonmain.swiftdeps
9-
fingerprint: afterachangewasmadetoswiftsource
9+
fingerprint: 22222222222222222222222222222222
1010
sequenceNumber: 0
1111
defsIDependUpon: [ 2 ]
1212
isProvides: true
@@ -15,7 +15,7 @@ allNodes:
1515
aspect: implementation
1616
context: ''
1717
name: dependsonmain.swiftdeps
18-
fingerprint: afterachangewasmadetoswiftsource
18+
fingerprint: 22222222222222222222222222222222
1919
sequenceNumber: 1
2020
defsIDependUpon: [ ]
2121
isProvides: true

test/Driver/Dependencies/Inputs/fail-interface-hash-fine/main.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ allNodes:
66
aspect: interface
77
context: ''
88
name: main.swiftdeps
9-
fingerprint: afterachangewasmadetoswiftsource
9+
fingerprint: 22222222222222222222222222222222
1010
sequenceNumber: 0
1111
defsIDependUpon: [ 2 ]
1212
isProvides: true
@@ -15,7 +15,7 @@ allNodes:
1515
aspect: implementation
1616
context: ''
1717
name: main.swiftdeps
18-
fingerprint: afterachangewasmadetoswiftsource
18+
fingerprint: 22222222222222222222222222222222
1919
sequenceNumber: 1
2020
defsIDependUpon: [ ]
2121
isProvides: true
Binary file not shown.

test/Driver/Dependencies/Inputs/fail-with-bad-deps-fine/bad.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ allNodes:
66
aspect: interface
77
context: ''
88
name: './bad.swiftdeps'
9-
fingerprint: afterachangewasmadetoswiftsource
9+
fingerprint: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1010
sequenceNumber: 0
1111
defsIDependUpon: [ 2, 5, 4 ]
1212
isProvides: true
@@ -15,7 +15,7 @@ allNodes:
1515
aspect: implementation
1616
context: ''
1717
name: './bad.swiftdeps'
18-
fingerprint: afterachangewasmadetoswiftsource
18+
fingerprint: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1919
sequenceNumber: 1
2020
defsIDependUpon: [ ]
2121
isProvides: true
Binary file not shown.

test/Driver/Dependencies/Inputs/fail-with-bad-deps-fine/depends-on-bad.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ allNodes:
66
aspect: interface
77
context: ''
88
name: './depends-on-bad.swiftdeps'
9-
fingerprint: afterachangewasmadetoswiftsource
9+
fingerprint: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1010
sequenceNumber: 0
1111
defsIDependUpon: [ 2, 4 ]
1212
isProvides: true
@@ -15,7 +15,7 @@ allNodes:
1515
aspect: implementation
1616
context: ''
1717
name: './depends-on-bad.swiftdeps'
18-
fingerprint: afterachangewasmadetoswiftsource
18+
fingerprint: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1919
sequenceNumber: 1
2020
defsIDependUpon: [ ]
2121
isProvides: true
Binary file not shown.

test/Driver/Dependencies/Inputs/fail-with-bad-deps-fine/depends-on-main.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ allNodes:
66
aspect: interface
77
context: ''
88
name: './depends-on-main.swiftdeps'
9-
fingerprint: afterachangewasmadetoswiftsource
9+
fingerprint: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1010
sequenceNumber: 0
1111
defsIDependUpon: [ 2, 4 ]
1212
isProvides: true
@@ -15,7 +15,7 @@ allNodes:
1515
aspect: implementation
1616
context: ''
1717
name: './depends-on-main.swiftdeps'
18-
fingerprint: afterachangewasmadetoswiftsource
18+
fingerprint: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1919
sequenceNumber: 1
2020
defsIDependUpon: [ ]
2121
isProvides: true
Binary file not shown.

test/Driver/Dependencies/Inputs/fail-with-bad-deps-fine/main.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ allNodes:
66
aspect: interface
77
context: ''
88
name: './depends-on-main.swiftdeps'
9-
fingerprint: afterachangewasmadetoswiftsource
9+
fingerprint: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1010
sequenceNumber: 0
1111
defsIDependUpon: [ 2, 4 ]
1212
isProvides: true
@@ -15,7 +15,7 @@ allNodes:
1515
aspect: implementation
1616
context: ''
1717
name: './depends-on-main.swiftdeps'
18-
fingerprint: afterachangewasmadetoswiftsource
18+
fingerprint: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1919
sequenceNumber: 1
2020
defsIDependUpon: [ ]
2121
isProvides: true
Binary file not shown.

test/Driver/Dependencies/Inputs/mutual-fine/main.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ allNodes:
66
aspect: interface
77
context: ''
88
name: main.swiftdeps
9-
fingerprint: afterachangewasmadetoswiftsource
9+
fingerprint: 22222222222222222222222222222222
1010
sequenceNumber: 0
1111
defsIDependUpon: [ 4, 8, 2, 7, 6 ]
1212
isProvides: true
@@ -15,7 +15,7 @@ allNodes:
1515
aspect: implementation
1616
context: ''
1717
name: main.swiftdeps
18-
fingerprint: afterachangewasmadetoswiftsource
18+
fingerprint: 22222222222222222222222222222222
1919
sequenceNumber: 1
2020
defsIDependUpon: [ ]
2121
isProvides: true

test/Driver/Dependencies/Inputs/mutual-fine/other.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ allNodes:
66
aspect: interface
77
context: ''
88
name: other.swiftdeps
9-
fingerprint: sameasiteverwassameasiteverwassa
9+
fingerprint: 11111111111111111111111111111111
1010
sequenceNumber: 0
1111
defsIDependUpon: [ 8, 7, 2, 4, 6 ]
1212
isProvides: true
@@ -15,7 +15,7 @@ allNodes:
1515
aspect: implementation
1616
context: ''
1717
name: other.swiftdeps
18-
fingerprint: sameasiteverwassameasiteverwassa
18+
fingerprint: 11111111111111111111111111111111
1919
sequenceNumber: 1
2020
defsIDependUpon: [ ]
2121
isProvides: true

test/Driver/Dependencies/Inputs/mutual-interface-hash-fine/does-change.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ allNodes:
66
aspect: interface
77
context: ''
88
name: does-change.swiftdeps
9-
fingerprint: afterachangewasmadetoswiftsource
9+
fingerprint: 22222222222222222222222222222222
1010
sequenceNumber: 0
1111
defsIDependUpon: [ 4, 8, 2, 7, 6 ]
1212
isProvides: true
@@ -15,7 +15,7 @@ allNodes:
1515
aspect: implementation
1616
context: ''
1717
name: does-change.swiftdeps
18-
fingerprint: afterachangewasmadetoswiftsource
18+
fingerprint: 22222222222222222222222222222222
1919
sequenceNumber: 1
2020
defsIDependUpon: [ ]
2121
isProvides: true
Binary file not shown.

test/Driver/Dependencies/Inputs/mutual-interface-hash-fine/does-not-change.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ allNodes:
66
aspect: interface
77
context: ''
88
name: does-not-change.swiftdeps
9-
fingerprint: sameasiteverwassameasiteverwassa
9+
fingerprint: 11111111111111111111111111111111
1010
sequenceNumber: 0
1111
defsIDependUpon: [ 8, 7, 2, 4, 6 ]
1212
isProvides: true
@@ -15,7 +15,7 @@ allNodes:
1515
aspect: implementation
1616
context: ''
1717
name: does-not-change.swiftdeps
18-
fingerprint: sameasiteverwassameasiteverwassa
18+
fingerprint: 11111111111111111111111111111111
1919
sequenceNumber: 1
2020
defsIDependUpon: [ ]
2121
isProvides: true
Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
// XFAIL: linux, openbsd
1+
// XFAIL: linux, openbsd, windows
22

33
// RUN: %empty-directory(%t)
44
// RUN: cp -r %S/Inputs/only-skip-once/* %t
55
// RUN: touch -t 201401240005 %t/*
66

7-
// RUN: cd %t && %target-swiftc_driver -driver-show-job-lifecycle -output-file-map %t/output-file-map.json -incremental main.swift file1.swift file2.swift -j1 2>%t/stderr.txt | %FileCheck -check-prefix=CHECK-INITIAL %s
7+
// RUN: cd %t && %target-swiftc_driver -driver-show-job-lifecycle -output-file-map %t/output-file-map.json -incremental main.swift file1.swift file2.swift -j1 2>&1 | tee /tmp/x | %FileCheck -check-prefix=CHECK-INITIAL %s
88

9-
// CHECK-INITIAL: Job finished: {compile: main.o <= main.swift}
10-
// CHECK-INITIAL: Job finished: {compile: file1.o <= file1.swift}
11-
// CHECK-INITIAL: Job finished: {compile: file2.o <= file2.swift}
12-
// CHECK-INITIAL: Job finished: {link: main <= main.o file1.o file2.o}
9+
// CHECK-INITIAL: {{(Job finished: {compile: main.o <= main.swift}|Finished Compiling main.swift)}}
10+
// CHECK-INITIAL: {{(Job finished: {compile: file1.o <= file1.swift}|Finished Compiling file1.swift)}}
11+
// CHECK-INITIAL: {{(Job finished: {compile: file2.o <= file2.swift}|Finished Compiling file2.swift)}}
12+
// CHECK-INITIAL: {{(Job finished: {link: main <= main.o file1.o file2.o}|Finished Linking main)}}
1313

1414
// RUN: touch -t 201401240006 %t/file2.swift
15-
// RUN: cd %t && %target-swiftc_driver -driver-show-job-lifecycle -output-file-map %t/output-file-map.json -incremental main.swift file1.swift file2.swift -j1 2>%t/stderr.txt | %FileCheck -check-prefix=CHECK-REBUILD %s
15+
// RUN: cd %t && %target-swiftc_driver -driver-show-job-lifecycle -output-file-map %t/output-file-map.json -incremental main.swift file1.swift file2.swift -j1 2>&1 |tee /tmp/y | %FileCheck -check-prefix=CHECK-REBUILD %s
1616

1717
// We should skip the main and file1 rebuilds here, but we should only note skipping them _once_
18-
// CHECK-REBUILD: Job finished: {compile: file2.o <= file2.swift}
19-
// CHECK-REBUILD: Job skipped: {compile: main.o <= main.swift}
20-
// CHECK-REBUILD: Job skipped: {compile: file1.o <= file1.swift}
21-
// CHECK-REBUILD: Job finished: {link: main <= main.o file1.o file2.o}
22-
// CHECK-REBUILD-NOT: Job skipped:
18+
// CHECK-REBUILD-DAG: {{(Job finished: {compile: file2.o <= file2.swift}|Finished Compiling file2.swift)}}
19+
// CHECK-REBUILD-DAG: {{(Job skipped: {compile: main.o <= main.swift}|Skipped Compiling main.swift)}}
20+
// CHECK-REBUILD-DAG: {{(Job skipped: {compile: file1.o <= file1.swift}|Skipped Compiling file1.swift)}}
21+
// CHECK-REBUILD-DAG: {{(Job finished: {link: main <= main.o file1.o file2.o}|Finished Linking main)}}
22+
// CHECK-REBUILD-NOT: {{(Job skipped:|Skipped)}}

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

Lines changed: 6 additions & 1 deletion
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)