From e17ddfd964ac41227160cbd2cb02498dfa0cdc12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 9 Mar 2019 19:09:15 +0100 Subject: [PATCH] Changed AST for variable declarations with initializations --- lib/checkautovariables.cpp | 5 +++-- lib/tokenlist.cpp | 12 ++++++++++++ test/testtokenize.cpp | 9 ++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 286dcc3d9..cf8c60a3c 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -613,8 +613,9 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token continue; } // Assign reference to non-local variable - } else if (Token::Match(tok->astParent(), "&|&&") && Token::simpleMatch(tok->astParent()->astParent(), "=") && - tok->variable() && tok->variable()->declarationId() == tok->varId() && tok->variable()->isStatic() && + } else if (Token::Match(tok->previous(), "&|&& %var% =") && tok->astParent() == tok->next() && + tok->variable() && tok->variable()->nameToken() == tok && + tok->variable()->declarationId() == tok->varId() && tok->variable()->isStatic() && !tok->variable()->isArgument()) { ErrorPath errorPath; const Variable *var = getLifetimeVariable(tok, errorPath); diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index c257fc2ce..677559803 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1165,6 +1165,18 @@ static Token * createAstAtToken(Token *tok, bool cpp) if (Token::Match(tok, "%type% <") && !Token::Match(tok->linkAt(1), "> [({]")) return tok->linkAt(1); + if (Token::Match(tok, "%type% %name%|*|&|::") && tok->str() != "return") { + bool decl = false; + Token *typetok = tok; + while (Token::Match(typetok, "%type%|::|*|&")) { + if (typetok->isStandardType() || Token::Match(typetok, "struct|const|static")) + decl = true; + typetok = typetok->next(); + } + if (decl && Token::Match(typetok->previous(), "[*&] %var% =")) + tok = typetok; + } + if (Token::Match(tok, "return|case") || (cpp && tok->str() == "throw") || !tok->previous() || Token::Match(tok, "%name% %op%|(|[|.|::|<|?|;") || Token::Match(tok->previous(), "[;{}] %cop%|++|--|( !!{")) { if (cpp && (Token::Match(tok->tokAt(-2), "[;{}] new|delete %name%") || Token::Match(tok->tokAt(-3), "[;{}] :: new|delete %name%"))) tok = tok->previous(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index c0c0c7bbe..eb3179417 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -8214,6 +8214,12 @@ private: tokenList.createLinks(); tokenList.createLinks2(); + // set varid.. + for (Token *tok = tokenList.list.front(); tok; tok = tok->next()) { + if (tok->str() == "var") + tok->varId(1); + } + // Create AST.. tokenList.prepareTernaryOpForAST(); tokenList.list.createAst(); @@ -8289,7 +8295,6 @@ private: ASSERT_EQUALS("a\"\"=", testAst("a=\"\"")); ASSERT_EQUALS("a\'\'=", testAst("a=\'\'")); - ASSERT_EQUALS("a1[\"\"=", testAst("char a[1]=\"\";")); ASSERT_EQUALS("'X''a'>", testAst("('X' > 'a')")); ASSERT_EQUALS("'X''a'>", testAst("(L'X' > L'a')")); @@ -8342,7 +8347,9 @@ private: ASSERT_EQUALS("ifCA_FarReadfilenew(,sizeofobjtype(,(!(", testAst("if (!CA_FarRead(file, (void far *)new, sizeof(objtype)))")); // #5910 - don't hang if C code is parsed as C++ // Variable declaration + ASSERT_EQUALS("a1[\"\"=", testAst("char a[1]=\"\";")); ASSERT_EQUALS("charp*(3[char5[3[new=", testAst("char (*p)[3] = new char[5][3];")); + ASSERT_EQUALS("varp=", testAst("const int *var = p;")); } void astexpr2() { // limit for large expressions