* Add valueFlowForwardExpression function to forward values of an expression
* Use token for expression
* Fix name in bailout message
* Handle expressions
* Add more tests for more expressions
* Add more tests
* Solve the expression if possible
* Formatting
For c++14, shifting a variable with a value larger than or equal to the
number of bits in the variable is undefined. Left-shifting with a value
equal to the number of bits of the variable is implementation defined.
See also trac ticket #9306.
* use range loops
* removed redundant string initializations
* use nullptr
* use proper boolean false
* removed unnecessary continue from end of loop
* removed unnecessary c_str() usage
* use emplace_back()
* removed redundant void arguments
* Fix memleak FP with return with parenthesis
Fix FPs pointed out by daca@home on the following form:
void* f(void) {
void* x = malloc(1);
return(x);
}
Fix it by only skipping tokens if there is an actual match with a
variable. This allows to remove the special casing of "return;".
* Add testcase with cast
This fixes crashes found by daca where valueType() is NULL. Also,
somewhat related, it removes warnings when casting to a type that is
unknown to cppcheck, for example, there is no longer a warning for the
following code:
void* f() {
void *x = malloc(1);
return (mytype)x;
}
* Fix false negatives in checkAssignBoolToFloat
Detect assignments to expressions involving pointer dereferences, array
element accesses, etc.
* Pass assignment token to assignBoolToFloatError
Pass assignment token rather than boolean token to make error reporting
consistent between checkAssignBoolToFloat and checkAssignBoolToPointer,
as well as with other assignment checks in the code base.
* Make checkAssignBoolToPointer check consistent with checkAssignBoolToFloat
This was most likely introduced when the checks were changed to run on
the full tokenlist instead of the simplified one.
Take care to warn about cases where casts destroy the pointer, such as
uint8_t f() {
void* x = malloc(1);
return (uint8_t)x;
}
* Add impossible category
* Replace values
* Try to adjust known values
* Add ! for impossible values
* Add impossible with possible values
* Remove contradictions
* Add values when the branch is not dead
* Only copy possible values
* Dont bail on while loops
* Load std lib in valueflow
* Check for function calls
* Fix stl errors
* Fix incorrect impossible check
* Fix heap-after-use error
* Remove impossible values when they are lowered
* Show the bound and remove overlaps
* Infer conditions
* Dont push pointer values through dynamic_cast
* Add test for dynamic_cast issue
* Add shifttoomanybits test
* Add test for div by zero
* Add a test for issue 9315
* Dont make impossible value inconclusive
* Fix FP with shift operator
* Improve handleKnownValuesInLoop for impossible values
* Fix cppcheck warning
* Fix impossible values for ctu
* Bailout for streams
* Check equality conditions
* Fix overflows
* Add regression test for 9332
* Remove duplicate conditions
* Skip impossible values for invalid value
* Check for null
* Rename bound to range
* Formatting
Is not allowed to define a type in an alias template definition.
This code:
template<int N>
using A1 = struct B1 { static auto constexpr value = N; };
A1<0> a1;
produces this output:
2: } ;
3: struct B1 { static const auto value = 0 a1 ;
test.cpp:2:57: error: Analysis failed. If the code is valid then please
report this failure. [cppcheckError]
using A1 = struct B1 { static auto constexpr value = N; };
^
because it tries to instantiate the invalid alias template definition
and generates garbage code.
This will now warn when doing something like this:
```cpp
template <class T, class K, class V>
const V& get_default(const T& t, const K& k, const V& v) {
auto it = t.find(k);
if (it == t.end()) return v;
return it->second;
}
const int& bar(const std::unordered_map<int, int>& m, int k) {
auto x = 0;
return get_default(m, k, x);
}
```
The lifetime warning is considered inconclusive in this case.
I also updated valueflow to no tinject inconclusive values unless `--inconclusive` flag is passed. This creates some false negatives because library functions are not configured to not modify their input parameters, and there are some checks that do not check if the value is inconclusive or not.
* make ellipsis ... a single token
Using cppcheck -E to preprocess code with ellipsis produces output that
can't be compiled because ... is split into 3 tokens.
* try to fix addon
This fixes the issue by making `ProgramMemory` keep track of values based on the conditions.
It also removes the `deadpointer` check since it duplicates the `invalidLifetime` check.
* Fix issue 8897: Huge array initializations
iscpp11init would take a lot of time when parsing huge arrays.
This patch add memoization to keeps track that we are parsing an array,
and allows to propagate the result without re-parsing the array for each
of its members.
* Use enum class instead of enum
* Try harder to track ref lifetimes
* Dont add lifetimes for references
* Use correct token
* Check for front and back as well
* Improve handling of addresses
* Formatting
* Fix FP
* Add missing Qt macros
Add two Qt macros that were missing
* Fix issue with __declspec and final
This change is a bit naive but it fixes the issues I was having when combining __declspec(dllexport) and final classes. Without the fix I get errors along the line of "The code 'class x final :' is not handled. You can use -I or --include to add handling of this code. "
There seems to be no reason for stopping checking the scope if a call to
free() is seen (or fclose() or realloc()), so just continue checking.
Also, if there are multiple arguments, check all, perhaps there are more
memory leaks to warn about.
This fixes the FP in cases like this:
```cpp
void f() {
bool b;
bool * x = &b;
if (x != nullptr)
x = 1;
}
```
It tracks the indirection of the uninit value in valueflow.
Use the AST a little bit more to improve the check. In order to do so,
rewrite the check to work from the outer function first and then check
the arguments, instead of the other way around.
It also fixes Trac ticket #9252, no warning is now given for
void* malloc1() {
return(malloc1(1));
}
This FP seems to be common in daca results.
It also makes it possible to improve handling of casts, for example
cppcheck now warns about
void f() {
strcpy(a, (void*) strdup(p));
}
But not for
char* f() {
char* ret = (char*)strcpy(malloc(10), "abc");
return ret;
}
These FP/FN were introduced when the check was switched to use the
simplified token list.
* dmake: Refactor object files to separate function
No functional change.
* dmake: Use range for loops
No functional change.
* Add all external cpp files instead of open coding
No functional change.
* Remove duplicate check.h in lib.pri HEADERS
* Add missing newline
No functional change, but the readability of the generated Makefile is
slightly improved.
This fixes false positives from daca@home where freopen is used to
reopen a standard stream. There is no longer a warning for
void f() {
assert(freopen("/dev/null", "r", stdin));
}
* template simplifier: refactor TemplateSimplifier::TokenAndName into a class
assert when more than one family flag is set
* fix function parameter names
* Fix for too much information in scope name
When the scope calculation encounters code such as
"friend class X::Y;"
or
"template<> class X<void> {"
it will now reset the additional name component of the scope that is about to be opened.
* Made sure new scope name is reset after being used
* Removed redundant scope calculation
* Add scope propagation code to insertToken
* Add relevant scope code to Token class
* Add code to calculate the scope of Tokens
* Add calculateScopes method to class
* Add missing include for shared_ptr
Since the number of test files is larger than the number of lib files,
this only caused an extra harmless '\' being printed after the last
header file in lib.pri. If the number of test files would have been
smaller than the number of lib files, the generated lib.pri would have
been broken.
* 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;
}
```
* 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.
Sources were built with Clang but with increased verbosity of error detection.
A number of syntax and semantic warnings were encountered. Commit adds
changes to correct these warnings.
Some changes involve removing extra, and unncessary, semi-colons at EOL
(e.g. at end of switch clause).
Project astyle settings are not currently setup to detect if a file is to
have an extra carriage return after the last line of data. Two files were
altered to ensure an extra carriage return.
An advisory to enhance code was encountered in triage code. Clang advisory
on a for-loop interation value suggested that:
`use reference type 'const QString &' to prevent copying`
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.
Increasing the verbosity in Clang, warnings were produced that identified
differences in code and doxygen-formatted comments.
Corrections applied to silence warnings yet still convey intent of original comments.
* Added scopeinfo member to token class
Moved ScopeInfo2 declaration here as well because that's where it needs to be now.
* Added scopeinfo accessors and declaration to class
* Add new method for calculating scopes
This replaces the methods in the TemplateSimplifier which calculate the current scope as the token list is iterated. The old method required checking if the scope had changed for every token multiple times (for multiple iterations), which was surprisingly costly. Calculating scopes in advance like this decreases runtime on a worst-case file by around thirty percent.
ScopeInfo objects are disposed of when the TemplateSimplification is done as they are not used later.
* Add calculateScopes method to header
* Removed code that calculated current scope
This has been replaced by code that calculates the scopes up front and stores them with each token, which is much faster.
* Fixed compile errors from extra parentheses
* Added missing code to fix memory leak
* Added code to actually clean up ScopeInfo structs
* Tidy up a dodgy for loop
* Convert argument to const ref
* Calculate missing scopes
As the templatesimplificator expands templates and does multiple passes it needs to make sure all scopes are calculated.
* Remove copying the scope to the next token
This is now done properly when scopes are calculated.
* Remove call to calculateScopes
This is now done by the TemplateSimplifier.
* Recalculate scopes for every pass of simplifyTemplates
* Add code to calculate extra scopes as they are added
I thought that this might be useful for calculating scopes when Tokens are created, but as there are several ways of creating Tokens that don't guarantee that they are placed in a list it is easier to just calculate scopes when you know you have a list and when you know you're adding to a list.
* Fix several bugs and poorly designed code
Remove the global scopes collection, and clean them up instead by iterating through the tokenlist to find them. This means scopes can be calculated by functions in the Token class as well as in the Tokenizer class without leaking the scope object.
Fix a couple of bugs in the calculateScopes method and make it more efficient.
* Remove unnecessary calls to calculateScopes
* Move brace to correct position
Calculating scopes during insertToken only needs to happen if we created a new Token.
* Handle 'using namespace' declarations separately
This fixes a bug caused by a statement matching 'struct B < 0 > ;'
* Fix argument name mismatch
* Actually use newScopeInfo when inserting Token
* Switch to using shared_ptr to hold scopeInfos
This means ScopeInfo2 objects get properly cleaned up when they are no longer needed.
* Change ScopeInfo member to be a shared_ptr
* Update code to use shared_ptr
* Add missing include for shared_ptr
* Remove unnecessary cleanup code
This has been replaced by shared_ptr for ScopeInfo2 objects
* 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
* lib: isNonBoolStdType no longer needed
lib/checkbool.cpp:50:13: warning: unused function 'isNonBoolStdType'
[-Wunused-function]
static bool isNonBoolStdType(const Variable* var)
* cmake: C++11 is required
also change instructions to a more common syntax
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
* Add cmd parameter for choosing between C90 and C99
Misra specifies different requirements to the uniqueness of
macros/enums/variables depending on what C standard
that's being used.
* Add standards configuration to each dump file
Read standards config from misra addon to decide what rules to use.
* Posix as standard setting should be deprecated. Don't include this in the xml
* Rewritten to use a switch
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;".
This improves the performance of the templatesimplefier by caching the template name position. I am not sure if the works entirely correctly but all the tests do pass with this change. Running this with gtest headers without removing unused template headers the time went from 48s to 5s, almost a 10x improvement.
* 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
* build: remove -Wabi and add -Wundef
gcc >= 8 throws a warning about -Wabi (without a specific ABI version)
being ignored, while -Wundef seems more useful (as shown by the change
in config.h, which was probably an unfortunate typo)
travis.yaml should probably be updated soon, but was left out from this
change as the current images don't yet need it
* lib: unused function in valueflow
refactored out since 8c03be3212
lib/valueflow.cpp:3124:21: warning: unused function 'endTemplateArgument' [-Wunused-function]
* readme: include picojson
* make: also clean exe
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
Fix some crashes caused by the template simplifier generating bad code
for some instantiations.
Sorry but there are no tests because I was unable to get C-Reduce to
create examples that were not garbage code.
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.
temp.bufferSizeArg2 was not initialized when only bufferSizeArg1
was specified or the value was out of range. But in valueflow.cpp in
valueFlowDynamicBufferSize() it was used as if it is always initialized
and has a sane value (greater than 0).
* Add defines set by compiler options when using compilation database
sets __cplusplus and __STDC_VERSION__ based on -std and the defines for -municode, -fpie, -fPIE, -fpic and -fPIC
* Fixed merge
This limits the recursion depth as a last line of defense to avoid stack
overflows when there are really huge arrays.
See https://trac.cppcheck.net/ticket/8922
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)
- CLI: Save the libraries that should be loaded to a list and load them
after the std.cfg has been loaded.
- GUI: Load std.cfg (and windows.cfg / posix.cfg when applicable) before
setting other options and loading the other libraries.
In the project-file-dialog the std.cfg is searched first. If some
other library fails to load is is retried with first loading std.cfg.
- boost.cfg: Enable containers that depend on std containers.
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.
CheckUninitVar::isMemberVariableAssignment uses argument direction
to check for assignment when the member variable is handed over to a
function by reference. Currently implemented for "in" direction. "out"
will be added with another commit.
lib/settings.cpp:53:7: warning: field 'removeUnusedIncludedTemplates' will be
initialized after field 'removeUnusedTemplates' [-Wreorder]
removeUnusedIncludedTemplates(false),
^
lib/settings.cpp:54:7: warning: field 'removeUnusedTemplates' will be
initialized after field 'checkConfiguration' [-Wreorder]
removeUnusedTemplates(false),
^
* 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.
This enhances the library configuration so the direction of function
arguments can be specified (in, out, inout).
isVariableChangedByFunctionCall() uses this information now to avoid
guessing.
If no 'alternatives' argument was specified and the `<warn/>` element
did not contain any text Cppcheck crashed because of a null pointer
access.
If there is no 'reason' and no 'alternatives argument and also no text loadFunction() returns with an error.
* 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.
otherwise showing (with Apple LLVM version 10.0.0):
lib/settings.cpp:34:7: warning: field 'jointSuppressionReport' will be
initialized after field 'maxCtuDepth' [-Wreorder]
jointSuppressionReport(false),
* 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.
* 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
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.
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;
}
```
In case the XML code of a library configuration is invalid Cppcheck now additionally prints out some helpful error description like this:
"Error=XML_ERROR_MISMATCHED_ELEMENT ErrorID=16 (0x10) Line number=304: XMLElement name=noreturn"
* out of line member functions are a namespace
* template<...> and *_cast<> can't be instantiations
* refactor code to use less function parameters
* fix instantiation scopes
* use full name with namespace when available
* fallback to just matching names when full name doesn't match
* 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
due to equal arguments...
* iterators1 (`CheckStl::iteratorsError(const Token*, const std::string&, const std::string&)`) and
* iterators2 (`CheckStl::iteratorsError(const Token*, const Token*, const std::string&, const std::string&)`)
... produced equal messages. Equal messages were filtered-out `CppCheck::reportErr(const ErrorLogger::ErrorMessage&)`.
So the error iterators2 disapeared from the error list.
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?)
* use already cached name token rather than recalculating it
multiple times
* cache end of template parameters token and use it rather than
recalculating it multiple times
* remove unnecessary end of template token and name token checks
* remove function parameter that is already contained in another
parameter
* valueflow: remove unused variable known
since e4677ae640 will trigger :
lib/valueflow.cpp:506:20: warning: unused variable 'known' [-Wunused-variable]
const bool known = (parent->astOperand1()->hasKnownValue() ||
* templatesimplifier: cleanup
since 48c960f56c showing:
lib/templatesimplifier.h:279:16: warning: private field 'mTokenizer' is not used
[-Wunused-private-field]
Tokenizer *mTokenizer;
* split CheckNullPointer::arithmeticError() into
* CheckNullPointer::pointerArithmeticError() and
* CheckNullPointer::redundantConditionWarning()
* Additional errorlist entry:
```XML
<error id="nullPointerArithmeticRedundantCheck"
severity="warning"
msg="Either the condition is redundant or there is pointer arithmetic with NULL pointer."
verbose="Either the condition is redundant or there is pointer arithmetic with NULL pointer." cwe="682"/>
```
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.
* Code changes for Token::mImpl optimisation
* Added new TokenImpl optimisation
Moving members to the TokenImpl struct reduces the size of the Token class, which is a fairly significant optimisation. In my testing on Windows with 32-bit Release-PCRE, this change reduced the size of the Token class from 108 bits to 52 bits and reduced run-time of my test case by around 20%.
* Several optimisations
Deleted some code that ran very slowly and did nothing, as there is no need to change a Token's string to null if you are about to delete it.
Added a frontToken to simplifyCalculations to reduce the amount of work it has to do on already-simplified calculations.
Moved template removal to the end of the list as this reduces redundant iteration and saves time.
* Added tok argument to simplifyCalculations
This means callers can avoid unnecessary work if they know which tokens have already been simplified. Passing nullptr indicates the original behaviour (starting from the front of the list).
* Removed mention of member from another change
* Re-added and optimised some code deleted in error
Changing mTemplateInstantiations to a vector avoids the high cost of doing repeated linear searches. Changing how the code iterates through the array was necessary because the vector can be resized at several points during the loop, which breaks existing references and iterators.
* Changed mTemplateInstantiations to a vector
This is an optimisation that makes repeated linear searches of this collection significantly faster.
Also added a copy constructor to TokenAndName so code can make copies of these objects to keep a reference if a vector gets resized.
* A cleaner optimisation to removing template tokens
This reverts the previous change to made mInstantiatedTemplates a vector and the iterator changes to support this, and makes mTypesUsedInTemplateInstantiation so the eraseTokens logic can be unified.
* Reverted vector to list
Also made mTypesUsedInTemplateInstantiation a vector of TokenAndName objects so it can share the same logic as the other members.
* Added member for template simplifier pointer
This can be used more efficiently than marking Tokens with a flag and then searching through all templates to find the one that matches.
* Turned loop inside out
This means we only have to iterate through the std::list once. std::list is very expensive to iterate through.
* Latest code from danmar and fixed optimisations
In particular I have optimised simplifying template instantiation names as this was incredibly slow because of the number of times it had to iterate through the template instantiation list. Previous optimisations to this weren't very effective and broke some edge cases.
* Added changes from danmar
Made mExplicitInstantiationsToDelete a vector of TokenAndName to be consistent with the rest of the members, which are cleaned up very efficiently.
* Tokens can have many templateSimplifierPointers
* templateSimplifierPointers must be kept in sync
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
}
```
* Implement hexadecimal float conversion in MathLib::toDoubleNumber independent of C99/C++17
* Refactor MathLib::isFloatHex and cure some false results
So this unifies the `valueFlowAfterCondition` so it re-uses more code between checking for integers and container sizes. This should make valueFlowContainer more robust.
It also extends valueflow to support container comparisons such as `if (v.size() < 3)` or `if (v.size() > 3)` using the same mechanism that is used for integers.
* Modify template simplifier to add forward declarations of some template functions so symbol database can make sense of the expanded templates.
* Fix travis.
This fixes several FPs in the lifetime checker. It also fixes issue [8846](https://trac.cppcheck.net/ticket/8846):
```cpp
int * f(int a[])
{
return a;
}
```
* Use lifetime analysis for pointers as well
* Fix issue 1143: Pointer to local array
* Update message when using pointers
* Avoid infinite loop in tracing lifetimes
* Inital valueflow lifetime checker
* Forward values
* Add initial tests
* Fix deplicate messages
* Fix traversing nested lambdas
* Turn test case into a todo
* Skip if returning a container
* Fix FP when using references
* Add missing header
* Fix FP from broken scopes
* Fix FP with static variable
* Add test for more FPs
* Parse lambda functions
* Check for capture by value
* Add tests for using a container and lambda together
* Fix cppcheck errors
* Add test for nextAfterAstRightmostLeaf
* Add valueflow tests
* Update error message
* Check for correct lambda token
* Improve error path reporting
* Fix hang when parsing arrays that look almlost like lambdas
* Add valueflow for terminating conditions
* Add valueflow test
* Dont check for same expressions for now to avoid double diagnostics
* Check nesting
* Add more tests
* Ensure conditions happen in order
* Check for null
* Add error path
* Support same expression check as well
* Use early continue
* Skip checking the same token
* Avoid double condtion diagnosis
* Fix FP when in switch statements
* Fix FP when time function
* Skip conditional escapes
* Use simpleMatch
* Fix naming
* Fix typo
* Add check for return value of boolean function
The rule for converting an integer to a boolean is that 0 is mapped to
false and everything else is mapped to true. There is nothing wrong with
the following code (according to the standards):
bool f()
{
return -1;
}
and neither gcc nor clang will warn about it. However, it's a bit
confusing. This commit adds a check that warns when a value other than 0
or 1 is returned from a boolean function (similar to the existing check
that functions with boolean arguments are only passed 0 or 1). Since the
code is perfectly legal, set the severity to "Style".
* Use early continue and remove some braces
* Add testcase with multiple returns
* Avoid null pointer dereference in case of return without operand
* Skip lambdas
Add TODO-test cases that shows FPs when the return type of lambdas are
specified explicitly (this is a problem with findLambdaEndToken).
* Enable testcases
* findLambdaEndToken: Add tests
* Add handling of explicit return in findLambdaEndToken()
* Use AST in findLambdaEndToken()
* Fix ast when lambda is mutable
It is possible to define default template parameter values in forward
declarations and not define any in the actual declaration. Cppcheck
ignores forward declarations and only uses the default values in the
actual declaration so default values in forward declarations are copied
to the actual declaration when necessary.
* insecureCmdLineArgs: Fixed FN in case strdup() copies argv[].
* Formatted the code. There are no functional changes intended.
* Changes due to review comments from Daniel.
* Identify return conditions in multiconditions
* Improve error messages
* Check return statements are always true or false
* Add more tests for FPs
* Fix FP when returning const like variables
* Fix FP when returning pointers or classes
* Fix FP with member variable access
* Check non-local variables
* Use simplematch
* Check for null
* Improve STL interators checking
* Improve error messages for container iterators from different scopes
* Mini refactoring
* Replace hardcoded pattern to ValueType::Type::ITERATOR
* Error messages improvements, more tests and refactoring
* Refactoring after code review
* Put getting operand data into separate function
* Update getErrorMessages and iterator errors ids
* Refactoring
* Fix error
* Refactoring, early return implementation
* Delete redundant code
* Tiny changes in comments
* Fix specialized template regression.
Only check for instantiation of template being processed rather than
count of all instantiations.
* Add 2 more tests.
* insecureCmdLineArgs: Fixed false negatives in case arguments are const.
* Formatted the code, there are functional changes.
* Simplified matching as suggested by Daniel.
* #4241: Check for address of single character passed as string
Add a check that address of a single character is not passed as argument
to argument marked as strings (using strz). The check does not warn if
the address of a character with known value '\0'.
Since ValueFlow currently does not handle global constants (see #7597),
do not warn if the variable is global to avoid FPs when the address of
a global variable assigned to '\0' is passed to a function expecting a
string.
Remove comment in docs saying strz is unused.
* Change asdf to Hello world
* Add test of address to first element in string
* Add error reporting function to getErrorMessages
* Fix strings in test
* Fixed#8693 (Template specialization: Constructor detected as normal function (functionStatic error))
Refactor template simplifier to remove the existing full specialization
function expandSpecialized and allow full specializations to use the
existing function expandTemplate. The function expandTemplate was
modified to either expand the template like it originally did by copying
it or to modify the template in place. Both instantiated and
uninstantiated full specializations are modified in place. This also
fixes#8692 and probably other related tickets as well.
The function simplifyTemplates now tries twice to simplify templates so
more templates can be simplified. We should try as many times as
necessary to find all possible templates. We can't do that now because
uninstantiated templates are left unchanged. It is relatively straight
forward to have the new code also expand in place uninstantiated
templates with their symbolic types but namespaces are not handled
properly (ticket #8671) and it would introduce regressions.
* Fix travis warnings.
The while part of a do-while loop looks almost like a function call, so
extend the check for function calls to ignore while-statements.
Note that there was only an FP when checking c-code, since the check is
disabled for c++-code. Therefore, make sure the test cases are run on a
c-file.
isVariableDeclaration did not handle pointer to const pointer, or
pointer to volatile pointer. This resulted in FPs in examples like the
following:
class Fred {
public:
const char *const *data;
const char *const *getData() { return data; };
}
where cppcheck would say getData could be static, since it didn't
recognize const char *const *data as a variable declaration.
* PCRE: added pcre_study to improve regex matching speed.
* PCRE: catch return values from pcre_exec and return an error message in case it fails.
* Formatted the code. There are no functional changes intended.
* PCRE: decode internal PCRE error messages.
* Integrating comments from PR.
* PCRE: Use pcre_study() only in case PCRE_CONFIG_JIT is defined.
* PCRE: Fixed potential resource leak. In case prce_compile worked, but pcre_study() returns an error, the allocated resources by pcre_compile() can be freed.
* Make travis happy.
* PCRE: Improved output message format.
* PCRE: Attempt to be compliant to older PCRE versions and fix travis build.
* Fixed#8683 (Using deleted token with multiple template instantiations.)
* Fixed#8321 (heap use after free: templatesimplifier)
* Add a flag to Token indicating that it has a pointer to it.
* Run dmake
* Fix one source of list pointers to deleted tokens.
Refactor TemplateSimplifier class to get access to template lists.
Remove many function parameters now that they are class variables.
Fix one source of list pointers to deleted tokens.
Add tests with no output to catch crashes.
* Run dmake again.
* Make 2 more functions private.
* Make requested changes.
* Missed one change request.
* Use TokenList rather than Tokenizer.
* Move TokenAndName constructor to cpp file so token.h is not needed in header file.