#7208 Cppcheck hangs with 100% CPU load in CheckOther::checkNegativeBitwiseShift (invalidcode). TokenList::validateAst() is running consistency checks on AST
This commit is contained in:
parent
e0e8c3fe60
commit
9a847d7b14
|
@ -1057,6 +1057,34 @@ void TokenList::createAst()
|
|||
for (Token *tok = _front; tok; tok = tok ? tok->next() : NULL) {
|
||||
tok = createAstAtToken(tok, isCPP());
|
||||
}
|
||||
|
||||
validateAst();
|
||||
}
|
||||
|
||||
void TokenList::validateAst()
|
||||
{
|
||||
// Verify that ast looks ok
|
||||
for (const Token *tok = _front; tok; tok = tok->next()) {
|
||||
// Syntax error if binary operator only has 1 operand
|
||||
if ((tok->isAssignmentOp() || tok->isComparisonOp() || Token::Match(tok,"[|^/%]")) && tok->astOperand1() && !tok->astOperand2())
|
||||
throw InternalError(tok, "Syntax Error: AST broken, binary operator has only one operand.", InternalError::SYNTAX);
|
||||
|
||||
// Syntax error if we encounter "?" with operand2 that is not ":"
|
||||
if (tok->astOperand2() && tok->str() == "?" && tok->astOperand2()->str() != ":")
|
||||
throw InternalError(tok, "Syntax Error: AST broken, ternary operator lacks ':'.", InternalError::SYNTAX);
|
||||
|
||||
// check for endless recursion
|
||||
const Token* parent=tok;
|
||||
while (parent = parent->astParent()) {
|
||||
if (parent==tok)
|
||||
throw InternalError(tok, "AST broken: endless recursion from '" + tok->str() + "'", InternalError::SYNTAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TokenList::cppcheckError(const Token *tok) const
|
||||
{
|
||||
throw InternalError(tok, "Analysis failed - inconsisten AST. If the code is valid then please report this failure.", InternalError::INTERNAL);
|
||||
}
|
||||
|
||||
const std::string& TokenList::file(const Token *tok) const
|
||||
|
|
|
@ -126,9 +126,24 @@ public:
|
|||
*/
|
||||
unsigned long long calculateChecksum() const;
|
||||
|
||||
/**
|
||||
* Create abstract syntax tree.
|
||||
*/
|
||||
void createAst();
|
||||
|
||||
/**
|
||||
* Create abstract syntax tree.
|
||||
*/
|
||||
void validateAst();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Send error message to error logger about internal bug.
|
||||
* @param tok the token that this bug concerns.
|
||||
*/
|
||||
void cppcheckError(const Token *tok) const;
|
||||
|
||||
/** Disable copy constructor, no implementation */
|
||||
TokenList(const TokenList &);
|
||||
|
||||
|
|
|
@ -210,6 +210,7 @@ private:
|
|||
TEST_CASE(garbageCode159); // #7119
|
||||
TEST_CASE(garbageCode160); // #7190
|
||||
TEST_CASE(garbageCode161); // #7200
|
||||
TEST_CASE(garbageCode162); // #7208
|
||||
TEST_CASE(garbageValueFlow);
|
||||
TEST_CASE(garbageSymbolDatabase);
|
||||
TEST_CASE(garbageAST);
|
||||
|
@ -1386,6 +1387,12 @@ private:
|
|||
//7200
|
||||
ASSERT_THROW(checkCode("{ }{ if () try { } catch (...)} B : : ~B { }"), InternalError);
|
||||
}
|
||||
|
||||
void garbageCode162() {
|
||||
//7208
|
||||
ASSERT_THROW(checkCode("return << >> x return << >> x ", "test.c"), InternalError);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestGarbage)
|
||||
|
|
Loading…
Reference in New Issue