Skip to content

Commit a595615

Browse files
authored
Merge pull request #5275 from milseman/escaping
[Version] Don't allow effective sub-versions, only major versions
2 parents 2e8e980 + 0cb2188 commit a595615

File tree

10 files changed

+62
-27
lines changed

10 files changed

+62
-27
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ ERROR(error_no_source_location_scope_map,none,
9797
"-dump-scope-maps argument must be 'expanded' or a list of source locations",
9898
())
9999

100+
NOTE(note_swift_version_major, none,
101+
"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))
104+
100105
ERROR(error_mode_cannot_emit_dependencies,none,
101106
"this mode does not support emitting dependency files", ())
102107
ERROR(error_mode_cannot_emit_header,none,

include/swift/Basic/Version.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ class Version {
103103
/// Whether this version is in the Swift 3 family
104104
bool isVersion3() const { return !empty() && Components[0] == 3; }
105105

106+
/// Return this Version struct with minor and sub-minor components stripped
107+
Version asMajorVersion() const;
108+
106109
/// Parse a version in the form used by the _compiler_version \#if condition.
107110
static Version parseCompilerVersionString(StringRef VersionString,
108111
SourceLoc Loc,
@@ -124,6 +127,12 @@ class Version {
124127
/// Returns a version from the currently defined SWIFT_VERSION_MAJOR and
125128
/// SWIFT_VERSION_MINOR.
126129
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+
};
127136
};
128137

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

lib/Basic/Version.cpp

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -310,29 +310,24 @@ 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-
// Swift 3 family
320-
"3",
321-
"3.0",
322-
323-
// Swift 4 family
324-
"4",
325-
"4.0",
326-
};
327-
for (auto const i : whitelist) {
328-
auto v = parseVersionString(i, SourceLoc(), nullptr);
313+
bool Version::isValidEffectiveLanguageVersion() const {
314+
for (auto verStr : getValidEffectiveVersions()) {
315+
auto v = parseVersionString(verStr, SourceLoc(), nullptr);
329316
assert(v.hasValue());
330317
if (v == *this)
331318
return true;
332319
}
333320
return false;
334321
}
335322

323+
Version Version::asMajorVersion() const {
324+
if (empty())
325+
return {};
326+
Version res;
327+
res.Components.push_back(Components[0]);
328+
return res;
329+
}
330+
336331
bool operator>=(const class Version &lhs,
337332
const class Version &rhs) {
338333

lib/Frontend/CompilerInvocation.cpp

Lines changed: 21 additions & 2 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,8 +793,7 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
773793
vers.getValue().isValidEffectiveLanguageVersion()) {
774794
Opts.EffectiveLanguageVersion = vers.getValue();
775795
} else {
776-
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
777-
A->getAsString(Args), A->getValue());
796+
diagnoseSwiftVersion(vers, A, Args, Diags);
778797
}
779798
}
780799

test/APINotes/versioned.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// RUN: rm -rf %t && mkdir -p %t
22

3-
// RUN: %target-swift-ide-test -F %S/Inputs/custom-frameworks -print-module -source-filename %s -module-to-print=APINotesFrameworkTest -function-definitions=false -print-regular-comments -swift-version 4.0 | %FileCheck -check-prefix=CHECK-SWIFT-4 %s
3+
// RUN: %target-swift-ide-test -F %S/Inputs/custom-frameworks -print-module -source-filename %s -module-to-print=APINotesFrameworkTest -function-definitions=false -print-regular-comments -swift-version 4 | %FileCheck -check-prefix=CHECK-SWIFT-4 %s
44

5-
// RUN: %target-swift-ide-test -F %S/Inputs/custom-frameworks -print-module -source-filename %s -module-to-print=APINotesFrameworkTest -function-definitions=false -print-regular-comments -swift-version 3.0 | %FileCheck -check-prefix=CHECK-SWIFT-3 %s
5+
// RUN: %target-swift-ide-test -F %S/Inputs/custom-frameworks -print-module -source-filename %s -module-to-print=APINotesFrameworkTest -function-definitions=false -print-regular-comments -swift-version 3 | %FileCheck -check-prefix=CHECK-SWIFT-3 %s
66

77
// CHECK-SWIFT-4: func jumpTo(x: Double, y: Double, z: Double)
88
// CHECK-SWIFT-3: func jumpTo(x: Double, y: Double, z: Double)

test/Driver/swift-version.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
// RUN: %target-swiftc_driver -swift-version 3 %s
2-
// RUN: %target-swiftc_driver -swift-version 3.0 %s
2+
// RUN: not %target-swiftc_driver -swift-version foo %s 2>&1 | %FileCheck --check-prefix BAD %s
33
// RUN: not %target-swiftc_driver -swift-version 1 %s 2>&1 | %FileCheck --check-prefix BAD %s
44
// RUN: not %target-swiftc_driver -swift-version 2 %s 2>&1 | %FileCheck --check-prefix BAD %s
55
// RUN: not %target-swiftc_driver -swift-version 2.3 %s 2>&1 | %FileCheck --check-prefix BAD %s
66
// RUN: not %target-swiftc_driver -swift-version 7 %s 2>&1 | %FileCheck --check-prefix BAD %s
77
// RUN: not %target-swiftc_driver -swift-version 7.2 %s 2>&1 | %FileCheck --check-prefix BAD %s
8+
// RUN: not %target-swiftc_driver -swift-version 3.0 %s 2>&1 | %FileCheck --check-prefix FIXIT_3 %s
9+
// RUN: not %target-swiftc_driver -swift-version 3.3 %s 2>&1 | %FileCheck --check-prefix FIXIT_3 %s
10+
// RUN: not %target-swiftc_driver -swift-version 4.3 %s 2>&1 | %FileCheck --check-prefix FIXIT_4 %s
811

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

1118
let x = 1

test/api-digester/compare-dump.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// RUN: rm -rf %t.module-cache && mkdir -p %t.module-cache
44
// RUN: %swift -emit-module -o %t.mod/cake1.swiftmodule %S/Inputs/cake1.swift -parse-as-library
55
// RUN: %swift -emit-module -o %t.mod/cake2.swiftmodule %S/Inputs/cake2.swift -parse-as-library
6-
// RUN: %api-digester -dump-sdk -module cake1 -o %t.dump1.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3.0 -I %t.mod
7-
// RUN: %api-digester -dump-sdk -module cake2 -o %t.dump2.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3.0 -I %t.mod
6+
// RUN: %api-digester -dump-sdk -module cake1 -o %t.dump1.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %t.mod
7+
// RUN: %api-digester -dump-sdk -module cake2 -o %t.dump2.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %t.mod
88
// RUN: %api-digester -diagnose-sdk --input-paths %t.dump1.json -input-paths %t.dump2.json > %t.result
99
// RUN: diff -u %S/Outputs/Cake.txt %t.result

test/api-digester/dump-module.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
// RUN: rm -rf %t.sdk && mkdir -p %t.sdk
33
// RUN: rm -rf %t.module-cache && mkdir -p %t.module-cache
44
// RUN: %swift -emit-module -o %t.mod/cake.swiftmodule %S/Inputs/cake.swift -parse-as-library
5-
// RUN: %api-digester -dump-sdk -module cake -o %t.dump.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3.0 -I %t.mod
5+
// RUN: %api-digester -dump-sdk -module cake -o %t.dump.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %t.mod
66
// RUN: diff -u %t.dump.json %S/Outputs/cake.json
77
// RUN: %api-digester -diagnose-sdk --input-paths %t.dump.json -input-paths %S/Outputs/cake.json

test/api-digester/source-stability.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// REQUIRES: OS=macosx
22
// RUN: rm -rf %S/tmp && mkdir %S/tmp && mkdir %S/tmp/module-cache && mkdir %S/tmp/dummy.sdk
3-
// RUN: %api-digester -dump-sdk -module Swift -o %S/tmp/current-stdlib.json -module-cache-path %S/tmp/module-cache -sdk %S/tmp/dummy.sdk -swift-version 3.0
3+
// RUN: %api-digester -dump-sdk -module Swift -o %S/tmp/current-stdlib.json -module-cache-path %S/tmp/module-cache -sdk %S/tmp/dummy.sdk -swift-version 3
44
// RUN: %api-digester -diagnose-sdk -input-paths %S/stdlib-stable.json -input-paths %S/tmp/current-stdlib.json >> %S/tmp/changes.txt
55
// RUN: %clang -E -P -x c %S/source-stability.swift.expected -o - | sed '/^\s*$/d' > %S/tmp/source-stability.swift.expected
66
// RUN: %clang -E -P -x c %S/tmp/changes.txt -o - | sed '/^\s*$/d' > %S/tmp/changes.txt.tmp

test/attr/attr_availability_swift_deserialize.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: rm -rf %t && mkdir -p %t
22
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/OldAndNew.swiftmodule -module-name OldAndNew %S/Inputs/OldAndNew.swift
3-
// RUN: not %target-swift-frontend -parse -I %t -swift-version 3.0 %s 2>&1 | %FileCheck -check-prefix THREE %s
4-
// RUN: not %target-swift-frontend -parse -I %t -swift-version 4.0 %s 2>&1 | %FileCheck -check-prefix FOUR %s
3+
// RUN: not %target-swift-frontend -parse -I %t -swift-version 3 %s 2>&1 | %FileCheck -check-prefix THREE %s
4+
// RUN: not %target-swift-frontend -parse -I %t -swift-version 4 %s 2>&1 | %FileCheck -check-prefix FOUR %s
55

66
import OldAndNew
77

0 commit comments

Comments
 (0)