Skip to content

Commit

Permalink
MISRA rule 15.4 Only one break/goto from iteration statement (danmar#…
Browse files Browse the repository at this point in the history
  • Loading branch information
larseven authored Nov 9, 2020
1 parent 8b52ed5 commit 9d70926
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
30 changes: 30 additions & 0 deletions addons/misra.py
Original file line number Diff line number Diff line change
Expand Up @@ -2019,6 +2019,35 @@ def misra_15_3(self, data):
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:
Expand Down Expand Up @@ -3108,6 +3137,7 @@ def parseDump(self, dumpfile):
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)
Expand Down
84 changes: 84 additions & 0 deletions addons/test/misra/misra-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 9d70926

Please sign in to comment.