goto label declared inside a switch body
ID |
objectivec.correctness.label_inside_switch |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Control Flow |
Language |
Objective-C |
Description
Reports a bare goto label written between two case/default labels of the same switch. A label placed after the switch closes, and the case/default labels themselves, are not reported.
Rationale
Two independent jump mechanisms now share one block: the case dispatch that the reader expects, and a label that can be entered from anywhere in the method. Which arm runs no longer follows from the controlling expression alone, and because the label sits at the same indentation as the case labels it reads like one, so a goto into the middle of an arm is easy to miss. Adding or reordering an arm silently changes where the jump lands.
The following code illustrates the pattern detected by this rule:
@implementation Machine
- (void)retryInsideSwitch:(XYState)state {
switch (state) {
case XYStateIdle:
goto retry;
// FLAGGED: goto label declared inside a switch body
retry:
[self start];
break;
default:
break;
}
}
- (BOOL)busy { return NO; }
- (void)start { }
- (void)stop { }
@end
Remediation
Move the label and its statements out of the switch — usually into a helper method the arm calls, or below the switch where the shared tail belongs. If the arms genuinely share code, call one method from both rather than jumping between them.