From e80104327af92eaff7d50c9ab6216bab6a1ff60a Mon Sep 17 00:00:00 2001 From: PKEuS Date: Thu, 26 Jun 2014 09:03:02 +0200 Subject: [PATCH] AST: Fixed detection of operator new/delete - don't hang when C code is checked as C++ (#5910) --- lib/tokenlist.cpp | 24 +++++++++++++----------- test/testtokenize.cpp | 2 ++ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 896d18bdc..32e52bf9f 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -490,16 +490,18 @@ static void compileTerm(Token *&tok, AST_state& state) if (tok->isLiteral()) { state.op.push(tok); tok = tok->next(); - } else if (tok->str() == "return") { - compileUnaryOp(tok, state, compileExpression); - state.op.pop(); - } else if (tok->isName() && (!state.cpp || !Token::Match(tok, "new|delete")) && tok->str() != "case") { - while (tok->next() && tok->next()->isName()) + } else if (tok->isName() && tok->str() != "case") { + if (tok->str() == "return") { + compileUnaryOp(tok, state, compileExpression); + state.op.pop(); + } else if (!state.cpp || !Token::Match(tok, "new|delete %var%|*|&|::|(|[")) { + while (tok->next() && tok->next()->isName()) + tok = tok->next(); + state.op.push(tok); + if (tok->next() && tok->linkAt(1) && Token::Match(tok, "%var% <")) + tok = tok->linkAt(1); tok = tok->next(); - state.op.push(tok); - if (tok->next() && tok->linkAt(1) && Token::Match(tok, "%var% <")) - tok = tok->linkAt(1); - tok = tok->next(); + } } else if (tok->str() == "{") { state.op.push(tok); tok = tok->link()->next(); @@ -615,7 +617,7 @@ static void compilePrecedence3(Token *&tok, AST_state& state) tok = tok->link()->next(); compilePrecedence3(tok, state); compileUnaryOp(tok2, state, nullptr); - } else if (state.cpp && tok->str() == "new") { + } else if (state.cpp && Token::Match(tok, "new %var%|::|(")) { Token* tok2 = tok; tok = tok->next(); state.op.push(tok); @@ -625,7 +627,7 @@ static void compilePrecedence3(Token *&tok, AST_state& state) tok = tok->next(); } compileUnaryOp(tok2, state, nullptr); - } else if (state.cpp && tok->str() == "delete") { + } else if (state.cpp && Token::Match(tok, "delete %var%|*|&|::|(|[")) { Token* tok2 = tok; tok = tok->next(); if (tok->str() == "[") diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 7c3eae02c..2fc48a195 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -10557,6 +10557,8 @@ private: ASSERT_EQUALS("FooBar(", testAst("void Foo(Bar&);")); ASSERT_EQUALS("FooBar(", testAst("void Foo(Bar& &);")); // Rvalue reference - simplified from && to & & by real tokenizer ASSERT_EQUALS("DerivedDerived::(", testAst("Derived::~Derived() {}")); + + 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++ } void astnewdelete() const {