Statement directly after an unconditional jump
ID |
objectivec.correctness.unreachable_code |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Dead Code |
Language |
Objective-C |
Description
Reports a statement written immediately below a return, break, continue, goto or @throw that occupies a whole line at the same indentation, so the two are siblings in the same block and the jump is not guarded by anything. A jump that ends its block, a jump followed by a case label or by the label a goto targets, and a copy of the shape inside a comment are not reported.
Rationale
The statement below the jump can never run. What matters is not the wasted line but what it implies: either the jump was placed too early and the work below it was silently dropped - a cleanup call, a counter update, an unlock - or the statement was appended by someone who did not notice the jump above it and believes it takes effect. Both readings describe a bug, and neither is visible at the call site, since the method still returns the value it always did. Compilers accept the code, so nothing else reports it.
The following code illustrates the pattern detected by this rule:
@implementation Dispatcher
- (NSInteger)countForKey:(NSString *)key {
// FLAGGED: Statement directly after an unconditional jump
return [self.counts[key] integerValue];
[self.counts removeObjectForKey:key];
}
- (BOOL)shouldSkip:(id)item { return NO; }
- (void)send:(id)item { }
- (void)flush { }
- (void)logHandled { }
- (void)logUnexpected:(NSInteger)code { }
@end
Remediation
Decide which of the two statements was meant to run. If the work below the jump is needed, move it above the jump, or move the jump into the branch that was supposed to guard it. If it is genuinely obsolete, delete it rather than leaving it in place, so the next reader is not misled into maintaining code that never executes.