MISRA rule 15.4 Only one break/goto from iteration statement (#2892)

This commit is contained in:
Lars Even Almaas 2020-11-09 15:11:08 +01:00 committed by GitHub
parent 8b52ed590e
commit 9d70926fcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 114 additions and 0 deletions

View File

@ -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)

View File

@ -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