MISRA rule 15.4 Only one break/goto from iteration statement (#2892)
This commit is contained in:
parent
8b52ed590e
commit
9d70926fcd
|
@ -2019,6 +2019,35 @@ class MisraChecker:
|
|||
self.reportError(token, 15, 3)
|
||||
break
|
||||
t = t.next
|
||||
|
||||
def misra_15_4(self, data):
|
||||
# Return a list of scopes affected by a break or goto
|
||||
def getLoopsAffectedByBreak(knownLoops, scope, isGoto):
|
||||
if scope and scope.type and scope.type not in ['Global', 'Function']:
|
||||
if not isGoto and scope.type == 'Switch':
|
||||
return
|
||||
if scope.type in ['For', 'While', 'Do']:
|
||||
knownLoops.append(scope)
|
||||
if not isGoto:
|
||||
return
|
||||
getLoopsAffectedByBreak(knownLoops, scope.nestedIn, isGoto)
|
||||
|
||||
loopWithBreaks = {}
|
||||
for token in data.tokenlist:
|
||||
if token.str not in ['break', 'goto']:
|
||||
continue
|
||||
|
||||
affectedLoopScopes = []
|
||||
getLoopsAffectedByBreak(affectedLoopScopes, token.scope, token.str == 'goto')
|
||||
for scope in affectedLoopScopes:
|
||||
if scope in loopWithBreaks:
|
||||
loopWithBreaks[scope] += 1
|
||||
else:
|
||||
loopWithBreaks[scope] = 1
|
||||
|
||||
for scope, breakCount in loopWithBreaks.items():
|
||||
if breakCount > 1:
|
||||
self.reportError(scope.bodyStart, 15, 4)
|
||||
|
||||
def misra_15_5(self, data):
|
||||
for token in data.tokenlist:
|
||||
|
@ -3108,6 +3137,7 @@ class MisraChecker:
|
|||
self.executeCheck(1501, self.misra_15_1, cfg)
|
||||
self.executeCheck(1502, self.misra_15_2, cfg)
|
||||
self.executeCheck(1503, self.misra_15_3, cfg)
|
||||
self.executeCheck(1504, self.misra_15_4, cfg)
|
||||
self.executeCheck(1505, self.misra_15_5, cfg)
|
||||
if cfgNumber == 0:
|
||||
self.executeCheck(1506, self.misra_15_6, data.rawTokens)
|
||||
|
|
|
@ -796,6 +796,90 @@ void misra_15_3() {
|
|||
}
|
||||
}
|
||||
|
||||
void misra_15_4() {
|
||||
misra_15_4_label:
|
||||
return;
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int z = 0;
|
||||
|
||||
// Break on different loop scopes
|
||||
for (x = 0; x < 42; ++x) {
|
||||
if (x==1) {
|
||||
break;
|
||||
}
|
||||
for (y = 0; y < 42; ++y) { // 15.4
|
||||
if (y==1) {
|
||||
break;
|
||||
}
|
||||
if (y==2) {
|
||||
break;
|
||||
}
|
||||
for (z = 0; y < 42; ++z) {
|
||||
if (z==1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Break in while loop
|
||||
do { // 15.4
|
||||
if(x == 1) {
|
||||
break;
|
||||
}
|
||||
if(x == 2) {
|
||||
break
|
||||
}
|
||||
x++;
|
||||
} while(x != 42);
|
||||
|
||||
// Break and goto in same loop
|
||||
for (int x = 0; x < 10; ++x) { // 15.4
|
||||
if (x == 1) {
|
||||
break;
|
||||
}
|
||||
if (x == 2) {
|
||||
goto misra_15_4_label; // 15.1 15.2
|
||||
}
|
||||
}
|
||||
|
||||
// Inner loop uses goto
|
||||
for (x = 0; x < 42; ++x) { // 15.4
|
||||
if (x==1) {
|
||||
break;
|
||||
}
|
||||
for (y = 0; y < 42; ++y) {
|
||||
if (y == 1) {
|
||||
goto misra_15_4_label; // 15.1 15.2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow switch with multiple breaks inside loop
|
||||
for (x = 0; x < 42; ++x) {
|
||||
switch (x) {
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Do not allow switch with multiple gotos inside loop
|
||||
for (x = 0; x < 42; ++x) { // 15.4
|
||||
switch (x) {
|
||||
case 1:
|
||||
goto misra_15_4_label; // 15.1 15.2
|
||||
break;
|
||||
default:
|
||||
goto misra_15_4_label; // 15.1 15.2
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int misra_15_5() {
|
||||
if (x!=0) {
|
||||
return 1; // 15.5
|
||||
|
|
Loading…
Reference in New Issue