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
|
token = token.next
|
||||||
return True
|
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):
|
def isStringLiteral(tokenString):
|
||||||
return tokenString.startswith('"')
|
return tokenString.startswith('"')
|
||||||
|
|
||||||
|
@ -64,6 +79,32 @@ def implicitlyVirtual(data):
|
||||||
continue
|
continue
|
||||||
reportError(function.tokenDef, 'style', 'Function \'' + function.name + '\' overrides base class function but is not marked with \'virtual\' keyword.', 'implicitlyVirtual')
|
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:]:
|
for arg in sys.argv[1:]:
|
||||||
if arg == '-verify':
|
if arg == '-verify':
|
||||||
continue
|
continue
|
||||||
|
@ -76,11 +117,12 @@ for arg in sys.argv[1:]:
|
||||||
for tok in data.rawTokens:
|
for tok in data.rawTokens:
|
||||||
if tok.str.startswith('//'):
|
if tok.str.startswith('//'):
|
||||||
for word in tok.str[2:].split(' '):
|
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)
|
VERIFY_EXPECTED.append(str(tok.linenr) + ':' + word)
|
||||||
|
|
||||||
stringConcatInArrayInit(data.rawTokens)
|
stringConcatInArrayInit(data.rawTokens)
|
||||||
implicitlyVirtual(data)
|
implicitlyVirtual(data)
|
||||||
|
ellipsisStructArg(data)
|
||||||
|
|
||||||
if VERIFY:
|
if VERIFY:
|
||||||
for expected in VERIFY_EXPECTED:
|
for expected in VERIFY_EXPECTED:
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
// To test:
|
// 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 *a[] = {"a" "b"};
|
||||||
const char *b[] = {"a","b" "c"}; // stringConcatInArrayInit
|
const char *b[] = {"a","b" "c"}; // stringConcatInArrayInit
|
||||||
const char *c[] = {
|
const char *c[] = {
|
||||||
|
@ -17,6 +19,8 @@ const char *c[] = {
|
||||||
"b\n"
|
"b\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Function is implicitly virtual
|
||||||
class base {
|
class base {
|
||||||
virtual void dostuff(int);
|
virtual void dostuff(int);
|
||||||
};
|
};
|
||||||
|
@ -24,3 +28,11 @@ class base {
|
||||||
class derived : base {
|
class derived : base {
|
||||||
void dostuff(int); // implicitlyVirtual
|
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