Skip to content

Commit 03029b6

Browse files
authored
Merge pull request #5440 from graydon/rdar-28786959-if-swift-3-digit-version
2 parents 55f303a + 5cf343f commit 03029b6

File tree

6 files changed

+44
-14
lines changed

6 files changed

+44
-14
lines changed

include/swift/Parse/Parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ class Parser {
122122
} InVarOrLetPattern = IVOLP_NotInVarOrLet;
123123

124124
bool InPoundLineEnvironment = false;
125+
bool InPoundIfEnvironment = false;
125126

126127
LocalContext *CurLocalContext = nullptr;
127128

lib/Basic/Version.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,11 @@ bool Version::isValidEffectiveLanguageVersion() const {
314314
for (auto verStr : getValidEffectiveVersions()) {
315315
auto v = parseVersionString(verStr, SourceLoc(), nullptr);
316316
assert(v.hasValue());
317-
if (v == *this)
317+
// In this case, use logical-equality _and_ precision-equality. We do not
318+
// want to permit users requesting effective language versions more precise
319+
// than our whitelist (eg. we permit 3 but not 3.0 or 3.0.0), since
320+
// accepting such an argument promises more than we're able to deliver.
321+
if (v == *this && v.getValue().size() == size())
318322
return true;
319323
}
320324
return false;
@@ -336,23 +340,27 @@ bool operator>=(const class Version &lhs,
336340
if (lhs.empty())
337341
return true;
338342

339-
auto n = std::min(lhs.size(), rhs.size());
343+
auto n = std::max(lhs.size(), rhs.size());
340344

341345
for (size_t i = 0; i < n; ++i) {
342-
if (lhs[i] < rhs[i])
346+
auto lv = i < lhs.size() ? lhs[i] : 0;
347+
auto rv = i < rhs.size() ? rhs[i] : 0;
348+
if (lv < rv)
343349
return false;
344-
else if (lhs[i] > rhs[i])
350+
else if (lv > rv)
345351
return true;
346352
}
347-
return lhs.size() >= rhs.size();
353+
// Equality
354+
return true;
348355
}
349356

350357
bool operator==(const class Version &lhs,
351358
const class Version &rhs) {
352-
if (lhs.size() != rhs.size())
353-
return false;
354-
for (size_t i = 0; i < lhs.size(); ++i) {
355-
if (lhs[i] != rhs[i])
359+
auto n = std::max(lhs.size(), rhs.size());
360+
for (size_t i = 0; i < n; ++i) {
361+
auto lv = i < lhs.size() ? lhs[i] : 0;
362+
auto rv = i < rhs.size() ? rhs[i] : 0;
363+
if (lv != rv)
356364
return false;
357365
}
358366
return true;

lib/Parse/ParseExpr.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,8 +1429,9 @@ ParserResult<Expr> Parser::parseExprPostfix(Diag<> ID, bool isExprBasic) {
14291429
SourceLoc nameLoc = consumeToken(tok::integer_literal);
14301430

14311431
// Don't allow '.<integer literal>' following a numeric literal
1432-
// expression.
1433-
if (Result.isNonNull() && isa<NumberLiteralExpr>(Result.get())) {
1432+
// expression (unless in #if env, for 1.2.3.4 version numbers)
1433+
if (!InPoundIfEnvironment &&
1434+
Result.isNonNull() && isa<NumberLiteralExpr>(Result.get())) {
14341435
diagnose(nameLoc, diag::numeric_literal_numeric_member)
14351436
.highlight(Result.get()->getSourceRange());
14361437
continue;

lib/Parse/ParseStmt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1759,7 +1759,7 @@ Parser::evaluateConditionalCompilationExpr(Expr *condition) {
17591759
ParserResult<Stmt> Parser::parseStmtIfConfig(BraceItemListKind Kind) {
17601760
StructureMarkerRAII ParsingDecl(*this, Tok.getLoc(),
17611761
StructureMarkerKind::IfConfig);
1762-
1762+
llvm::SaveAndRestore<bool> S(InPoundIfEnvironment, true);
17631763
ConditionalCompilationExprState ConfigState;
17641764
bool foundActive = false;
17651765
SmallVector<IfConfigStmtClause, 4> Clauses;

test/Parse/ConditionalCompilation/language_version.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@
4343
#if swift("") // expected-error {{unexpected platform condition argument: expected a unary comparison, such as '>=2.2'}}
4444
#endif
4545

46-
// We won't expect three version components to work for now.
47-
#if swift(>=2.2.1) // expected-error {{expected named member of numeric literal}}
46+
#if swift(>=2.2.1)
4847
#endif
4948

5049
#if swift(>=2.0, *) // expected-error {{expected only one argument to platform condition}}

test/Parse/ConditionalCompilation/language_version_explicit.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,24 @@
77
asdf asdf asdf asdf
88
#endif
99

10+
#if swift(>=4.0)
11+
let x = 1
12+
#else
13+
// This shouldn't emit any diagnostics.
14+
asdf asdf asdf asdf
15+
#endif
16+
17+
#if swift(>=4.0.0)
18+
let y = 1
19+
#else
20+
// This shouldn't emit any diagnostics.
21+
asdf asdf asdf asdf
22+
#endif
23+
24+
#if swift(>=4.0.1)
25+
// This shouldn't emit any diagnostics.
26+
asdf asdf asdf asdf
27+
#else
28+
let z = 1
29+
#endif
30+

0 commit comments

Comments
 (0)