From ba217815cb9da9372d15333a634952597e0994a7 Mon Sep 17 00:00:00 2001 From: Georgy Komarov Date: Fri, 8 Nov 2019 10:06:10 +0300 Subject: [PATCH] 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 --- addons/misra.py | 14 ++++++++++++ addons/test/misra/misra-test.c | 39 ++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/addons/misra.py b/addons/misra.py index cd3a350aa..8645678e7 100755 --- a/addons/misra.py +++ b/addons/misra.py @@ -1570,13 +1570,27 @@ class MisraChecker: STATE_NONE = 0 # default state, not in switch case/default block 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_SWITCH = 3 # walking through switch statement scope + state = STATE_NONE + end_swtich_token = None # end '}' for the switch scope 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': state = STATE_BREAK elif token.str == ';': if state == STATE_BREAK: state = STATE_OK + elif token.next and token.next == end_swtich_token: + self.reportError(token.next, 16, 3) else: state = STATE_NONE elif token.str.startswith('/*') or token.str.startswith('//'): diff --git a/addons/test/misra/misra-test.c b/addons/test/misra/misra-test.c index c3ca24237..f7fe4277f 100644 --- a/addons/test/misra/misra-test.c +++ b/addons/test/misra/misra-test.c @@ -524,7 +524,46 @@ void misra_16_3() { { 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() {