Merge pull request #866 from simartin/ticket_7440
Ticket #7440: Function calls should not abort pointer alias analysis for local variables.
This commit is contained in:
commit
7ae0b2b336
|
@ -6413,6 +6413,7 @@ bool Tokenizer::simplifyKnownVariablesGetData(unsigned int varid, Token **_tok2,
|
||||||
bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsigned int varid, const std::string &structname, std::string &value, unsigned int valueVarId, bool valueIsPointer, const Token * const valueToken, int indentlevel) const
|
bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsigned int varid, const std::string &structname, std::string &value, unsigned int valueVarId, bool valueIsPointer, const Token * const valueToken, int indentlevel) const
|
||||||
{
|
{
|
||||||
const bool pointeralias(valueToken->isName() || Token::Match(valueToken, "& %name% ["));
|
const bool pointeralias(valueToken->isName() || Token::Match(valueToken, "& %name% ["));
|
||||||
|
const bool varIsGlobal = (indentlevel == 0);
|
||||||
const bool printDebug = _settings->debugwarnings;
|
const bool printDebug = _settings->debugwarnings;
|
||||||
|
|
||||||
if (_errorLogger && !list.getFiles().empty())
|
if (_errorLogger && !list.getFiles().empty())
|
||||||
|
@ -6491,12 +6492,9 @@ bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsign
|
||||||
if (pointeralias && Token::Match(tok3, "do|for|while"))
|
if (pointeralias && Token::Match(tok3, "do|for|while"))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Stop if unknown function call is seen
|
// Stop if unknown function call is seen and the variable is global: it might be
|
||||||
// If the variable is a global or a member variable it might be
|
|
||||||
// changed by the function call
|
// changed by the function call
|
||||||
// TODO: don't bail out if the variable is a local variable,
|
if (varIsGlobal && tok3->str() == ")" && tok3->link() &&
|
||||||
// then it can't be changed by the function call.
|
|
||||||
if (tok3->str() == ")" && tok3->link() &&
|
|
||||||
Token::Match(tok3->link()->tokAt(-2), "[;{}] %name% (") &&
|
Token::Match(tok3->link()->tokAt(-2), "[;{}] %name% (") &&
|
||||||
!Token::Match(tok3->link()->previous(), "if|for|while|switch|BOOST_FOREACH"))
|
!Token::Match(tok3->link()->previous(), "if|for|while|switch|BOOST_FOREACH"))
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -369,6 +369,7 @@ private:
|
||||||
TEST_CASE(trac3991);
|
TEST_CASE(trac3991);
|
||||||
TEST_CASE(crash);
|
TEST_CASE(crash);
|
||||||
TEST_CASE(trac7680);
|
TEST_CASE(trac7680);
|
||||||
|
TEST_CASE(trac7440);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getcode(const char code[], const char varname[], bool classfunc=false) {
|
std::string getcode(const char code[], const char varname[], bool classfunc=false) {
|
||||||
|
@ -4032,6 +4033,16 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void trac7440() {
|
||||||
|
check("int main(void) {\n"
|
||||||
|
" char* data = new char[100];\n"
|
||||||
|
" char** dataPtr = &data;\n"
|
||||||
|
" printf(\"test\");\n"
|
||||||
|
" delete [] *dataPtr;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestMemleakInFunction)
|
REGISTER_TEST(TestMemleakInFunction)
|
||||||
|
|
|
@ -193,6 +193,7 @@ private:
|
||||||
TEST_CASE(simplifyKnownVariablesClassMember); // #2815 - value of class member may be changed by function call
|
TEST_CASE(simplifyKnownVariablesClassMember); // #2815 - value of class member may be changed by function call
|
||||||
TEST_CASE(simplifyKnownVariablesFunctionCalls); // Function calls (don't assume pass by reference)
|
TEST_CASE(simplifyKnownVariablesFunctionCalls); // Function calls (don't assume pass by reference)
|
||||||
TEST_CASE(simplifyKnownVariablesReturn); // 3500 - return
|
TEST_CASE(simplifyKnownVariablesReturn); // 3500 - return
|
||||||
|
TEST_CASE(simplifyKnownVariablesPointerAliasFunctionCall); // #7440
|
||||||
TEST_CASE(simplifyExternC);
|
TEST_CASE(simplifyExternC);
|
||||||
TEST_CASE(simplifyKeyword); // #5842 - remove C99 static keyword between []
|
TEST_CASE(simplifyKeyword); // #5842 - remove C99 static keyword between []
|
||||||
|
|
||||||
|
@ -2879,6 +2880,22 @@ private:
|
||||||
ASSERT_EQUALS("int a ( ) { return 123 ; }", tokenizeAndStringify(code,true));
|
ASSERT_EQUALS("int a ( ) { return 123 ; }", tokenizeAndStringify(code,true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void simplifyKnownVariablesPointerAliasFunctionCall() { // #7440
|
||||||
|
const char code[] = "int main() {\n"
|
||||||
|
" char* data = new char[100];\n"
|
||||||
|
" char** dataPtr = &data;\n"
|
||||||
|
" printf(\"test\");\n"
|
||||||
|
" delete [] *dataPtr;\n"
|
||||||
|
"}";
|
||||||
|
const char exp[] = "int main ( ) {\n"
|
||||||
|
"char * data ; data = new char [ 100 ] ;\n"
|
||||||
|
"char * * dataPtr ; dataPtr = & data ;\n"
|
||||||
|
"printf ( \"test\" ) ;\n"
|
||||||
|
"delete [ ] data ;\n"
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS(exp, tokenizeAndStringify(code, /*simplify=*/true));
|
||||||
|
}
|
||||||
|
|
||||||
void simplifyKnownVariablesClassMember() {
|
void simplifyKnownVariablesClassMember() {
|
||||||
// Ticket #2815
|
// Ticket #2815
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue