* Fix#9225 (Crash on valid C++14 code)
This only fixes the crash. Specialization of nested templates is still
broken.
* fix cppcheck warnings
* fixed another cppcheck warning
* Use library for memleak checks
Change memleakOnRealloc and leakReturnValNotUsed to use library
configuration instead of hardcoding "realloc".
In order to do so, some care needs to be taken when matching for a
reallocation function, since it can no longer be assumed that the input
to be allocated is the first argument of the function. This complicates
getReallocationType() and checkReallocUsage() but is necessary in order
to handle for example freopen() properly.
Also, refactor memleakOnRealloc check to reduce duplicated code when
checking "a" and "*a". When doing so, extending the check to look for
arbitrary number of "*" can be done for free (just change an if
statement to a while statement). Most likely, this is an unusual case in
real world code.
* Remove redundant whitespace in Token::Match()
* Run on simplified checks
* Fix cppcheck warning
* Fix FP memory leak with unknown function call in condition
This was introduced in 8513fb81d2 when
fixing memory leaks for global variables allocated in condition. The
refactored code had an inconsistency where c and c++ code behaved
slightly differently when `var` is NULL. This seemed to not have an
impact as the code was written prior to 8513fb81d2,
but when the same code was used for conditions, FPs were introduced.
The introduced FPs were memleak warnings when there should have been an
information message about missing configurations for code like
void f() {
char *p = malloc(10);
if (set_data(p)) {}
}
Fix this by always returning true if varTok->Variable() is NULL for
both c and c++ code.
* Improve function name
This will diagnose more issues such as:
```cpp
void f(std::vector<int> &v) {
auto v0 = v.begin();
v.push_back(123);
std::cout << *v0 << std::endl;
}
```
* Improve configuration of g_try_realloc and g_try_realloc_n
* Mark g_realloc and similar functions as realloc functions
* Remove g_new, g_new0, etc as <alloc> functions, these are defined as
macros and handled as the functions they're expanded to.
* Add tests. TODO tests will be resolved by using the library
configuration in the checker.
* Fix adding unescaped slash token when splitting gcc case range.
Construction like case '!'...'~' converted to a list of separate case
tokens. When slas '\' symbol appears as a part of this list it was added
"as is", but it should be escaped like '\\' to be valid c++ code.
* Add test for switch-case range with slash
* Fix#9097 (Crash on thousands of "else ifs"s in gcc-avr package)
* increase recursion count maximum to 512 because cppcheck was hitting the 256 limit
* 512 was too much for windows
* Refactor Tokenizer::simplifyUsing to use continue to reduce indentation
added function findTemplateDeclarationEnd to skip template declarations
to reduce duplicate code
* fix travis build
This switches to use lifetime analysis to check for assigning to non-local variables:
```cpp
class test
{
public:
void f()
{
int x;
this->ptr = &x;
}
protected:
int *ptr;
};
```
* Partial fix for #9191 (simplifyTypedef: Problem when namespace is used)
This fixes simplifyUsing which has the same problem as simplifyTypedef.
simplifyUsing was designed to support using namespace but it was never
implemented. The changes are minor to add it.
simplifyTypedef requires much more work to support using namespace.
* reduce scope of variable
* make idx const
* Allow to configure realloc like functions
* memleakonrealloc: Bring back tests.
The old memleak checker was removed, and the tests for it was removed in
commit 9765a2dfab. This also removed the
tests for memleakOnRealloc. Bring back those tests, somewhat modified
since the checker no longer checks for memory leaks.
* Add realloc to mem leak check
* Add tests of realloc buffer size
* Configure realloc functions
* Add test of freopen
* Allow to configure which element is realloc argument
* Fix wrong close in test
cppcheck now warns for this
* Update manual
* Update docs
* Rename alloc/dalloc/realloc functions
Naming the member function realloc caused problems on appveyor. Rename
the alloc and dealloc functions as well for consistency.
* Change comparisson order
* Remove variable and use function call directly
* Create temporary variable to simplify
* Throw mismatchError on mismatching allocation/reallocation
* Refactor to separate function
* Fix potential nullptr dereference
As pointed out by cppcheck.
* Overlapping sprintf, improve handling of casts
If there is a cast of the argument buffer, cppcheck would print out the
expression including the cast, which looks a bit strange to talk about
Variable (char*)buf is used as...
Instead, only print the variable name without the cast.
Also, handle arbitrary many casts (the previous code only handled one).
Multiple casts of the input arguments is probably an unusual case in
real code, but can perhaps occur if macros are used.
* Fix printing of variable
... and add a test.
* Simplify testcase
* Update symbol database such that the override keyword implies that the function is also virtual
* Add test case for implicit override
* change isVirtual to hasVirtualSpecifier
* fix method documentation for getVirtualFunctionCalls and getFirstVirtualFunctionCallStack
* Fix isImplicitlyVirtual to consider the override keyword and document logic
* Fix getFirstVirtualFunctionCallStack and getVirtualFunctionCalls to use isImplicitlyVirtual instead of isVirtual so new test case passes
* Fix#9047 (c-style casts before malloc)
Note that there are still no warnings for c++-style casts
* Fix memleak check with casts of assignments in if-statements
* Fix possible null pointer dereference
As pointed out by cppcheck.
* Add check of astOperand2 when removing casts
This is similar to how it is done in other checks.
Further to pull request #1938. Changes were missed in previous commit.
Resolve warnings `warning: zero as null pointer constant` in code by
using C++ 11 recommended `nullptr`.
Building with enhanced clang warnings indicated a large number of
instances with the warning:
`warning: zero as null pointer constant`
Recommended practice in C++11 is to use `nullptr` as value for
a NULL or empty pointer value. All instances where this warning
was encountered were corrected in this commit.
Where warning was encountered in dependency code (i.e. external library)
no chnages were made. Patching will be offered upstream.
* fix adding instantiation of first argument to an instantiation
* add support for function pointer template variables
* fix more cases where templates ending in ">>" are changed to end in "> >"
* fix travis build
* standard types can't be a template parameter name
* remove redundant level == 0 checks
* fix lambda in template variable
* fix a test
This reverts commit 2a4be5ae1c.
When I look at daca@home now there are still lots of false negatives. So this bailout did not cause as much false negatives as I thought.
strdup() allocates the string length plus one for a terminating null
character. Add one to compensate for this.
Fixes false positive buffer out of bounds on code like this:
void f() {
const char *a = "abcd";
char * b = strdup(a);
printf("%c", b[4]); // prints the terminating null character
free(b);
}
Also, add a testcase for valueFlowDynamicBufferSize() and add tests for
strdup(), malloc() and calloc().
* Add non const version of some methods of Token
The aim is to reduce the (ab)use of const_cast.
* Cleanup some more const_cast in valueflow
* Remove useless const_cast
* Remove some const_cast from templatesimplifier
* Remove some const_cast from valueflow
* template simplifier: add 2 new template parameter simplifications
int{} -> 0
decltype(int{}) -> int
This fixes reduced test cases like #9153. I'm not sure they will help
real world code that much.
It was necessary to increase the pass count to 4 to get #9153 completly
simplified.
* relax decltype(type{}) simplification to any type
Refactored simplifyTemplateAliases to iterate over template type aliases
rather than instantiations. This fixed template type aliases that were
not templates.
Don't instantiate templates in template type aliases. They will get
instantiated once the type alias is instantiated. This required
increasing the template simplifier pass count to 3 so one of the
existing tests continued to work.
Specialized member classes declared outsize the class were not
recognized. This caused the the member class to be instantiated rather
than the specialized class. We already had a test for this but it was
wrong so it went unnoticed.
With the following code
int f(int x, int y) {
if (!!(x != 0)) {
return y/x;
}
cppcheck would wrongly warn that there might be a division by zero in
"return y/x;".
* template simplifier: fix instantiation of variadic template with no arguments
* fix white space change
* add support for <class...>
* add variadic template flag
* Fix issue 8890: AST broken calling member function from templated base class
* Format
* Check for double bracket
* Add test to createLinks2
* Remove extra test
* Reduce test case for links
This will warn for cases where searching in an associative container happens before insertion, like this:
```cpp
void f1(std::set<unsigned>& s, unsigned x) {
if (s.find(x) == s.end()) {
s.insert(x);
}
}
void f2(std::map<unsigned, unsigned>& m, unsigned x) {
if (m.find(x) == m.end()) {
m.emplace(x, 1);
} else {
m[x] = 1;
}
}
```
In the case of the map it could be written as `m[x] = 1` as it will create the key if it doesnt exist, so the extra search is not necessary.
I have this marked as `performance` as it is mostly concerning performance, but there could be a copy-paste error possibly, although I dont think thats common.
A common pattern is to have a function like similar to this:
bool isFlagSet(uint32_t f) {
return f & 0x4;
}
Warning that the function returns a non-boolean in this case is too
noisy, it would be better suited for a Misra check, so remove the
warnings in the most obvious cases.
Change the astStringVerbose() recursion to extend a string instead of
returning one. This has the benefit that for tokens where the recursion
runs deep (typically large arrays), the time savings can be substantial
(see comments on benchmarks further down).
The reason is that previously, for each token, the astString of its
operands was constructed, and then appended to this tokens astString.
This led to a lot of unnecessary string copying (and with that
allocations). Instead, by passing the string by reference, the number
of temporary strings is greatly reduced.
Another way of seeing it is that previously, the string was constructed
from end to beginning, but now it is constructed from the beginning to
end. There was no notable speedup by preallocating the entire string
using string::reserve() (at least not on Linux).
To benchmark, the changes and master were tested on Linux using the
commands:
make
time cppcheck --debug --verbose $file >/dev/null
i.e., the cppcheck binary was compiled with the settings in the
Makefile. Printing the output to screen or file will of course take
longer time.
In Trac ticket #8355 which triggered this change, an example file from the
Wine repository was attached. Running the above cppcheck on master took
24 minutes and with the changes in this commmit, took 22 seconds.
Another test made was on lib/tokenlist.cpp in the cppcheck repo, which is
more "normal" file. On that file there was no measurable time difference.
A synthetic benchmark was generated to illustrate the effects on dumping
the ast for arrays of different sizes. The generate code looked as
follows:
const int array[] = {...};
with different number of elements. The results are as follows (times are
in seconds):
N master optimized
10 0.1 0.1
100 0.1 0.1
1000 2.8 0.7
2000 19 1.8
3000 53 3.8
5000 350 10
10000 3215 38
As we can see, for small arrays, there is no time difference, but for
large arrays the time savings are substantial.
Before this fix, the code:
```
class A {
A(int, int x=3){
x;
}
};
```
Was considered OK.
But explicit keyword is still needed
I'm still new to open-source contributions, so I will gladly take advice.
This fixes simplifyUsing to remove 'typename' and 'template' from type
aliases of the form: using T3 = typename T1::template T3<T2>;
This lets the template simplifier instantiate the type alias which will
then remove the using type alias.
The crash will still happen if there is no instantiation because the
type alias will not be removed. The type alias is what cppcheck is
crashing on after the template simplifier and that still needs fixing.
* Fixed#8889 (varid on function when using trailing return type.)
Don't set varid for trailing return type.
* Add a test for #9066 (Tokenizer::setVarId: varid set for trailing return type)
* Handle 'arguments' sections in compile_commands.json
Previous code assumes 'commands' exists and ill assert if t does not.
* Correct typo checking for "arguments" rather than "commands"
* Use ostringstring rather than stringstream
* Add test deominstrating graceful degradation
* Add test for parsing "arguments" rather than "commands"
This is trying to fix the issue by fixing the ast and symbol database. First, the ast nodes will be created for the init list and the symbol database will not mark it as a scope. I am not sure if this is the correct approach as I dont really understand how the AST part works.
It did change the AST for `try {} catch (...) {}` but that is because it incorrectly treats `try {}` as an initializer list.
Improve the internal check for redundant null pointer check before
calling Token::Match() (and friends). Now, warn about code snippets like
if (a && tok && Token::Match(tok, "foo"))
Also, extend the check for the inverted case.
There is still no warning for
if (tok && a && Token::Match(tok, "foo"))
since that would require checking if a is independent of tok.
* teststring.cpp: Fix ternary syntax in tests
* stringLiteralWrite: Add tests wide character and utf16 strings
* suspiciousStringCompare: Add test with wide character string
* strPlusChar: Handle wide characters
* incorrectStringCompare: Add test with wide string
* Suspicious string compare: suggest wcscmp for wide strings
* deadStrcmp: Extend to handle wide strings
* sprintfOverlappingData: Print name of strcmp function
* Conversion of char literal to boolean, add wide character tests
* Conversion of char literal to boolean, fix ternary
This only fixes the crash. It does not fix the underlying problem of
template using with templates of templates causing the use of deleted
instantiations.
This fixes issue 8996 by improving the alias checking by using lifetime analysis. It also extends the lifetime checker to handle constructors and initializer lists for containers and arrays.
Some POSIX and Windows functions require buffers of at least some
specific size. This is now possible to configure via for example this
minsize configuration: `<minsize type="value" value="26"/>`.
The range for valid buffer size values is 1 to LLONG_MAX
(9223372036854775807)
- Remove redundant function configurations for the same function since
it is not (yet) possible to configure overloaded functions. Instead mark
the optional arguments with `default="0"` so the configuration works
with a different number of arguments.
- Add documentation to boost.cfg (links and function declarations).
- Rearranged configurations so functions, defines, ... are together now.
- Add `direction` for function arguments where applicable.
- Add some tests to boost.cpp.
There are important TODOs still; for instance adding CTU support using our CTU infrastructure, add handling of pointers (maybe I'll use FwdAnalysis for this), add handling of multidimensional arrays, etc..
This handles concatenated strings and characters from simplecpp.
Previously, L'c' would be preprocessed to the tokens "L" and "'c'".
cppcheck would then remove the "L" token and set "'c'" to be a wide
character literal. Now, it needs to remove the prefix instead.
When doing this, add handling of utf32 encoded literals (U) and UTF-8
encoded literals (u8).
CheckUninitVar::isMemberVariableAssignment uses argument direction "out"
now also to check for assignment when the member variable is handed over
to a function by reference.
testuninitvar.cpp: Improve tests, use a test library configuration.
strcpy_s belongs to the standard so it must be in std.cfg instead of
windows.cfg.
Configuration for strcpy_s has been improved and tests were added.
Found by daca@home
* std.cfg: Add further argument directions (in, out, inout).
* testlibrary.cpp: Add test for function argument direction configuration.
* std.cfg: runastyle and add some more direction configurations.
* library.h: Add documentation for function argument direction enum.
* Do not use "direction" library information for pointer arguments.
Also fix further unmatched uninitvar messages in std configuration
tests.
* std.cfg: Add more argument direction configurations.
* test/cfg/std.c: Add test for argument direction configuration.
* astutils.cpp: Only ignore pointer arguments for out/inout arguments.
* library.h: Use suggested documentation for argument direction enum.
For now, only print the ways of running testrunner and the few options
that are available.
Also, refactor to remove an unneeded const_cast and use a range for loop.
Partially fixes#8514.
* template simplifier: make sure all instantiations are found and expanded in #5097
* template simplifier: check output on another test
* template simplifier: add output to another test
* template simplifier: instantiate template class when something inside class instantiated.
* template simplifier: add output to another test that now works
This uses the lifetime analysis to check when comparing pointer that point to different objects:
```cpp
int main(void)
{
int foo[10];
int bar[10];
int diff;
if(foo > bar) // Undefined Behavior
{
diff = 1;
}
return 0;
}
```
This will now warn for cases like this:
```cpp
auto& f() {
std::vector<int> x;
return x[0];
}
```
It also improves the handling of address of operator, so it can now warn across some function calls, like this:
```cpp
int& f(int& a) {
return a;
}
int* hello() {
int x = 0;
return &f(x);
}
```
Even if `ptr` is a local variable, the object `ptr->item` might be not.
So taking address of `ptr->item` is definitely not unsafe in general.
This commit fixes false positives triggered by commit
1.85-249-gf42648fe2 on the following code of sssd:
https://github.com/SSSD/sssd/blob/d409df33/src/sbus/request/sbus_request.c#L359
This reworks constStatement to find more issues. It catches issue [8827](https://trac.cppcheck.net/ticket/8827):
```cpp
extern void foo(int,const char*,int);
void f(int value)
{
foo(42,"test",42),(value&42);
}
```
It also catches from issue [8451](https://trac.cppcheck.net/ticket/8451):
```cpp
void f1(int x) {
1;
(1);
(char)1;
((char)1);
!x;
(!x);
~x;
}
```
And also:
```cpp
void f(int x) {
x;
}
```
The other examples are not caught due to incomplete AST.
Add a call to simplifyPlatformTypes() in
SymbolDatabase::setValueTypeInTokenList() to simplify return types of
library configured functions. This fixes the FN in #8141. Regression
tests are added, both for the original issue and another FN in the comments.
In order to do that, move simplifyPlatformTypes() to TokenList from Tokenizer.
This is a pure refactoring and does not change any behaviour. The code was
literally copy-pasted from one file to another and in two places
'list.front()' was changed to 'front()'.
When adding the call to simplifyPlatformTypes(), the original type of
v.size() where v is a container is changed from 'size_t' to 'std::size_t'.
Tests are updated accordingly. It can be noted that if v is declared as
'class fred : public std::vector<int> {} v', the original type of 'v.size()'
is still 'size_t' and not 'std::size_t'.
* Fixed#8962 ("(debug) Unknown type 'T'" with template typename parameter)
Only simple one parameter template functions with one function parameter
are supported.
* Added TODO test case for FIXME.
* Fixed#8971 ("(debug) Unknown type 'x'." using alias in class members)
* template simplifier: partial fix for #8972
Add support for multi-token default template parameters.
* template simplifier: fix for #8971
Remove typename outside of templates.
Qt defines `Q_NULLPTR` with `nullptr` if it is available, otherwise with `NULL`.
Since there seems to be no (sane) way to configure it the same way in the library configuration it is just defined with `NULL`.
* Fixed#8960 ("(debug) Unknown type 'x'." with alias in template class alias)
This commit adds non-template type alias support to the template
simplifier. Only relatively simple type aliases are supported at this
time. More complex types will be added later.
--debug-warnings will show unsupported type aliases.
Type alias support will be removed from the symbol database in the
future. Type alias tests have been removed from the symbol database
tests.
* Add the changes.
* Fix codacy warning.
* Fix travis warnings.
* template simplifier: fix crash on windows
Use right token when searching for template type alias to delete.
* template simplifier: fix a cppcheck warning
* Remove newlines after check(
* Remove unneeded statements after if-statements
As an example, the previous test case
check(
"bool foo(int x) {\n"
" if (x < 0)"
" return true;\n"
" return false;\n"
"}");
is changed to
check("void foo(int x) {\n"
" if (x < 0) {}\n"
"}");
This has basic handling of GUI projects. But further work will be needed to handle addons etc, the plan is that we will be able to run addons from the command line soon.
The unsigned less than zero checker looked for patterns like "<= 0".
Switching to use valueflow improves the checker in a few aspects.
First, it removes false positives where instead of 0, the code is using
0L, 0U, etc. Instead of having to hard code the different variants of 0,
valueflow handles this automatically. This fixes FPs on the form
uint32_t value = 0xFUL;
void f() {
if (value < 0u)
{
value = 0u;
}
}
where 0u was previously not recognized by the checker. This fixes#8836.
Morover, it makes it possible to handle templates properly. In commit
fa076598ad, all warnings inside templates
were made inconclusive, since the checker had no idea if "0" came from
a template parameter or not.
This makes it possible to not warn for the following case which was
reported as a FP in #3233
template<int n> void foo(unsigned int x) {
if (x <= n);
}
foo<0>();
but give a warning for the following case
template<int n> void foo(unsigned int x) {
if (x <= 0);
}
Previously, both these cases gave inconclusive warnings.
Finally, it makes it possible to give warnings for the following code:
void f(unsigned x) {
int y = 0;
if (x <= y) {}
}
Also, previously, the checker for unsigned variables larger than 0, the
checker used the string of the astoperand. This meant that for code like
the following:
void f(unsigned x, unsigned y) {
if (x -y >= 0) {}
}
cppcheck would output
[unsigned-expression-positive.c] (style) Unsigned variable '-' can't be negative so it is unnecessary to test it.
using expressionString() instead gives a better error message
[unsigned-expression-positive.c] (style) Unsigned expression 'x-z' can't be negative so it is unnecessary to test it.
Use `--check-library` for all tests as it was done before.
Re-enable all tests in runtests.sh again.
The regressions where runtests.sh would fail are disabled via "FIXME"
comment in the inline suppression comment.
* Add regression test for #6906
Ticket #6906 was fixed in f65cf220ba.
Add a test to make sure there are no regressions.
* Add regression test for #7284
Ticket #7284 was fixed in 5d1fdf7958.
Add tests to avoid regressions.
This will use the lifetime checker for dangling references. It will find these cases for indirectly assigned reference:
```cpp
int &foo()
{
int s = 0;
int& x = s;
return x;
}
```
This will also fix issue 510 as well:
```cpp
int &f( int k )
{
static int &r = k;
return r;
}
```
As discussed in https://trac.cppcheck.net/ticket/8931 a regression test is added
to the test/cfg/runtests.sh script to make sure that unmatchedSuppression messages result in an Cppcheck exit code that signals a failure.
On linux systems (like travis) Qt often seems to be built with the option "reduce_relocations" which requires an application using it to specify the option "-fPIC".
* fix for CMake compile_commands.json input - director does not include trailing / which makes include directories wrong - so add it if it doesnt exist
* fix the bugfix for trailing / in the directory name of CMAKE JSON file, add also new test case to see if it works in both cases (with and without trailing /)
* revert adding accidental new line
To be able to use real Qt-Code in "test/cfg/qt.cpp" and still do a
syntax check the Qt settings are read out via pkg-config now if it is
available. This way the test now can contain Qt macros and functions and
the syntax check can still be used.
Additionally the same options as for the other tests are used now for
the Qt config tests.
Installing the package "qtbase5-dev" should be enough to enable the
syntax checks (already installed for travis tests).
This fixes valueflow to have a value for `||` operator here:
```cpp
bool f()
{
bool a = (4 == 3); // <-- 0
bool b = (3 == 3); // <-- 1
return a || b; // <-- 1
}
```
When comparing if the shift is large enough to make the result zero, use
an unsigned long long to make sure the result fits. Also, a check that
avoids setting the value if the shift is equal to or larger than the
number of bits in the operand (this is undefined behaviour). Finally,
add a check to make sure the calculated value is not too large to store.
Add test cases to cover this.
This was detected by an MSVC warning.
valueflow.cpp(1350): warning C4334: '<<' : result of 32-bit shift implicitly
converted to 64 bits (was 64-bit shift intended?)
This fixes issue in:
```cpp
void f()
{
char stack[512];
RGNDATA *data;
if (data_size > sizeof (stack))
data = malloc (data_size);
else
data = (RGNDATA *)stack;
if ((char *)data != stack)
free (data); // <- data is not stack
}
```
It seems the `ProgramMemory` can't handle two known values(such as int and tok) together. So instead `ValueFlowAfterAssign` runs `ValueFlowForward` with tok values and then runs it with the other values.
I sometimes find myself wondering which test cases I have broken when I fiddle with some check (since I then can try running these specific tests in the debugger, or make a small change and see if the tests pass). This PR adds the testclass and the test case names to the file and line number. I took special care to cover the case where an assert would be placed directly in the ```run()```-function, i.e., not inside a test case (from what I could see, no such case exists). If there is no need to handle this case, the code can be simplified (there wouldn't be need for the ```teardownTest()```-function for example).
The exact format for how to print the test name is very much up for discussion.
This makes arrays non-null in valueflow, so it can catch comparisons against null that is always true:
```cpp
void f(void) {
int buf[42];
if( buf != 0) {;} // << always true
}
```
Add a check for function arguments that can be constant:
```cpp
extern void bar(int);
void f(int x) {
bar((x & 0x01) >> 7); // function 'bar' is always called with a '0'-argument
}
```