#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) {
|
for (Token *tok = _front; tok; tok = tok ? tok->next() : NULL) {
|
||||||
tok = createAstAtToken(tok, isCPP());
|
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
|
const std::string& TokenList::file(const Token *tok) const
|
||||||
|
|
|
@ -126,9 +126,24 @@ public:
|
||||||
*/
|
*/
|
||||||
unsigned long long calculateChecksum() const;
|
unsigned long long calculateChecksum() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create abstract syntax tree.
|
||||||
|
*/
|
||||||
void createAst();
|
void createAst();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create abstract syntax tree.
|
||||||
|
*/
|
||||||
|
void validateAst();
|
||||||
|
|
||||||
private:
|
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 */
|
/** Disable copy constructor, no implementation */
|
||||||
TokenList(const TokenList &);
|
TokenList(const TokenList &);
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,7 @@ private:
|
||||||
TEST_CASE(garbageCode159); // #7119
|
TEST_CASE(garbageCode159); // #7119
|
||||||
TEST_CASE(garbageCode160); // #7190
|
TEST_CASE(garbageCode160); // #7190
|
||||||
TEST_CASE(garbageCode161); // #7200
|
TEST_CASE(garbageCode161); // #7200
|
||||||
|
TEST_CASE(garbageCode162); // #7208
|
||||||
TEST_CASE(garbageValueFlow);
|
TEST_CASE(garbageValueFlow);
|
||||||
TEST_CASE(garbageSymbolDatabase);
|
TEST_CASE(garbageSymbolDatabase);
|
||||||
TEST_CASE(garbageAST);
|
TEST_CASE(garbageAST);
|
||||||
|
@ -1386,6 +1387,12 @@ private:
|
||||||
//7200
|
//7200
|
||||||
ASSERT_THROW(checkCode("{ }{ if () try { } catch (...)} B : : ~B { }"), InternalError);
|
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)
|
REGISTER_TEST(TestGarbage)
|
||||||
|
|
Loading…
Reference in New Issue