Skip to content

Commit 5c3a580

Browse files
authored
Merge pull request #68195 from gottesmm/pr-1f647dd0c785123c93b7a25e78addfca45c2b473
[send-non-sendable] Convert some of the concurrency tests that test targeted concurrency to also test complete and complete + sis
2 parents f6a4aa1 + e8448ee commit 5c3a580

File tree

106 files changed

+824
-254
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+824
-254
lines changed

include/swift/Basic/DiagnosticOptions.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ class DiagnosticOptions {
8383
/// Path to a directory of diagnostic localization tables.
8484
std::string LocalizationPath = "";
8585

86+
/// A list of prefixes that are appended to expected- that the diagnostic
87+
/// verifier should check for diagnostics.
88+
///
89+
/// For example, if one placed the phrase "NAME", the verifier will check for:
90+
/// expected-$NAME{error,note,warning,remark} as well as the normal expected-
91+
/// prefixes.
92+
std::vector<std::string> AdditionalDiagnosticVerifierPrefixes;
93+
8694
/// Return a hash code of any components from these options that should
8795
/// contribute to a Swift Bridging PCH hash.
8896
llvm::hash_code getPCHHashComponents() const {

include/swift/Frontend/DiagnosticVerifier.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,15 @@ class DiagnosticVerifier : public DiagnosticConsumer {
9494
SmallVector<unsigned, 4> AdditionalBufferIDs;
9595
bool AutoApplyFixes;
9696
bool IgnoreUnknown;
97+
ArrayRef<std::string> AdditionalExpectedPrefixes;
9798

9899
public:
99100
explicit DiagnosticVerifier(SourceManager &SM, ArrayRef<unsigned> BufferIDs,
100-
bool AutoApplyFixes, bool IgnoreUnknown)
101+
bool AutoApplyFixes, bool IgnoreUnknown,
102+
ArrayRef<std::string> AdditionalExpectedPrefixes)
101103
: SM(SM), BufferIDs(BufferIDs), AutoApplyFixes(AutoApplyFixes),
102-
IgnoreUnknown(IgnoreUnknown) {}
104+
IgnoreUnknown(IgnoreUnknown),
105+
AdditionalExpectedPrefixes(AdditionalExpectedPrefixes) {}
103106

104107
void appendAdditionalBufferID(unsigned bufferID) {
105108
AdditionalBufferIDs.push_back(bufferID);

include/swift/Option/FrontendOptions.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ def verify : Flag<["-"], "verify">,
111111
"annotations">;
112112
def verify_additional_file : Separate<["-"], "verify-additional-file">,
113113
HelpText<"Verify diagnostics in this file in addition to source files">;
114+
def verify_additional_prefix : Separate<["-"], "verify-additional-prefix">,
115+
HelpText<"Check for diagnostics with the prefix expected-<PREFIX> as well as expected-">;
114116
def verify_apply_fixes : Flag<["-"], "verify-apply-fixes">,
115117
HelpText<"Like -verify, but updates the original source file">;
116118
def verify_ignore_unknown: Flag<["-"], "verify-ignore-unknown">,

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,6 +1795,8 @@ static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
17951795

17961796
for (Arg *A : Args.filtered(OPT_verify_additional_file))
17971797
Opts.AdditionalVerifierFiles.push_back(A->getValue());
1798+
for (Arg *A : Args.filtered(OPT_verify_additional_prefix))
1799+
Opts.AdditionalDiagnosticVerifierPrefixes.push_back(A->getValue());
17981800

17991801
Opts.UseColor |=
18001802
Args.hasFlag(OPT_color_diagnostics,

lib/Frontend/DiagnosticVerifier.cpp

Lines changed: 109 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,81 @@
2626

2727
using namespace swift;
2828

29+
namespace {
30+
31+
struct ExpectedCheckMatchStartParser {
32+
StringRef MatchStart;
33+
const char *ClassificationStartLoc = nullptr;
34+
std::optional<DiagnosticKind> ExpectedClassification;
35+
36+
ExpectedCheckMatchStartParser(StringRef MatchStart)
37+
: MatchStart(MatchStart) {}
38+
39+
bool tryParseClassification() {
40+
if (MatchStart.startswith("note")) {
41+
ClassificationStartLoc = MatchStart.data();
42+
ExpectedClassification = DiagnosticKind::Note;
43+
MatchStart = MatchStart.substr(strlen("note"));
44+
return true;
45+
}
46+
47+
if (MatchStart.startswith("warning")) {
48+
ClassificationStartLoc = MatchStart.data();
49+
ExpectedClassification = DiagnosticKind::Warning;
50+
MatchStart = MatchStart.substr(strlen("warning"));
51+
return true;
52+
}
53+
54+
if (MatchStart.startswith("error")) {
55+
ClassificationStartLoc = MatchStart.data();
56+
ExpectedClassification = DiagnosticKind::Error;
57+
MatchStart = MatchStart.substr(strlen("error"));
58+
return true;
59+
}
60+
61+
if (MatchStart.startswith("remark")) {
62+
ClassificationStartLoc = MatchStart.data();
63+
ExpectedClassification = DiagnosticKind::Remark;
64+
MatchStart = MatchStart.substr(strlen("remark"));
65+
return true;
66+
}
67+
68+
return false;
69+
}
70+
71+
bool parse(ArrayRef<std::string> prefixes) {
72+
// First try to parse as if we did not have a prefix. We always parse at
73+
// least expected-*.
74+
if (tryParseClassification())
75+
return true;
76+
77+
// Otherwise, walk our prefixes until we find one that matches and attempt
78+
// to check for a note, warning, error, or remark.
79+
//
80+
// TODO: We could make this more flexible, but this should work in the
81+
// short term.
82+
for (auto &p : prefixes) {
83+
if (MatchStart.starts_with(p)) {
84+
MatchStart = MatchStart.substr(p.size());
85+
return tryParseClassification();
86+
}
87+
}
88+
89+
return false;
90+
}
91+
};
92+
93+
} // anonymous namespace
94+
2995
namespace swift {
96+
3097
struct ExpectedFixIt {
3198
const char *StartLoc, *EndLoc; // The loc of the {{ and }}'s.
3299
LineColumnRange Range;
33100

34101
std::string Text;
35102
};
103+
36104
} // end namespace swift
37105

38106
const LineColumnRange &
@@ -460,6 +528,28 @@ static llvm::Optional<LineColumnRange> parseExpectedFixItRange(
460528
return Range;
461529
}
462530

531+
/// Before we do anything, check if any of our prefixes are prefixes of later
532+
/// prefixes. In such a case, we will never actually pattern match the later
533+
/// prefix. In such a case, crash with a nice error message.
534+
static void validatePrefixList(ArrayRef<std::string> prefixes) {
535+
// Work backwards through the prefix list.
536+
while (!prefixes.empty()) {
537+
auto target = StringRef(prefixes.front());
538+
prefixes = prefixes.drop_front();
539+
540+
for (auto &p : prefixes) {
541+
if (StringRef(p).starts_with(target)) {
542+
llvm::errs() << "Error! Found a verifier diagnostic additional prefix "
543+
"that is a prefix of a later prefix. The later prefix "
544+
"will never be pattern matched!\n"
545+
<< "First Prefix: " << target << '\n'
546+
<< "Second Prefix: " << p << '\n';
547+
llvm::report_fatal_error("Standard compiler error!\n");
548+
}
549+
}
550+
}
551+
}
552+
463553
/// After the file has been processed, check to see if we got all of
464554
/// the expected diagnostics and check to see if there were any unexpected
465555
/// ones.
@@ -486,6 +576,10 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) {
486576
Errors.push_back(diag);
487577
};
488578

579+
// Validate that earlier prefixes are not prefixes of alter
580+
// prefixes... otherwise, we will never pattern match the later prefix.
581+
validatePrefixList(AdditionalExpectedPrefixes);
582+
489583
// Scan the memory buffer looking for expected-note/warning/error.
490584
for (size_t Match = InputFile.find("expected-");
491585
Match != StringRef::npos; Match = InputFile.find("expected-", Match+1)) {
@@ -494,23 +588,21 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) {
494588
StringRef MatchStart = InputFile.substr(Match);
495589
const char *DiagnosticLoc = MatchStart.data();
496590
MatchStart = MatchStart.substr(strlen("expected-"));
497-
const char *ClassificationStartLoc = MatchStart.data();
498591

499-
DiagnosticKind ExpectedClassification;
500-
if (MatchStart.startswith("note")) {
501-
ExpectedClassification = DiagnosticKind::Note;
502-
MatchStart = MatchStart.substr(strlen("note"));
503-
} else if (MatchStart.startswith("warning")) {
504-
ExpectedClassification = DiagnosticKind::Warning;
505-
MatchStart = MatchStart.substr(strlen("warning"));
506-
} else if (MatchStart.startswith("error")) {
507-
ExpectedClassification = DiagnosticKind::Error;
508-
MatchStart = MatchStart.substr(strlen("error"));
509-
} else if (MatchStart.startswith("remark")) {
510-
ExpectedClassification = DiagnosticKind::Remark;
511-
MatchStart = MatchStart.substr(strlen("remark"));
512-
} else
513-
continue;
592+
const char *ClassificationStartLoc = nullptr;
593+
std::optional<DiagnosticKind> ExpectedClassification;
594+
{
595+
ExpectedCheckMatchStartParser parser(MatchStart);
596+
// If we fail to parse... continue.
597+
if (!parser.parse(AdditionalExpectedPrefixes)) {
598+
continue;
599+
}
600+
MatchStart = parser.MatchStart;
601+
ClassificationStartLoc = parser.ClassificationStartLoc;
602+
ExpectedClassification = parser.ExpectedClassification;
603+
}
604+
assert(ClassificationStartLoc);
605+
assert(bool(ExpectedClassification));
514606

515607
// Skip any whitespace before the {{.
516608
MatchStart = MatchStart.substr(MatchStart.find_first_not_of(" \t"));
@@ -525,7 +617,7 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) {
525617

526618
ExpectedDiagnosticInfo Expected(DiagnosticLoc, ClassificationStartLoc,
527619
/*ClassificationEndLoc=*/MatchStart.data(),
528-
ExpectedClassification);
620+
*ExpectedClassification);
529621
int LineOffset = 0;
530622

531623
if (TextStartIdx > 0 && MatchStart[0] == '@') {

lib/Frontend/Frontend.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,8 @@ bool CompilerInstance::setupDiagnosticVerifierIfNeeded() {
363363
DiagVerifier = std::make_unique<DiagnosticVerifier>(
364364
SourceMgr, InputSourceCodeBufferIDs,
365365
diagOpts.VerifyMode == DiagnosticOptions::VerifyAndApplyFixes,
366-
diagOpts.VerifyIgnoreUnknown);
366+
diagOpts.VerifyIgnoreUnknown,
367+
diagOpts.AdditionalDiagnosticVerifierPrefixes);
367368
for (const auto &filename : diagOpts.AdditionalVerifierFiles) {
368369
auto result = getFileSystem().getBufferForFile(filename);
369370
if (!result) {

test/Concurrency/LLDBDebuggerFunctionActorExtension.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
// RUN: %target-typecheck-verify-swift -disable-availability-checking -debugger-support
1+
// RUN: %target-swift-frontend -disable-availability-checking -debugger-support %s -emit-sil -o /dev/null -verify
2+
// RUN: %target-swift-frontend -disable-availability-checking -debugger-support %s -emit-sil -o /dev/null -verify -strict-concurrency=targeted
3+
// RUN: %target-swift-frontend -disable-availability-checking -debugger-support %s -emit-sil -o /dev/null -verify -strict-concurrency=complete
4+
// RUN: %target-swift-frontend -disable-availability-checking -debugger-support %s -emit-sil -o /dev/null -verify -strict-concurrency=complete -enable-experimental-feature SendNonSendable
5+
26
// REQUIRES: concurrency
37

48
// This test simulates LLDB's expression evaluator making an otherwise illegal

test/Concurrency/actor_call_implicitly_async.swift

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
// RUN: %target-typecheck-verify-swift -disable-availability-checking -warn-concurrency -parse-as-library
1+
// RUN: %target-swift-frontend -disable-availability-checking -warn-concurrency -parse-as-library %s -emit-sil -o /dev/null -verify -verify-additional-prefix complete-
2+
// RUN: %target-swift-frontend -disable-availability-checking -warn-concurrency -parse-as-library %s -emit-sil -o /dev/null -verify -enable-experimental-feature SendNonSendable
3+
24
// REQUIRES: concurrency
35

46

@@ -289,8 +291,8 @@ func blender(_ peeler : () -> Void) {
289291

290292

291293
await wisk({})
292-
// expected-warning@-1{{passing argument of non-sendable type '() -> ()' into global actor 'BananaActor'-isolated context may introduce data races}}
293-
// expected-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
294+
// expected-complete-warning@-1{{passing argument of non-sendable type '() -> ()' into global actor 'BananaActor'-isolated context may introduce data races}}
295+
// expected-complete-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
294296
await wisk(1)
295297
await (peelBanana)()
296298
await (((((peelBanana)))))()
@@ -300,15 +302,15 @@ func blender(_ peeler : () -> Void) {
300302
// expected-warning@-1 2{{converting function value of type '@BananaActor () -> ()' to '() -> Void' loses global actor 'BananaActor'}}
301303

302304
await wisk(peelBanana)
303-
// expected-warning@-1{{passing argument of non-sendable type '() -> ()' into global actor 'BananaActor'-isolated context may introduce data races}}
304-
// expected-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
305+
// expected-complete-warning@-1{{passing argument of non-sendable type '() -> ()' into global actor 'BananaActor'-isolated context may introduce data races}}
306+
// expected-complete-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
305307

306308
await wisk(wisk)
307-
// expected-warning@-1{{passing argument of non-sendable type '(Any) -> ()' into global actor 'BananaActor'-isolated context may introduce data races}}
308-
// expected-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
309+
// expected-complete-warning@-1{{passing argument of non-sendable type '(Any) -> ()' into global actor 'BananaActor'-isolated context may introduce data races}}
310+
// expected-complete-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
309311
await (((wisk)))(((wisk)))
310-
// expected-warning@-1{{passing argument of non-sendable type '(Any) -> ()' into global actor 'BananaActor'-isolated context may introduce data races}}
311-
// expected-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
312+
// expected-complete-warning@-1{{passing argument of non-sendable type '(Any) -> ()' into global actor 'BananaActor'-isolated context may introduce data races}}
313+
// expected-complete-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
312314

313315
await {wisk}()(1)
314316

test/Concurrency/actor_defer.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
// RUN: %target-swift-frontend -parse-as-library -emit-sil -DNEGATIVES -verify %s
2+
// RUN: %target-swift-frontend -parse-as-library -emit-sil -DNEGATIVES -verify %s -strict-concurrency=targeted
3+
// RUN: %target-swift-frontend -parse-as-library -emit-sil -DNEGATIVES -verify %s -strict-concurrency=complete
4+
// RUN: %target-swift-frontend -parse-as-library -emit-sil -DNEGATIVES -verify %s -strict-concurrency=complete -enable-experimental-feature SendNonSendable
5+
26
// RUN: %target-swift-frontend -parse-as-library -emit-sil -enable-actor-data-race-checks -o - %s | %FileCheck %s
37

48
// REQUIRES: concurrency

test/Concurrency/actor_derived_conformances.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
// RUN: %target-typecheck-verify-swift -disable-availability-checking
1+
// RUN: %target-swift-frontend -disable-availability-checking %s -emit-sil -o /dev/null -verify
2+
// RUN: %target-swift-frontend -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=targeted
3+
// RUN: %target-swift-frontend -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=complete
4+
// RUN: %target-swift-frontend -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=complete -enable-experimental-feature SendNonSendable
5+
26
// REQUIRES: concurrency
37

48
actor A1: Comparable {}

test/Concurrency/actor_existentials.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
// RUN: %target-typecheck-verify-swift -disable-availability-checking
1+
// RUN: %target-swift-frontend -disable-availability-checking %s -emit-sil -o /dev/null -verify
2+
// RUN: %target-swift-frontend -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=targeted
3+
// RUN: %target-swift-frontend -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=complete
4+
// RUN: %target-swift-frontend -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=complete -enable-experimental-feature SendNonSendable
5+
26
// REQUIRES: concurrency
37

48
protocol P: Actor {

0 commit comments

Comments
 (0)