Skip to content

Commit 5d540ab

Browse files
committed
[Swift version] Note all supported versions when -swift-version is misused.
1 parent 12efcc9 commit 5d540ab

File tree

5 files changed

+36
-22
lines changed

5 files changed

+36
-22
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ ERROR(error_no_source_location_scope_map,none,
9999

100100
NOTE(note_swift_version_major, none,
101101
"use major version, as in '-swift-version %0'", (unsigned))
102+
NOTE(note_valid_swift_versions, none,
103+
"valid arguments to '-swift-version' are %0", (StringRef))
102104

103105
ERROR(error_mode_cannot_emit_dependencies,none,
104106
"this mode does not support emitting dependency files", ())

include/swift/Basic/Version.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ class Version {
127127
/// Returns a version from the currently defined SWIFT_VERSION_MAJOR and
128128
/// SWIFT_VERSION_MINOR.
129129
static Version getCurrentLanguageVersion();
130+
131+
// Whitelist of backward-compatibility versions that we permit passing as
132+
// -swift-version <vers>
133+
static std::array<StringRef, 2> getValidEffectiveVersions() {
134+
return {{"3", "4"}};
135+
};
130136
};
131137

132138
bool operator>=(const Version &lhs, const Version &rhs);

lib/Basic/Version.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -310,17 +310,9 @@ Version::operator clang::VersionTuple() const
310310
}
311311
}
312312

313-
bool
314-
Version::isValidEffectiveLanguageVersion() const
315-
{
316-
// Whitelist of backward-compatibility versions that we permit passing as
317-
// -swift-version <vers>
318-
char const *whitelist[] = {
319-
"3",
320-
"4",
321-
};
322-
for (auto const i : whitelist) {
323-
auto v = parseVersionString(i, SourceLoc(), nullptr);
313+
bool Version::isValidEffectiveLanguageVersion() const {
314+
for (auto verStr : getValidEffectiveVersions()) {
315+
auto v = parseVersionString(verStr, SourceLoc(), nullptr);
324316
assert(v.hasValue());
325317
if (v == *this)
326318
return true;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,26 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
761761
return false;
762762
}
763763

764+
static void diagnoseSwiftVersion(Optional<version::Version> &vers, Arg *verArg,
765+
ArgList &Args, DiagnosticEngine &diags) {
766+
// General invalid version error
767+
diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
768+
verArg->getAsString(Args), verArg->getValue());
769+
770+
// Check for an unneeded minor version, otherwise just list valid verions
771+
if (vers.hasValue() && !vers.getValue().empty() &&
772+
vers.getValue().asMajorVersion().isValidEffectiveLanguageVersion()) {
773+
diags.diagnose(SourceLoc(), diag::note_swift_version_major,
774+
vers.getValue()[0]);
775+
} else {
776+
// Note valid versions instead
777+
auto validVers = version::Version::getValidEffectiveVersions();
778+
auto versStr =
779+
"'" + llvm::join(validVers.begin(), validVers.end(), "', '") + "'";
780+
diags.diagnose(SourceLoc(), diag::note_valid_swift_versions, versStr);
781+
}
782+
}
783+
764784
static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
765785
DiagnosticEngine &Diags,
766786
const FrontendOptions &FrontendOpts) {
@@ -773,16 +793,7 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
773793
vers.getValue().isValidEffectiveLanguageVersion()) {
774794
Opts.EffectiveLanguageVersion = vers.getValue();
775795
} else {
776-
// General invalid version error
777-
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
778-
A->getAsString(Args), A->getValue());
779-
780-
// Check for an unneeded minor version
781-
if (vers.hasValue() && !vers.getValue().empty() &&
782-
vers.getValue().asMajorVersion().isValidEffectiveLanguageVersion()) {
783-
Diags.diagnose(SourceLoc(), diag::note_swift_version_major,
784-
vers.getValue()[0]);
785-
}
796+
diagnoseSwiftVersion(vers, A, Args, Diags);
786797
}
787798
}
788799

test/Driver/swift-version.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-swiftc_driver -swift-version 3 %s
2+
// RUN: not %target-swiftc_driver -swift-version foo %s 2>&1 | %FileCheck --check-prefix BAD %s
23
// RUN: not %target-swiftc_driver -swift-version 1 %s 2>&1 | %FileCheck --check-prefix BAD %s
34
// RUN: not %target-swiftc_driver -swift-version 2 %s 2>&1 | %FileCheck --check-prefix BAD %s
45
// RUN: not %target-swiftc_driver -swift-version 2.3 %s 2>&1 | %FileCheck --check-prefix BAD %s
@@ -9,7 +10,9 @@
910
// RUN: not %target-swiftc_driver -swift-version 4.3 %s 2>&1 | %FileCheck --check-prefix FIXIT_4 %s
1011

1112
// BAD: invalid value
13+
// BAD: note: valid arguments to '-swift-version' are '3', '4'
14+
1215
// FIXIT_3: use major version, as in '-swift-version 3'
13-
// FIXIT_4: use major version, as in '-swift-version 4
16+
// FIXIT_4: use major version, as in '-swift-version 4'
1417

1518
let x = 1

0 commit comments

Comments
 (0)