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.