Skip to content

Commit d181e98

Browse files
committed
misc.py: Added experimental ellipsisStructArg checker that warns when struct is passed to ellipsis function
1 parent 194b409 commit d181e98

2 files changed

Lines changed: 56 additions & 2 deletions

File tree

addons/misc.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ def simpleMatch(token, pattern):
2828
token = token.next
2929
return True
3030

31+
# Get function arguments
32+
def getArgumentsRecursive(tok, arguments):
33+
if tok is None:
34+
return
35+
if tok.str == ',':
36+
getArgumentsRecursive(tok.astOperand1, arguments)
37+
getArgumentsRecursive(tok.astOperand2, arguments)
38+
else:
39+
arguments.append(tok);
40+
41+
def getArguments(ftok):
42+
arguments = []
43+
getArgumentsRecursive(ftok.astOperand2, arguments)
44+
return arguments
45+
3146
def isStringLiteral(tokenString):
3247
return tokenString.startswith('"')
3348

@@ -64,6 +79,32 @@ def implicitlyVirtual(data):
6479
continue
6580
reportError(function.tokenDef, 'style', 'Function \'' + function.name + '\' overrides base class function but is not marked with \'virtual\' keyword.', 'implicitlyVirtual')
6681

82+
def ellipsisStructArg(data):
83+
for cfg in data.configurations:
84+
for tok in cfg.tokenlist:
85+
if tok.str != '(':
86+
continue
87+
if tok.astOperand1 is None or tok.astOperand2 is None:
88+
continue
89+
if tok.astOperand1.function is None:
90+
continue
91+
for argnr, argvar in tok.astOperand1.function.argument.items():
92+
if argnr < 1:
93+
continue
94+
if not simpleMatch(argvar.typeStartToken, '. . .'):
95+
continue
96+
callArgs = getArguments(tok)
97+
for i in range(argnr-1, len(callArgs)):
98+
valueType = callArgs[i].valueType
99+
if not valueType:
100+
continue
101+
if valueType.pointer > 0:
102+
continue
103+
if valueType.type != 'record':
104+
continue
105+
reportError(tok, 'style', 'Passing record to ellipsis function \'' + tok.astOperand1.function.name + '\'.', 'ellipsisStructArg')
106+
break
107+
67108
for arg in sys.argv[1:]:
68109
if arg == '-verify':
69110
continue
@@ -76,11 +117,12 @@ def implicitlyVirtual(data):
76117
for tok in data.rawTokens:
77118
if tok.str.startswith('//'):
78119
for word in tok.str[2:].split(' '):
79-
if word == 'stringConcatInArrayInit' or word == 'implicitlyVirtual':
120+
if word in ['stringConcatInArrayInit', 'implicitlyVirtual', 'ellipsisStructArg']:
80121
VERIFY_EXPECTED.append(str(tok.linenr) + ':' + word)
81122

82123
stringConcatInArrayInit(data.rawTokens)
83124
implicitlyVirtual(data)
125+
ellipsisStructArg(data)
84126

85127
if VERIFY:
86128
for expected in VERIFY_EXPECTED:

addons/test/misc-test.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// To test:
2-
// ~/cppcheck/cppcheck --dump misc-test.c && python ../misc.py -verify misc-test.c.dump
2+
// ~/cppcheck/cppcheck --dump misc-test.cpp && python ../misc.py -verify misc-test.cpp.dump
33

4+
5+
// Warn about string concatenation in array initializers..
46
const char *a[] = {"a" "b"};
57
const char *b[] = {"a","b" "c"}; // stringConcatInArrayInit
68
const char *c[] = {
@@ -17,10 +19,20 @@ const char *c[] = {
1719
"b\n"
1820
};
1921

22+
23+
// Function is implicitly virtual
2024
class base {
2125
virtual void dostuff(int);
2226
};
2327

2428
class derived : base {
2529
void dostuff(int); // implicitlyVirtual
2630
};
31+
32+
33+
// Pass struct to ellipsis function
34+
struct {int x;int y;} s;
35+
void ellipsis(int x, ...);
36+
void foo(void) {
37+
ellipsis(321, s); // ellipsisStructArg
38+
}

0 commit comments

Comments
 (0)