Skip to content

Commit a29accc

Browse files
committed
[sil-opt] Add the ability to specify a swift-version.
I implemented this by adding a new option called swift-version. If not set, we just leave LangOpts.EffectiveLanguageVersion alone and get whatever that default behavior is. If it is set, we use the same version parsing infrastructure used by the normal frontend. If the parse fails, we exit -1. To write the test that I wanted to write to show this behavior, I also needed to add support to sil-opt for verify-additional-prefixes which is just useful goodness.
1 parent 7efc73e commit a29accc

File tree

2 files changed

+69
-7
lines changed

2 files changed

+69
-7
lines changed

lib/DriverTool/sil_opt_main.cpp

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,27 @@
1515
//
1616
//===----------------------------------------------------------------------===//
1717

18-
#include "swift/Subsystems.h"
1918
#include "swift/AST/DiagnosticsFrontend.h"
2019
#include "swift/AST/SILOptions.h"
2120
#include "swift/Basic/FileTypes.h"
22-
#include "swift/Basic/LLVMInitialize.h"
2321
#include "swift/Basic/InitializeSwiftModules.h"
22+
#include "swift/Basic/LLVMInitialize.h"
2423
#include "swift/Basic/QuotedString.h"
2524
#include "swift/Frontend/DiagnosticVerifier.h"
2625
#include "swift/Frontend/Frontend.h"
2726
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
27+
#include "swift/IRGen/IRGenPublic.h"
28+
#include "swift/IRGen/IRGenSILPasses.h"
29+
#include "swift/Parse/ParseVersion.h"
2830
#include "swift/SIL/SILRemarkStreamer.h"
2931
#include "swift/SILOptimizer/Analysis/Analysis.h"
30-
#include "swift/SILOptimizer/PassManager/Passes.h"
3132
#include "swift/SILOptimizer/PassManager/PassManager.h"
33+
#include "swift/SILOptimizer/PassManager/Passes.h"
34+
#include "swift/Serialization/SerializationOptions.h"
3235
#include "swift/Serialization/SerializedModuleLoader.h"
3336
#include "swift/Serialization/SerializedSILLoader.h"
34-
#include "swift/Serialization/SerializationOptions.h"
37+
#include "swift/Subsystems.h"
3538
#include "swift/SymbolGraphGen/SymbolGraphOptions.h"
36-
#include "swift/IRGen/IRGenPublic.h"
37-
#include "swift/IRGen/IRGenSILPasses.h"
3839
#include "llvm/ADT/Statistic.h"
3940
#include "llvm/Support/CommandLine.h"
4041
#include "llvm/Support/FileSystem.h"
@@ -363,6 +364,12 @@ struct SILOptOptions {
363364
llvm::cl::desc("verify diagnostics against expected-"
364365
"{error|warning|note} annotations"));
365366

367+
llvm::cl::list<std::string> VerifyAdditionalPrefixes =
368+
llvm::cl::list<std::string>(
369+
"verify-additional-prefix",
370+
llvm::cl::desc("Check for diagnostics with the prefix "
371+
"expected-<PREFIX> as well as expected-"));
372+
366373
llvm::cl::opt<unsigned>
367374
AssertConfId = llvm::cl::opt<unsigned>("assert-conf-id", llvm::cl::Hidden,
368375
llvm::cl::init(0));
@@ -542,6 +549,11 @@ struct SILOptOptions {
542549
llvm::cl::opt<bool>(
543550
"disable-region-based-isolation-with-strict-concurrency",
544551
llvm::cl::init(false));
552+
553+
llvm::cl::opt<std::string> SwiftVersionString = llvm::cl::opt<std::string>(
554+
"swift-version",
555+
llvm::cl::desc(
556+
"The swift version to assume AST declarations correspond to"));
545557
};
546558

547559
/// Regular expression corresponding to the value given in one of the
@@ -641,6 +653,23 @@ int sil_opt_main(ArrayRef<const char *> argv, void *MainAddr) {
641653
// cache.
642654
Invocation.getClangImporterOptions().ModuleCachePath = options.ModuleCachePath;
643655
Invocation.setParseStdlib();
656+
if (options.SwiftVersionString.size()) {
657+
auto vers = VersionParser::parseVersionString(options.SwiftVersionString,
658+
SourceLoc(), nullptr);
659+
bool isValid = false;
660+
if (vers.has_value()) {
661+
if (auto effectiveVers = vers.value().getEffectiveLanguageVersion()) {
662+
Invocation.getLangOptions().EffectiveLanguageVersion =
663+
effectiveVers.value();
664+
isValid = true;
665+
}
666+
}
667+
if (!isValid) {
668+
llvm::errs() << "error: invalid swift version "
669+
<< options.SwiftVersionString << '\n';
670+
exit(-1);
671+
}
672+
}
644673
Invocation.getLangOptions().DisableAvailabilityChecking = true;
645674
Invocation.getLangOptions().EnableAccessControl = false;
646675
Invocation.getLangOptions().EnableObjCAttrRequiresFoundation = false;
@@ -716,7 +745,12 @@ int sil_opt_main(ArrayRef<const char *> argv, void *MainAddr) {
716745
}
717746

718747
Invocation.getDiagnosticOptions().VerifyMode =
719-
options.VerifyMode ? DiagnosticOptions::Verify : DiagnosticOptions::NoVerify;
748+
options.VerifyMode ? DiagnosticOptions::Verify
749+
: DiagnosticOptions::NoVerify;
750+
for (auto &additionalPrefixes : options.VerifyAdditionalPrefixes) {
751+
Invocation.getDiagnosticOptions()
752+
.AdditionalDiagnosticVerifierPrefixes.push_back(additionalPrefixes);
753+
}
720754

721755
ClangImporterOptions &clangImporterOptions =
722756
Invocation.getClangImporterOptions();

test/sil-opt/swift-version.sil

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %target-sil-opt -transfer-non-sendable -strict-concurrency=complete -swift-version 5 %s -verify -verify-additional-prefix complete-
2+
// RUN: %target-sil-opt -transfer-non-sendable -strict-concurrency=complete -swift-version 6 %s -verify -verify-additional-prefix tns-
3+
4+
// READ THIS: This test takes advantage of the semantics of concurrency to
5+
// validate that sil-opt can properly set the swift-version flag in a way that
6+
// the rest of the compiler can understand. Please do not add actual concurrency
7+
// code to this test and always keep it simple if additional code needs to be
8+
// added since we aren't actually trying to test concurrency here!
9+
10+
// REQUIRES: asserts
11+
// REQUIRES: concurrency
12+
13+
import Swift
14+
import _Concurrency
15+
16+
class NonSendableKlass {}
17+
18+
sil @transfer_to_main : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
19+
20+
sil [ossa] @test : $@convention(thin) @async (@guaranteed NonSendableKlass) -> () {
21+
bb0(%0 : @guaranteed $NonSendableKlass):
22+
%1 = function_ref @transfer_to_main : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
23+
apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %1(%0) : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
24+
// expected-complete-warning @-1 {{task-isolated value of type 'NonSendableKlass' transferred to global actor '<null>'-isolated context; later accesses to value could race; this is an error in the Swift 6 language mode}}
25+
// expected-tns-error @-2 {{task-isolated value of type 'NonSendableKlass' transferred to global actor '<null>'-isolated context; later accesses to value could race}}
26+
%9999 = tuple ()
27+
return %9999 : $()
28+
}

0 commit comments

Comments
 (0)