Misra: Added 17.2 checker
This commit is contained in:
parent
526a86dc60
commit
f524bf79ad
|
@ -88,7 +88,6 @@ class ValueType:
|
|||
return self.typeScope and self.typeScope.type == "Enum"
|
||||
|
||||
|
||||
|
||||
class Token:
|
||||
"""
|
||||
Token class. Contains information about each token in the source code.
|
||||
|
@ -288,6 +287,8 @@ class Scope:
|
|||
className Name of this scope.
|
||||
For a function scope, this is the function name;
|
||||
For a class scope, this is the class name.
|
||||
function If this scope belongs at a function call, this attribute
|
||||
has the Function information. See the Function class.
|
||||
type Type of scope: Global, Function, Class, If, While
|
||||
"""
|
||||
|
||||
|
@ -297,6 +298,8 @@ class Scope:
|
|||
bodyEndId = None
|
||||
bodyEnd = None
|
||||
className = None
|
||||
functionId = None
|
||||
function = None
|
||||
nestedInId = None
|
||||
nestedIn = None
|
||||
type = None
|
||||
|
@ -305,6 +308,8 @@ class Scope:
|
|||
def __init__(self, element):
|
||||
self.Id = element.get('id')
|
||||
self.className = element.get('className')
|
||||
self.functionId = element.get('function')
|
||||
self.function = None
|
||||
self.bodyStartId = element.get('bodyStart')
|
||||
self.bodyStart = None
|
||||
self.bodyEndId = element.get('bodyEnd')
|
||||
|
@ -318,6 +323,7 @@ class Scope:
|
|||
self.bodyStart = IdMap[self.bodyStartId]
|
||||
self.bodyEnd = IdMap[self.bodyEndId]
|
||||
self.nestedIn = IdMap[self.nestedInId]
|
||||
self.function = IdMap[self.functionId]
|
||||
|
||||
|
||||
class Function:
|
||||
|
@ -325,6 +331,12 @@ class Function:
|
|||
Information about a function
|
||||
C++ class:
|
||||
http://cppcheck.net/devinfo/doxyoutput/classFunction.html
|
||||
|
||||
Attributes
|
||||
argument Argument list
|
||||
tokenDef Token in function definition
|
||||
isVirtual Is this function is virtual
|
||||
isImplicitlyVirtual Is this function is virtual this in the base classes
|
||||
"""
|
||||
|
||||
Id = None
|
||||
|
|
|
@ -1580,6 +1580,54 @@ class MisraChecker:
|
|||
elif token.str == 'va_list':
|
||||
self.reportError(token, 17, 1)
|
||||
|
||||
def misra_17_2(self, data):
|
||||
# find recursions..
|
||||
def find_recursive_call(search_for_function, direct_call, calls_map, visited=set()):
|
||||
if direct_call == search_for_function:
|
||||
return True
|
||||
for indirect_call in calls_map[direct_call]:
|
||||
if indirect_call == search_for_function:
|
||||
return True
|
||||
if indirect_call in visited:
|
||||
# This has already been handled
|
||||
continue
|
||||
visited.add(indirect_call)
|
||||
if find_recursive_call(search_for_function, indirect_call, calls_map, visited):
|
||||
return True
|
||||
return False
|
||||
|
||||
# List functions called in each function
|
||||
function_calls = {}
|
||||
for scope in data.scopes:
|
||||
if scope.type != 'Function':
|
||||
continue
|
||||
calls = []
|
||||
tok = scope.bodyStart
|
||||
while tok != scope.bodyEnd:
|
||||
tok = tok.next
|
||||
if not isFunctionCall(tok):
|
||||
continue
|
||||
f = tok.astOperand1.function
|
||||
if f is not None and f not in calls:
|
||||
calls.append(f)
|
||||
function_calls[scope.function] = calls
|
||||
|
||||
# Report warnings for all recursions..
|
||||
for func in function_calls:
|
||||
for call in function_calls[func]:
|
||||
if not find_recursive_call(func, call, function_calls):
|
||||
# Function call is not recursive
|
||||
continue
|
||||
# Warn about all functions calls..
|
||||
for scope in data.scopes:
|
||||
if scope.type != 'Function' or scope.function != func:
|
||||
continue
|
||||
tok = scope.bodyStart
|
||||
while tok != scope.bodyEnd:
|
||||
if tok.function and tok.function == call:
|
||||
self.reportError(tok, 17, 2)
|
||||
tok = tok.next
|
||||
|
||||
|
||||
def misra_17_6(self, rawTokens):
|
||||
for token in rawTokens:
|
||||
|
@ -2313,6 +2361,7 @@ class MisraChecker:
|
|||
self.misra_16_6(cfg)
|
||||
self.misra_16_7(cfg)
|
||||
self.misra_17_1(cfg)
|
||||
self.misra_17_2(cfg)
|
||||
if cfgNumber == 1:
|
||||
self.misra_17_6(data.rawTokens)
|
||||
self.misra_17_7(cfg)
|
||||
|
|
|
@ -224,8 +224,9 @@ void misra_11_7(int *p, float f) {
|
|||
y = ( int * ) f; //11.7
|
||||
}
|
||||
|
||||
char * misra_11_8_const(const char *str) { }
|
||||
char * misra_11_8(const char *str) {
|
||||
(void)misra_11_8(str); // no-warning
|
||||
(void)misra_11_8_const(str); // no-warning
|
||||
return (char *)str; // 11.8
|
||||
}
|
||||
|
||||
|
@ -495,6 +496,33 @@ void misra_17_1() {
|
|||
va_copy(); // 17.1
|
||||
}
|
||||
|
||||
void misra_17_2_ok_1(void) { ; }
|
||||
void misra_17_2_ok_2(void) {
|
||||
misra_17_2_ok_1(); // no-warning
|
||||
}
|
||||
void misra_17_2_1(void) {
|
||||
misra_17_2_ok_1(); // no-warning
|
||||
misra_17_2_1(); // 17.2
|
||||
misra_17_2_ok_2(); // no-warning
|
||||
misra_17_2_1(); // 17.2
|
||||
}
|
||||
void misra_17_2_2(void) {
|
||||
misra_17_2_3(); // 17.2
|
||||
}
|
||||
void misra_17_2_3(void) {
|
||||
misra_17_2_4(); // 17.2
|
||||
}
|
||||
void misra_17_2_4(void) {
|
||||
misra_17_2_2(); // 17.2
|
||||
misra_17_2_3(); // 17.2
|
||||
}
|
||||
|
||||
void misra_17_2_5(void) {
|
||||
misra_17_2_ok_1(); // no-warning
|
||||
misra_17_2_5(); // 17.2
|
||||
misra_17_2_1(); // no-warning
|
||||
}
|
||||
|
||||
void misra_17_6(int x[static 20]) {} // 17.6
|
||||
|
||||
int calculation(int x) { return x + 1; }
|
||||
|
|
Loading…
Reference in New Issue