From e4ae4471e8c867fcb2c63975f08c9ed7fcc3f7b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 11 Jul 2021 20:55:54 +0200 Subject: [PATCH] misra; implement rule 11.2 --- addons/misra.py | 87 ++++++++++++++++++++++++++-------- addons/test/misra/misra-test.c | 6 +++ 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/addons/misra.py b/addons/misra.py index 18e557e32..b2fd5b660 100755 --- a/addons/misra.py +++ b/addons/misra.py @@ -375,6 +375,35 @@ def is_header(file): return file.endswith('.h') +def get_type_conversion_to_from(token): + def get_vartok(expr): + while expr: + if isCast(expr): + if expr.astOperand2 is None: + expr = expr.astOperand1 + else: + expr = expr.astOperand2 + elif expr.str in ('.', '::'): + expr = expr.astOperand2 + elif expr.str == '[': + expr = expr.astOperand1 + else: + break + return expr if (expr and expr.variable) else None + + if isCast(token): + vartok = get_vartok(token) + if vartok: + return (token.next, vartok.variable.typeStartToken) + + elif token.str == '=': + lhs = get_vartok(token.astOperand1) + rhs = get_vartok(token.astOperand2) + if lhs and rhs: + return (lhs.variable.typeStartToken, rhs.variable.typeStartToken) + + return None + def getEssentialTypeCategory(expr): if not expr: return None @@ -1971,30 +2000,47 @@ class MisraChecker: def misra_11_1(self, data): for token in data.tokenlist: - if not isCast(token): + to_from = get_type_conversion_to_from(token) + if to_from is None: continue - vartok = token - while vartok: - if isCast(vartok): - if vartok.astOperand2 is None: - vartok = vartok.astOperand1 - else: - vartok = vartok.astOperand2 - elif vartok.str in ('.', '::'): - vartok = vartok.astOperand2 - elif vartok.str == '[': - vartok = vartok.astOperand1 - else: - break - if (vartok is None) or (not vartok.variable): + from_type = get_function_pointer_type(to_from[1]) + if from_type is None: continue - var_type = get_function_pointer_type(vartok.variable.typeStartToken) - if var_type is None: - continue - cast_type = get_function_pointer_type(token.next) - if cast_type is None or cast_type != var_type: + to_type = get_function_pointer_type(to_from[0]) + if to_type is None or to_type != from_type: self.reportError(token, 11, 1) + def misra_11_2(self, data): + def get_pointer_type(type_token): + while type_token and (type_token.str in ('const', 'struct')): + type_token = type_token.next + if type_token is None: + return None + if not type_token.isName: + return None + return type_token if (type_token.next and type_token.next.str == '*') else None + + incomplete_types = [] + + for token in data.tokenlist: + if token.str == 'struct' and token.next and token.next.next and token.next.isName and token.next.next.str == ';': + incomplete_types.append(token.next.str) + to_from = get_type_conversion_to_from(token) + if to_from is None: + continue + to_pointer_type_token = get_pointer_type(to_from[0]) + if to_pointer_type_token is None: + continue + from_pointer_type_token = get_pointer_type(to_from[1]) + if from_pointer_type_token is None: + continue + if to_pointer_type_token.str == from_pointer_type_token.str: + continue + if from_pointer_type_token.typeScope is None and (from_pointer_type_token.str in incomplete_types): + self.reportError(token, 11, 2) + elif to_pointer_type_token.typeScope is None and (to_pointer_type_token.str in incomplete_types): + self.reportError(token, 11, 2) + def misra_11_3(self, data): for token in data.tokenlist: if not isCast(token): @@ -3485,6 +3531,7 @@ class MisraChecker: self.executeCheck(1006, self.misra_10_6, cfg) self.executeCheck(1008, self.misra_10_8, cfg) self.executeCheck(1101, self.misra_11_1, cfg) + self.executeCheck(1102, self.misra_11_2, cfg) self.executeCheck(1103, self.misra_11_3, cfg) self.executeCheck(1104, self.misra_11_4, cfg) self.executeCheck(1105, self.misra_11_5, cfg) diff --git a/addons/test/misra/misra-test.c b/addons/test/misra/misra-test.c index 3fd9bd05a..b0875eebb 100644 --- a/addons/test/misra/misra-test.c +++ b/addons/test/misra/misra-test.c @@ -685,6 +685,12 @@ static void misra_10_8(u8 x, s32 a, s32 b) { int (*misra_11_1_p)(void); void *misra_11_1_bad1 = (void*)misra_11_1_p; // 11.1 +struct misra_11_2_s; +struct misra_11_2_t; + +static struct misra_11_2_s * sp; +static struct misra_11_2_t * tp = sp; // 11.2 + struct Fred {}; struct Wilma {}; static void misra_11_3(u8* p, struct Fred *fred) { x = (u64*)p; // 11.3