Sema: Fix -warn-long-expression-type-checking when expression timer is turned off

My change 983b75e1cf broke
-warn-long-expression-type-checking because now the
ExpressionTimer is not instantiated by default and that
entire code path is skipped.

Change it so that if -warn-long-expression-type-checking
is passed in, we still start the timer, we just don't
ever consider it to have 'expired'.

Fixes rdar://problem/152998878.
This commit is contained in:
Slava Pestov
2025-06-25 18:55:45 -04:00
parent e744e35086
commit 017be57e9b
3 changed files with 19 additions and 6 deletions

View File

@@ -249,6 +249,8 @@ private:
bool PrintWarning;
public:
const static unsigned NoLimit = (unsigned) -1;
ExpressionTimer(AnchorType Anchor, ConstraintSystem &CS,
unsigned thresholdInSecs);
@@ -274,6 +276,9 @@ public:
/// Return the remaining process time in seconds until the
/// threshold specified during construction is reached.
unsigned getRemainingProcessTimeInSeconds() const {
if (ThresholdInSecs == NoLimit)
return NoLimit;
auto elapsed = unsigned(getElapsedProcessTimeInFractionalSeconds());
return elapsed >= ThresholdInSecs ? 0 : ThresholdInSecs - elapsed;
}

View File

@@ -141,9 +141,18 @@ ConstraintSystem::~ConstraintSystem() {
void ConstraintSystem::startExpressionTimer(ExpressionTimer::AnchorType anchor) {
ASSERT(!Timer);
unsigned timeout = getASTContext().TypeCheckerOpts.ExpressionTimeoutThreshold;
if (timeout == 0)
return;
const auto &opts = getASTContext().TypeCheckerOpts;
unsigned timeout = opts.ExpressionTimeoutThreshold;
// If either the timeout is set, or we're asked to emit warnings,
// start the timer. Otherwise, don't start the timer, it's needless
// overhead.
if (timeout == 0) {
if (opts.WarnLongExpressionTypeChecking == 0)
return;
timeout = ExpressionTimer::NoLimit;
}
Timer.emplace(anchor, *this, timeout);
}

View File

@@ -1,5 +1,4 @@
// RUN: %target-typecheck-verify-swift -warn-long-expression-type-checking=1 -warn-long-function-bodies=1
// REQUIRES: rdar44305428
// RUN: %target-typecheck-verify-swift -warn-long-expression-type-checking=1 -solver-disable-shrink -warn-long-function-bodies=1
@_silgen_name("generic_foo")
func foo<T>(_ x: T) -> T
@@ -8,6 +7,6 @@ func foo(_ x: Int) -> Int
func test(m: Double) -> Int {
// expected-warning@-1 {{global function 'test(m:)' took}}
return Int(foo(Float(m) / 20) * 20 - 2) + 10
return ~(~(~(~(~(~(~(~(~(~(~(~(0))))))))))))
// expected-warning@-1 {{expression took}}
}