* Fix #11078 FN constructing string from nullptr / #11079 FN unread variables * Format
This commit is contained in:
parent
54ec666739
commit
112b1573c5
|
@ -215,9 +215,9 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Set
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// std::string dereferences nullpointers
|
// std::string dereferences nullpointers
|
||||||
if (Token::Match(parent->tokAt(-3), "std :: string|wstring (") && tok->strAt(1) == ")")
|
if (Token::Match(parent->tokAt(-3), "std :: string|wstring (|{ %name% )|}"))
|
||||||
return true;
|
return true;
|
||||||
if (Token::Match(parent->previous(), "%name% (") && tok->strAt(1) == ")") {
|
if (Token::Match(parent->previous(), "%name% (|{ %name% )|}")) {
|
||||||
const Variable* var = tok->tokAt(-2)->variable();
|
const Variable* var = tok->tokAt(-2)->variable();
|
||||||
if (var && !var->isPointer() && !var->isArray() && var->isStlStringType())
|
if (var && !var->isPointer() && !var->isArray() && var->isStlStringType())
|
||||||
return true;
|
return true;
|
||||||
|
@ -350,8 +350,8 @@ void CheckNullPointer::nullConstantDereference()
|
||||||
else if (Token::Match(tok, "0 [") && (tok->previous()->str() != "&" || !Token::Match(tok->next()->link()->next(), "[.(]")))
|
else if (Token::Match(tok, "0 [") && (tok->previous()->str() != "&" || !Token::Match(tok->next()->link()->next(), "[.(]")))
|
||||||
nullPointerError(tok);
|
nullPointerError(tok);
|
||||||
|
|
||||||
else if (Token::Match(tok->previous(), "!!. %name% (") && (tok->previous()->str() != "::" || tok->strAt(-2) == "std")) {
|
else if (Token::Match(tok->previous(), "!!. %name% (|{") && (tok->previous()->str() != "::" || tok->strAt(-2) == "std")) {
|
||||||
if (Token::Match(tok->tokAt(2), "0|NULL|nullptr )") && tok->varId()) { // constructor call
|
if (Token::Match(tok->tokAt(2), "0|NULL|nullptr )|}") && tok->varId()) { // constructor call
|
||||||
const Variable *var = tok->variable();
|
const Variable *var = tok->variable();
|
||||||
if (var && !var->isPointer() && !var->isArray() && var->isStlStringType())
|
if (var && !var->isPointer() && !var->isArray() && var->isStlStringType())
|
||||||
nullPointerError(tok);
|
nullPointerError(tok);
|
||||||
|
|
|
@ -1198,6 +1198,8 @@ void CheckUnusedVar::checkFunctionVariableUsage()
|
||||||
if (tok->str() == "=" && isRaiiClass(tok->valueType(), mTokenizer->isCPP(), false))
|
if (tok->str() == "=" && isRaiiClass(tok->valueType(), mTokenizer->isCPP(), false))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
const bool isPointer = tok->valueType() && tok->valueType()->pointer;
|
||||||
|
|
||||||
if (tok->isName()) {
|
if (tok->isName()) {
|
||||||
if (isRaiiClass(tok->valueType(), mTokenizer->isCPP(), false))
|
if (isRaiiClass(tok->valueType(), mTokenizer->isCPP(), false))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1213,7 +1215,7 @@ void CheckUnusedVar::checkFunctionVariableUsage()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Do not warn about assignment with NULL
|
// Do not warn about assignment with NULL
|
||||||
if (isNullOperand(tok->astOperand2()))
|
if (isPointer && isNullOperand(tok->astOperand2()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!tok->astOperand1())
|
if (!tok->astOperand1())
|
||||||
|
|
|
@ -3588,6 +3588,15 @@ private:
|
||||||
" return s;\n"
|
" return s;\n"
|
||||||
"}\n", /*inconclusive*/ true);
|
"}\n", /*inconclusive*/ true);
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("void f() {\n" // #11078
|
||||||
|
" const char* p = nullptr;\n"
|
||||||
|
" std::string s1{ p };\n"
|
||||||
|
" std::string s2{ nullptr };\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference: p\n"
|
||||||
|
"[test.cpp:4]: (error) Null pointer dereference\n",
|
||||||
|
errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void nullpointerStdStream() {
|
void nullpointerStdStream() {
|
||||||
|
|
|
@ -5961,6 +5961,29 @@ private:
|
||||||
" p = (Foo *)NULL;\n"
|
" p = (Foo *)NULL;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
functionVariableUsage("void f() {\n" // #11079
|
||||||
|
" std::string s1{ nullptr };\n"
|
||||||
|
" std::string s2{ NULL };\n"
|
||||||
|
" std::string s4(nullptr);\n"
|
||||||
|
" std::string s5(NULL);\n"
|
||||||
|
"}\n"
|
||||||
|
"struct A { A(void*) {} };\n"
|
||||||
|
"static void g() {\n"
|
||||||
|
" A a1{ nullptr };\n"
|
||||||
|
" A a2{ NULL };\n"
|
||||||
|
" A a4(nullptr);\n"
|
||||||
|
" A a5(NULL);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 's1' is assigned a value that is never used.\n"
|
||||||
|
"[test.cpp:3]: (style) Variable 's2' is assigned a value that is never used.\n"
|
||||||
|
"[test.cpp:4]: (style) Variable 's4' is assigned a value that is never used.\n"
|
||||||
|
"[test.cpp:5]: (style) Variable 's5' is assigned a value that is never used.\n"
|
||||||
|
"[test.cpp:9]: (style) Variable 'a1' is assigned a value that is never used.\n"
|
||||||
|
"[test.cpp:10]: (style) Variable 'a2' is assigned a value that is never used.\n"
|
||||||
|
"[test.cpp:11]: (style) Variable 'a4' is assigned a value that is never used.\n"
|
||||||
|
"[test.cpp:12]: (style) Variable 'a5' is assigned a value that is never used.\n",
|
||||||
|
errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvarUnusedGoto() {
|
void localvarUnusedGoto() {
|
||||||
|
|
Loading…
Reference in New Issue