misra.py: Fix false negatives in string concatenation for rule 20.7

This will fix Trac#9633
This commit is contained in:
Georgy Komarov 2020-07-24 07:15:40 +03:00
parent a11a0e79e4
commit dc1faa71ed
No known key found for this signature in database
GPG Key ID: 195B8622FE88ED46
2 changed files with 44 additions and 0 deletions

View File

@ -2302,10 +2302,50 @@ class MisraChecker:
self.reportError(directive, 20, 5)
def misra_20_7(self, data):
def find_string_concat(exp, arg, directive_args):
# Handle concatenation of string literals, e.g.:
# #define MACRO(A, B) (A " " B)
# Addon should not report errors for both macro arguments.
arg_pos = exp.find(arg, 0)
need_check = False
skip_next = False
state_in_string = False
pos_search = arg_pos + 1
directive_args = [a.strip() for a in directive_args if a != arg]
arg = arg.strip()
while pos_search < len(exp):
if exp[pos_search] == '"':
if state_in_string:
state_in_string = False
else:
state_in_string = True
pos_search += 1
elif exp[pos_search] in directive_args:
skip_next = True # Skip check for the next argument
break
elif exp[pos_search] == arg:
pos_search += 1
elif exp[pos_search] == ' ':
pos_search += 1
elif state_in_string:
pos_search += 1
else:
need_check = True
break
return need_check, skip_next
for directive in data.directives:
d = Define(directive)
exp = '(' + d.expansionList + ')'
skip_next = False
for arg in d.args:
if skip_next:
_, skip_next = find_string_concat(exp, arg, d.args)
continue
need_check, skip_next = find_string_concat(exp, arg, d.args)
if not need_check:
continue
pos = 0
while pos < len(exp):
pos = exp.find(arg, pos)

View File

@ -1031,6 +1031,10 @@ union misra_19_2 { }; // 19.2
#define M_20_7_7(x) a = # x // 20.10
#define M_20_7_8(x, fn) a = fn ( # x ) // 20.7 20.10
#define M_20_7_9(x, fn) a = (fn) ( # x ) // 20.10
#define M_20_7_10(A, B) (A " " B)
#define M_20_7_11(A, B, C) (A " " B " " C)
#define M_20_7_12(A, B, C) (A " " B + C) // 20.7
#define M_20_7_13(A, B, C) (A + B " " C) // 20.7
// Compliant: M is a structure member name, not an expression
struct { int a; } struct_20_7_s;