addons/cert.py: Add MSC30-C: Do not use rand() (#1348)

Add function isStandardFunction() that checks if the given function is a standard function.
Only when this function returns true for the currently checked rand() tokens it is reported as a violation.
Tests added for C and C++.
This commit is contained in:
Sebastian 2018-08-24 15:05:50 +02:00 committed by GitHub
parent a460ba422f
commit dce3281766
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 0 deletions

View File

@ -131,6 +131,8 @@ script:
- python3 ../misc.py -verify misc-test.cpp.dump - python3 ../misc.py -verify misc-test.cpp.dump
- ${CPPCHECK} --dump cert-test.c - ${CPPCHECK} --dump cert-test.c
- python3 ../cert.py -verify cert-test.c.dump - python3 ../cert.py -verify cert-test.c.dump
- ${CPPCHECK} --dump cert-test.cpp
- python3 ../cert.py -verify cert-test.cpp.dump
- ${CPPCHECK} --dump misra-test.c - ${CPPCHECK} --dump misra-test.c
- python3 ../misra.py -verify misra-test.c.dump - python3 ../misra.py -verify misra-test.c.dump
- ${CPPCHECK} --dump misra-test.cpp - ${CPPCHECK} --dump misra-test.cpp

View File

@ -70,6 +70,19 @@ def isCast(expr):
return False return False
return True return True
def isStandardFunction(token):
if token.function:
return False
prev = token.previous
if prev:
if prev.str == '.':
return False
if prev.str == '::':
prevprev = prev.previous
if prevprev and not prevprev.str == 'std':
return False
return True
# Get function arguments # Get function arguments
def getArgumentsRecursive(tok, arguments): def getArgumentsRecursive(tok, arguments):
if tok is None: if tok is None:
@ -215,6 +228,13 @@ def int31(data, platform):
'cert-INT31-c') 'cert-INT31-c')
break break
# MSC30-C
# Do not use the rand() function for generating pseudorandom numbers
def msc30(data):
for token in data.tokenlist:
if simpleMatch(token, "rand ( )") and isStandardFunction(token):
reportError(token, 'style', 'Do not use the rand() function for generating pseudorandom numbers', 'cert-MSC30-c')
for arg in sys.argv[1:]: for arg in sys.argv[1:]:
if arg == '-verify': if arg == '-verify':
VERIFY = True VERIFY = True
@ -238,6 +258,7 @@ for arg in sys.argv[1:]:
exp42(cfg) exp42(cfg)
exp46(cfg) exp46(cfg)
int31(cfg, data.platform) int31(cfg, data.platform)
msc30(cfg)
if VERIFY: if VERIFY:
for expected in VERIFY_EXPECTED: for expected in VERIFY_EXPECTED:

View File

@ -54,3 +54,10 @@ unsigned char int31(int x)
x = (unsigned char)-1; // cert-INT31-c x = (unsigned char)-1; // cert-INT31-c
x = (unsigned long long)-1; // cert-INT31-c x = (unsigned long long)-1; // cert-INT31-c
} }
void msc30()
{
unsigned int num = rand(); // cert-MSC30-c
int rand = 5;
int a = rand;
}

21
addons/test/cert-test.cpp Normal file
View File

@ -0,0 +1,21 @@
// To test:
// ~/cppcheck/cppcheck --dump cert-test.cpp && python ../cert.py -verify cert-test.cpp.dump
#include <cstdlib>
class msc30TestClass {
public:
static int rand();
};
void msc30(msc30TestClass & testClass)
{
unsigned int num = rand(); // cert-MSC30-c
num = std::rand(); // cert-MSC30-c
num = msc30TestClass::rand();
num = unknownClass::rand();
num = testClass.rand();
num = unknownClass.rand();
int rand = 5;
int a = rand;
}