From f77347d7b437e9d662460ba1c02c1e304f1af4e7 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Sun, 1 Dec 2019 07:53:03 -0600 Subject: [PATCH] Fix crash 9492: Crash in FwdAnalysis::checkRecursive() (condTok is nullptr) (#2411) * Fix crash 9492: Crash in FwdAnalysis::checkRecursive() (condTok is nullptr) * Formatting --- lib/tokenize.cpp | 4 ++-- lib/tokenlist.cpp | 9 +++++++++ test/teststl.cpp | 7 ++++--- test/testtokenize.cpp | 16 ++++++++++++++++ 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index eedc89d7f..2d866dd9c 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2473,7 +2473,7 @@ void Tokenizer::combineOperators() } else if (tok->str() == "->") { // If the preceding sequence is "( & %name% )", replace it by "%name%" Token *t = tok->tokAt(-4); - if (Token::Match(t, "( & %name% )")) { + if (Token::Match(t, "( & %name% )") && !Token::simpleMatch(t->previous(), ">")) { t->deleteThis(); t->deleteThis(); t->deleteNext(); @@ -9471,7 +9471,7 @@ void Tokenizer::findGarbageCode() const // Code must end with } ; ) NAME if (!Token::Match(list.back(), "%name%|;|}|)")) syntaxError(list.back()); - if (list.back()->str() == ")" && !Token::Match(list.back()->link()->previous(), "%name% (")) + if (list.back()->str() == ")" && !Token::Match(list.back()->link()->previous(), "%name%|> (")) syntaxError(list.back()); for (const Token *end = list.back(); end && end->isName(); end = end->previous()) { if (Token::Match(end, "void|char|short|int|long|float|double|const|volatile|static|inline|struct|class|enum|union|template|sizeof|case|break|continue|typedef")) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 0091bd6a4..7366cf245 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1461,6 +1461,15 @@ void TokenList::validateAst() const if (!tok->astOperand1() || !tok->astOperand2()) throw InternalError(tok, "Syntax Error: AST broken, binary operator '" + tok->str() + "' doesn't have two operands.", InternalError::AST); } + + // Check control blocks + if (Token::Match(tok->previous(), "if|while|for|switch (")) { + if (!tok->astOperand1() || !tok->astOperand2()) + throw InternalError(tok, + "Syntax Error: AST broken, '" + tok->previous()->str() + + "' doesn't have two operands.", + InternalError::AST); + } } } diff --git a/test/teststl.cpp b/test/teststl.cpp index 99e861144..69acecd14 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -2420,9 +2420,10 @@ private: ASSERT_EQUALS("", errout.str()); // #3714 - segmentation fault for syntax error - check("void f() {\n" - " if (()) { }\n" - "}"); + ASSERT_THROW(check("void f() {\n" + " if (()) { }\n" + "}"), + InternalError); // #3865 check("void f() {\n" diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 4f2c59287..4987a9d20 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -471,6 +471,7 @@ private: TEST_CASE(checkTemplates); TEST_CASE(checkNamespaces); TEST_CASE(checkLambdas); + TEST_CASE(checkIfCppCast); // #9052 TEST_CASE(noCrash1); @@ -946,6 +947,7 @@ private: ASSERT_EQUALS("; __published: ;", tokenizeAndStringify(";__published:;", false)); ASSERT_EQUALS("a . public : ;", tokenizeAndStringify("a.public:;", false)); ASSERT_EQUALS("void f ( x & = 2 ) ;", tokenizeAndStringify("void f(x &= 2);", false)); + ASSERT_EQUALS("const_cast < a * > ( & e )", tokenizeAndStringify("const_cast(&e)", false)); } void concatenateNegativeNumber() { @@ -8078,6 +8080,20 @@ private: " }\n" "};\n")) } + void checkIfCppCast() { + ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n" + " int b();\n" + "};\n" + "struct c {\n" + " bool d() const;\n" + " a e;\n" + "};\n" + "bool c::d() const {\n" + " int f = 0;\n" + " if (!const_cast(&e)->b()) {}\n" + " return f;\n" + "}\n")) + } void noCrash1() { ASSERT_NO_THROW(tokenizeAndStringify(