misc.py: Added experimental ellipsisStructArg checker that warns when struct is passed to ellipsis function
This commit is contained in:
parent
194b4096c2
commit
d181e98d02
|
@ -28,6 +28,21 @@ def simpleMatch(token, pattern):
|
|||
token = token.next
|
||||
return True
|
||||
|
||||
# Get function arguments
|
||||
def getArgumentsRecursive(tok, arguments):
|
||||
if tok is None:
|
||||
return
|
||||
if tok.str == ',':
|
||||
getArgumentsRecursive(tok.astOperand1, arguments)
|
||||
getArgumentsRecursive(tok.astOperand2, arguments)
|
||||
else:
|
||||
arguments.append(tok);
|
||||
|
||||
def getArguments(ftok):
|
||||
arguments = []
|
||||
getArgumentsRecursive(ftok.astOperand2, arguments)
|
||||
return arguments
|
||||
|
||||
def isStringLiteral(tokenString):
|
||||
return tokenString.startswith('"')
|
||||
|
||||
|
@ -64,6 +79,32 @@ def implicitlyVirtual(data):
|
|||
continue
|
||||
reportError(function.tokenDef, 'style', 'Function \'' + function.name + '\' overrides base class function but is not marked with \'virtual\' keyword.', 'implicitlyVirtual')
|
||||
|
||||
def ellipsisStructArg(data):
|
||||
for cfg in data.configurations:
|
||||
for tok in cfg.tokenlist:
|
||||
if tok.str != '(':
|
||||
continue
|
||||
if tok.astOperand1 is None or tok.astOperand2 is None:
|
||||
continue
|
||||
if tok.astOperand1.function is None:
|
||||
continue
|
||||
for argnr, argvar in tok.astOperand1.function.argument.items():
|
||||
if argnr < 1:
|
||||
continue
|
||||
if not simpleMatch(argvar.typeStartToken, '. . .'):
|
||||
continue
|
||||
callArgs = getArguments(tok)
|
||||
for i in range(argnr-1, len(callArgs)):
|
||||
valueType = callArgs[i].valueType
|
||||
if not valueType:
|
||||
continue
|
||||
if valueType.pointer > 0:
|
||||
continue
|
||||
if valueType.type != 'record':
|
||||
continue
|
||||
reportError(tok, 'style', 'Passing record to ellipsis function \'' + tok.astOperand1.function.name + '\'.', 'ellipsisStructArg')
|
||||
break
|
||||
|
||||
for arg in sys.argv[1:]:
|
||||
if arg == '-verify':
|
||||
continue
|
||||
|
@ -76,11 +117,12 @@ for arg in sys.argv[1:]:
|
|||
for tok in data.rawTokens:
|
||||
if tok.str.startswith('//'):
|
||||
for word in tok.str[2:].split(' '):
|
||||
if word == 'stringConcatInArrayInit' or word == 'implicitlyVirtual':
|
||||
if word in ['stringConcatInArrayInit', 'implicitlyVirtual', 'ellipsisStructArg']:
|
||||
VERIFY_EXPECTED.append(str(tok.linenr) + ':' + word)
|
||||
|
||||
stringConcatInArrayInit(data.rawTokens)
|
||||
implicitlyVirtual(data)
|
||||
ellipsisStructArg(data)
|
||||
|
||||
if VERIFY:
|
||||
for expected in VERIFY_EXPECTED:
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// To test:
|
||||
// ~/cppcheck/cppcheck --dump misc-test.c && python ../misc.py -verify misc-test.c.dump
|
||||
// ~/cppcheck/cppcheck --dump misc-test.cpp && python ../misc.py -verify misc-test.cpp.dump
|
||||
|
||||
|
||||
// Warn about string concatenation in array initializers..
|
||||
const char *a[] = {"a" "b"};
|
||||
const char *b[] = {"a","b" "c"}; // stringConcatInArrayInit
|
||||
const char *c[] = {
|
||||
|
@ -17,6 +19,8 @@ const char *c[] = {
|
|||
"b\n"
|
||||
};
|
||||
|
||||
|
||||
// Function is implicitly virtual
|
||||
class base {
|
||||
virtual void dostuff(int);
|
||||
};
|
||||
|
@ -24,3 +28,11 @@ class base {
|
|||
class derived : base {
|
||||
void dostuff(int); // implicitlyVirtual
|
||||
};
|
||||
|
||||
|
||||
// Pass struct to ellipsis function
|
||||
struct {int x;int y;} s;
|
||||
void ellipsis(int x, ...);
|
||||
void foo(void) {
|
||||
ellipsis(321, s); // ellipsisStructArg
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue