Skip to content

Commit 816d186

Browse files
author
Josh Learn
committed
Extend compile-time constantness check to support constant Ranges
Currently the function parameter constantness check for functions annotated with @_semantics("oslog.requires_constant_argument") does not support ranges (e.g. 0...5, 0..<5). Ranges like this are considered binary expressions by the compiler. This change adds support for accepting binary expressions as constant arguments as long as both arguments to the expression are constant. rdar://71822563
1 parent a3f4407 commit 816d186

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

lib/Sema/ConstantnessSemaDiagnostics.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static Expr *checkConstantness(Expr *expr) {
105105
expressionsToCheck.push_back(expr);
106106
while (!expressionsToCheck.empty()) {
107107
Expr *expr = expressionsToCheck.pop_back_val();
108-
// Lookthrough identity_expr, tuple and inject_into_optional expressions.
108+
// Lookthrough identity_expr, tuple, binary_expr and inject_into_optional expressions.
109109
if (IdentityExpr *identityExpr = dyn_cast<IdentityExpr>(expr)) {
110110
expressionsToCheck.push_back(identityExpr->getSubExpr());
111111
continue;
@@ -115,6 +115,10 @@ static Expr *checkConstantness(Expr *expr) {
115115
expressionsToCheck.push_back(element);
116116
continue;
117117
}
118+
if (BinaryExpr *binaryExpr = dyn_cast<BinaryExpr>(expr)) {
119+
expressionsToCheck.push_back(binaryExpr->getArg());
120+
continue;
121+
}
118122
if (InjectIntoOptionalExpr *optionalExpr =
119123
dyn_cast<InjectIntoOptionalExpr>(expr)) {
120124
expressionsToCheck.push_back(optionalExpr->getSubExpr());

test/Sema/diag_constantness_check.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,3 +328,19 @@ func testAtomicOrderingConstantness(
328328
_ = atomicInt.load(ordering: myOrder)
329329
// expected-error@-1 {{ordering argument must be a static method or property of 'AtomicLoadOrdering'}}
330330
}
331+
332+
// Test that the check can handle ranges
333+
@_semantics("oslog.requires_constant_arguments")
334+
func constantRange(x: Range<Int>) {}
335+
336+
@_semantics("oslog.requires_constant_arguments")
337+
func constantClosedRange(x: ClosedRange<Int>) {}
338+
339+
func testConstantRange(x: Int) {
340+
constantRange(x: 0..<5)
341+
constantRange(x: 0..<x)
342+
// expected-error@-1 {{argument must be an integer literal}}
343+
constantClosedRange(x: 0...10)
344+
constantClosedRange(x: x...10)
345+
// expected-error@-1 {{argument must be an integer literal}}
346+
}

0 commit comments

Comments
 (0)