From 6417be4a71dc34466d6712fed01427ccf158b183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 8 Jul 2017 22:12:01 +0200 Subject: [PATCH] Fixed #8054 (Tokenizer::simplifyKnownVariables(): Wrong simplification for global variables) --- lib/tokenize.cpp | 37 +++++++++++++++++++++++++++---------- test/testtokenize.cpp | 11 +++++++++++ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index fc3a793e0..d7b203a0c 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6242,7 +6242,8 @@ bool Tokenizer::simplifyKnownVariables() } } - // variable id for float/double variables + // variable id for local, float/double, array variables + std::set localvars; std::set floatvars; std::set arrays; @@ -6253,20 +6254,33 @@ bool Tokenizer::simplifyKnownVariables() if (!start) continue; + for (const Token *tok2 = start->previous(); tok2 && !Token::Match(tok2, "[;{}]"); tok2 = tok2->previous()) { + if (tok2->varId() != 0) + localvars.insert(tok2->varId()); + } + tok = start; // parse the block of code.. int indentlevel = 0; Token *tok2 = tok; for (; tok2; tok2 = tok2->next()) { - if (Token::Match(tok2, "[;{}] float|double %name% ;")) { - floatvars.insert(tok2->tokAt(2)->varId()); - } - - if (Token::Match(tok2, "[;{}] %type% *| %name% [")) { - const Token *nameToken = tok2->tokAt(2); - if (nameToken->str() == "*") - nameToken = nameToken->next(); - arrays.insert(nameToken->varId()); + if (Token::Match(tok2, "[;{}] %type% %name%|*")) { + bool isfloat = false; + bool ispointer = false; + const Token *vartok = tok2->next(); + while (Token::Match(vartok, "%name%|* %name%|*")) { + if (Token::Match(vartok, "float|double")) + isfloat = true; + if (vartok->str() == "*") + ispointer = true; + vartok = vartok->next(); + } + if (Token::Match(vartok, "%var% ;|[")) + localvars.insert(vartok->varId()); + if (isfloat && !ispointer && Token::Match(vartok, "%var% ;")) + floatvars.insert(vartok->varId()); + if (Token::Match(vartok, "%var% [")) + arrays.insert(vartok->varId()); } if (tok2->str() == "{") @@ -6290,6 +6304,9 @@ bool Tokenizer::simplifyKnownVariables() if (varid == 0) continue; + if (Token::Match(tok2->previous(), "[;{}]") && localvars.find(varid) == localvars.end()) + continue; + // initialization of static variable => the value is not *known* { bool isstatic = false; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 61863b594..061264775 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -203,6 +203,7 @@ private: TEST_CASE(simplifyKnownVariablesFloat); // #2454 - float variable 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(simplifyKnownVariablesGlobalVars); TEST_CASE(simplifyKnownVariablesReturn); // 3500 - return TEST_CASE(simplifyKnownVariablesPointerAliasFunctionCall); // #7440 TEST_CASE(simplifyExternC); @@ -2949,6 +2950,16 @@ private: } } + void simplifyKnownVariablesGlobalVars() { + // #8054 + const char code[] = "static int x;" + "void f() {" + " x = 123;" + " while (!x) { dostuff(); }" + "}"; + ASSERT_EQUALS("static int x ; void f ( ) { x = 123 ; while ( ! x ) { dostuff ( ) ; } }", tokenizeAndStringify(code,true)); + } + void simplifyKnownVariablesReturn() { const char code[] = "int a() {" " int x = 123;"