Loop on a constant condition with no way out of the body

ID

objectivec.correctness.infinite_loop

Severity

low

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

medium

Resource

Control Flow

Language

Objective-C

Description

Reports a while (YES), while (1), while (true) or for (;;) whose body, from the header down to the closing brace at the same indentation, contains no break, return, goto, @throw, exit, abort or longjmp, and does not drive a run loop. A loop with an exit anywhere in its body - including inside a nested block - a loop with an empty body, a loop on a real condition, and a copy of the shape inside a comment are not reported. Loops whose condition is a variable are outside the rule: whether the body updates it cannot be decided reliably here, and guessing produces false reports on the ordinary case of a flag set from another method or thread.

Rationale

The header promises the loop runs until something says stop, and nothing in the body ever does. The thread the loop is running on never returns: on the main thread the application stops responding and is terminated by the watchdog, and on a worker thread it holds whatever locks and resources it acquired for the lifetime of the process while consuming a core. Nothing distinguishes this from a deliberate event loop at the call site, so it is usually found only when the application hangs.

The following code illustrates the pattern detected by this rule:

@implementation Worker
- (void)processForever {
    // FLAGGED: Loop on a constant condition with no way out of the body
    while (YES) {
        [self processNextEvent];
    }
}

- (void)processNextEvent { }
- (void)poll { }
- (void)drainOnce { }
- (void)sleepBriefly { }
- (void)cleanup { }
@end

Remediation

Add the exit the loop was meant to have - a break on the condition that ends the work, or a return once the result is available - and make sure the exit is reachable on every path through the body, not only inside a branch that may never be taken. Where the loop really is meant to run for the lifetime of the process, drive a run loop or a dispatch queue instead of spinning, so the thread blocks rather than burning a core.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved