parent
d565cde815
commit
db4f94fdfe
|
@ -266,16 +266,16 @@ void CheckAutoVariables::autoVariables()
|
|||
errorAutoVariableAssignment(tok->next(), false);
|
||||
}
|
||||
// Invalid pointer deallocation
|
||||
else if ((Token::Match(tok, "%name% ( %var% ) ;") && mSettings->library.getDeallocFuncInfo(tok)) ||
|
||||
(mTokenizer->isCPP() && Token::Match(tok, "delete [| ]| (| %var% !!["))) {
|
||||
tok = Token::findmatch(tok->next(), "%var%");
|
||||
if (isArrayVar(tok))
|
||||
else if ((Token::Match(tok, "%name% ( %var%|%str% ) ;") && mSettings->library.getDeallocFuncInfo(tok)) ||
|
||||
(mTokenizer->isCPP() && Token::Match(tok, "delete [| ]| (| %var%|%str% !!["))) {
|
||||
tok = Token::findmatch(tok->next(), "%var%|%str%");
|
||||
if (isArrayVar(tok) || tok->tokType() == Token::eString)
|
||||
errorInvalidDeallocation(tok, nullptr);
|
||||
else if (tok->variable() && tok->variable()->isPointer()) {
|
||||
for (const ValueFlow::Value &v : tok->values()) {
|
||||
if (!(v.isTokValue()))
|
||||
continue;
|
||||
if (isArrayVar(v.tokvalue)) {
|
||||
if (isArrayVar(v.tokvalue) || v.tokvalue->tokType() == Token::eString) {
|
||||
errorInvalidDeallocation(tok, &v);
|
||||
break;
|
||||
}
|
||||
|
@ -804,7 +804,11 @@ void CheckAutoVariables::errorInvalidDeallocation(const Token *tok, const ValueF
|
|||
const Variable *var = val ? val->tokvalue->variable() : (tok ? tok->variable() : nullptr);
|
||||
|
||||
std::string type = "auto-variable";
|
||||
if (var) {
|
||||
if (tok && tok->tokType() == Token::eString)
|
||||
type = "string literal";
|
||||
else if (val && val->tokvalue->tokType() == Token::eString)
|
||||
type = "pointer pointing to a string literal";
|
||||
else if (var) {
|
||||
if (var->isGlobal())
|
||||
type = "global variable";
|
||||
else if (var->isStatic())
|
||||
|
|
|
@ -79,6 +79,7 @@ private:
|
|||
TEST_CASE(testautovar_extern);
|
||||
TEST_CASE(testautovar_reassigned);
|
||||
TEST_CASE(testinvaliddealloc);
|
||||
TEST_CASE(testinvaliddealloc_string);
|
||||
TEST_CASE(testinvaliddealloc_C);
|
||||
TEST_CASE(testassign1); // Ticket #1819
|
||||
TEST_CASE(testassign2); // Ticket #2765
|
||||
|
@ -627,6 +628,11 @@ private:
|
|||
"[test.cpp:9]: (error) Deallocation of an auto-variable results in undefined behaviour.\n"
|
||||
"[test.cpp:11]: (error) Deallocation of an auto-variable results in undefined behaviour.\n", errout.str());
|
||||
|
||||
check("void func1(char * ptr) {\n"
|
||||
" free(ptr);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void func1() {\n"
|
||||
" char* tmp1[256];\n"
|
||||
" init(tmp1);\n"
|
||||
|
@ -758,6 +764,26 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void testinvaliddealloc_string() {
|
||||
// #7341
|
||||
check("void f() {\n"
|
||||
" char *ptr = \"a\";\n"
|
||||
" free(\"a\");\n"
|
||||
" delete \"a\";\n"
|
||||
" free(ptr);\n"
|
||||
" delete ptr;\n"
|
||||
" char * p = malloc(1000);\n"
|
||||
" p = \"abc\";\n"
|
||||
" free(p);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Deallocation of an string literal results in undefined behaviour.\n"
|
||||
"[test.cpp:4]: (error) Deallocation of an string literal results in undefined behaviour.\n"
|
||||
"[test.cpp:5]: (error) Deallocation of an pointer pointing to a string literal (\"a\") results in undefined behaviour.\n"
|
||||
"[test.cpp:6]: (error) Deallocation of an pointer pointing to a string literal (\"a\") results in undefined behaviour.\n"
|
||||
"[test.cpp:9]: (error) Deallocation of an pointer pointing to a string literal (\"abc\") results in undefined behaviour.\n",
|
||||
errout.str());
|
||||
}
|
||||
|
||||
void testinvaliddealloc_C() {
|
||||
// #5691
|
||||
check("void svn_repos_dir_delta2() {\n"
|
||||
|
|
Loading…
Reference in New Issue