* 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.
* Check if member function modifies the variable
* Check for const pointer
* Add test for const condition
* Add more null checking
* Add todo assert for FN
* Allow syntax "typedef 'typename' unsigned 'typename' (functon_name)()" for some old libraries
https://trac.cppcheck.net/ticket/7792
* Unnecessary check of "tokOffset", match-function already checks if it is null
* add testcase ticket #7792: simplifyTypedef124
* Follow variables when comparing same expression
* Remove assert include
* Dont follow function arguments
* Improve the checking to check more cases
* Add more tests
* Check if the variable is used inside a loop
* Follow both variables
* Only skip loops when variable is modified in scope
* Fix FP when followed variable is modified
* Dont follow arrays
* Skip pointer indirection
* Make recursive
* Improve checking more variables
* Fix test with sizeof
* Skip following operators
* Fix test when using sizeof
* Dont check every step
* Use early returns
* Update test to use a loop instead of conditional
* Add static
* Check variables are global
* Check local variables in another scope
* Fix issue with const pointers
* Distinguish between pointer indirection and multiply
* Use simple match
* Prevent crash with uniform initialization
* Use unary op and ast to detect pointer indirection
* Expand error message when expression do not match exactly
* Add errorpath to issameexpression
* Revert "Clarify warning message for 'Same expression on both sides of operator'"
This reverts commit 0e491b41a8.
* Check if the tokens are the same
* Report the operator and not the expressions
* Fix issue 6856: add checks in isOppositeCond when using == and < or >
* Move tests to testcondition
* Fix some more tests
* Fix test messages
* Remove the float check
* Add tests for log10{,f,l} valid arguments
* Add log2{,f,l} to checkfunctions
* Add log1p{,f,l} to checkfunctions
* checkfunctions: Simplify check for log function limit out of range
The conditions for negative and non-negative int and float were
identical so the call to isNegative can be removed and the if-statements
be simplified.
* Set values in else branch even when the first branch modifies the value
* Move tests
* Add check for goto
* Remvoe todo
* Also check scope is noreturn
* Use isEscapeScope when variables are changed
* Fix issue 470: Condition is always true or false on logical operators
* Dont warn on literals
* Compute logical operators using valueflow
* Fix FP when using literals
* Always warn on subconditions that are always true
* Use percent matches first
* Add test for logical operators
* Check if parent is null
* Add tests for invalid ranges
* Refactor loadLibErrors
This reduces the amount of code slightly and will simplify adding
more tests.
* Handle empty valid field
Before this change, the sequence <valid></valid> in a config file would
result in a segmentation fault. Now an empty field results in the error
message:
cppcheck: Failed to load library configuration file 'mycfg.cfg'. Bad attribute value '""'
* Add support for valid for floating point arguments
Previously, it was not possible to add valid ranges to floating point
arguments since it only handled integers. This made ranges not work well
for floating point arguments since arguments were cast to integers
before the ranges were handled.
Fix this by using doubles instead of integers if the argument is a float.
Add some tests for this and make sure errors are printed with enough
precision (somewhat arbitrarily chosen).
Note that it is still only possible to add integer ranges (i.e. -1:1).
* Add support for floats in configuration valid range
Now that it is possible to handle decimal arguments, there is no reason
to not allow non-integer ranges. Take care to not allow broken
configurations.
* Move check to within if-clause
* Move asin{,f,l} and acos{,f,l} input checks to config file