AST: Fixed detection of operator new/delete - don't hang when C code is checked as C++ (#5910)
This commit is contained in:
parent
5fc3e37842
commit
e80104327a
|
@ -490,16 +490,18 @@ static void compileTerm(Token *&tok, AST_state& state)
|
||||||
if (tok->isLiteral()) {
|
if (tok->isLiteral()) {
|
||||||
state.op.push(tok);
|
state.op.push(tok);
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
} else if (tok->str() == "return") {
|
} else if (tok->isName() && tok->str() != "case") {
|
||||||
compileUnaryOp(tok, state, compileExpression);
|
if (tok->str() == "return") {
|
||||||
state.op.pop();
|
compileUnaryOp(tok, state, compileExpression);
|
||||||
} else if (tok->isName() && (!state.cpp || !Token::Match(tok, "new|delete")) && tok->str() != "case") {
|
state.op.pop();
|
||||||
while (tok->next() && tok->next()->isName())
|
} 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();
|
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() == "{") {
|
} else if (tok->str() == "{") {
|
||||||
state.op.push(tok);
|
state.op.push(tok);
|
||||||
tok = tok->link()->next();
|
tok = tok->link()->next();
|
||||||
|
@ -615,7 +617,7 @@ static void compilePrecedence3(Token *&tok, AST_state& state)
|
||||||
tok = tok->link()->next();
|
tok = tok->link()->next();
|
||||||
compilePrecedence3(tok, state);
|
compilePrecedence3(tok, state);
|
||||||
compileUnaryOp(tok2, state, nullptr);
|
compileUnaryOp(tok2, state, nullptr);
|
||||||
} else if (state.cpp && tok->str() == "new") {
|
} else if (state.cpp && Token::Match(tok, "new %var%|::|(")) {
|
||||||
Token* tok2 = tok;
|
Token* tok2 = tok;
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
state.op.push(tok);
|
state.op.push(tok);
|
||||||
|
@ -625,7 +627,7 @@ static void compilePrecedence3(Token *&tok, AST_state& state)
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
}
|
}
|
||||||
compileUnaryOp(tok2, state, nullptr);
|
compileUnaryOp(tok2, state, nullptr);
|
||||||
} else if (state.cpp && tok->str() == "delete") {
|
} else if (state.cpp && Token::Match(tok, "delete %var%|*|&|::|(|[")) {
|
||||||
Token* tok2 = tok;
|
Token* tok2 = tok;
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
if (tok->str() == "[")
|
if (tok->str() == "[")
|
||||||
|
|
|
@ -10557,6 +10557,8 @@ private:
|
||||||
ASSERT_EQUALS("FooBar(", testAst("void Foo(Bar&);"));
|
ASSERT_EQUALS("FooBar(", testAst("void Foo(Bar&);"));
|
||||||
ASSERT_EQUALS("FooBar(", testAst("void Foo(Bar& &);")); // Rvalue reference - simplified from && to & & by real tokenizer
|
ASSERT_EQUALS("FooBar(", testAst("void Foo(Bar& &);")); // Rvalue reference - simplified from && to & & by real tokenizer
|
||||||
ASSERT_EQUALS("DerivedDerived::(", testAst("Derived::~Derived() {}"));
|
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 {
|
void astnewdelete() const {
|
||||||
|
|
Loading…
Reference in New Issue