misra.py: Fix R16.3 FN in last case/default statement (#2325)

Fix R16.3 state machine which doesn't report errors in last case/default
statemenet. See added tests for examples.

Issue on trac: https://trac.cppcheck.net/ticket/8548
This commit is contained in:
Georgy Komarov 2019-11-08 10:06:10 +03:00 committed by Daniel Marjamäki
parent 1fcbd696be
commit ba217815cb
2 changed files with 53 additions and 0 deletions

View File

@ -1570,13 +1570,27 @@ class MisraChecker:
STATE_NONE = 0 # default state, not in switch case/default block STATE_NONE = 0 # default state, not in switch case/default block
STATE_BREAK = 1 # break/comment is seen but not its ';' STATE_BREAK = 1 # break/comment is seen but not its ';'
STATE_OK = 2 # a case/default is allowed (we have seen 'break;'/'comment'/'{'/attribute) STATE_OK = 2 # a case/default is allowed (we have seen 'break;'/'comment'/'{'/attribute)
STATE_SWITCH = 3 # walking through switch statement scope
state = STATE_NONE state = STATE_NONE
end_swtich_token = None # end '}' for the switch scope
for token in rawTokens: for token in rawTokens:
# Find switch scope borders
if token.str == 'switch':
state = STATE_SWITCH
if state == STATE_SWITCH:
if token.str == '{':
end_swtich_token = findRawLink(token)
else:
continue
if token.str == 'break' or token.str == 'return' or token.str == 'throw': if token.str == 'break' or token.str == 'return' or token.str == 'throw':
state = STATE_BREAK state = STATE_BREAK
elif token.str == ';': elif token.str == ';':
if state == STATE_BREAK: if state == STATE_BREAK:
state = STATE_OK state = STATE_OK
elif token.next and token.next == end_swtich_token:
self.reportError(token.next, 16, 3)
else: else:
state = STATE_NONE state = STATE_NONE
elif token.str.startswith('/*') or token.str.startswith('//'): elif token.str.startswith('/*') or token.str.startswith('//'):

View File

@ -525,6 +525,45 @@ void misra_16_3() {
break; break;
} }
} }
switch (x) {
case 1:
break;
default: // 16.5
x++;
case 19: // 16.3
break;
case 20:
x + 2;
x + 3;
break;
}
switch (x) { // 16.6
default:;
} // 16.3
switch (x) { default:; } // 16.3 16.6
switch (x) {
case 20:
x + 2;
x + 3;
break;
case 21:
x + 2;
x + 3;
break;
default:
;
} // 16.3
switch (x) { // 16.4 16.6
case 1:
x++;
break;
case 2:
x++;
} // 16.3
} }
void misra_16_4() { void misra_16_4() {