#6715 segmentation fault (invalid code) in TemplateSimplifier::hasComplicatedSyntaxErrorsInTemplates. Harden TemplateSimplifier::hasComplicatedSyntaxErrorsInTemplates()

This commit is contained in:
Alexander Mai 2015-05-28 21:38:20 +02:00
parent 8adff0a31b
commit 098391ee32
4 changed files with 20 additions and 8 deletions

View File

@ -118,14 +118,18 @@ void TemplateSimplifier::cleanupAfterSimplify(Token *tokens)
}
const Token* TemplateSimplifier::hasComplicatedSyntaxErrorsInTemplates(Token *tokens)
bool TemplateSimplifier::hasComplicatedSyntaxErrorsInTemplates(const Token *tokens, const Token *& errorToken)
{
errorToken=nullptr;
// check for more complicated syntax errors when using templates..
for (const Token *tok = tokens; tok; tok = tok->next()) {
// skip executing scopes (ticket #3183)..
if (Token::simpleMatch(tok, "( {"))
if (Token::simpleMatch(tok, "( {")) {
tok = tok->link();
if (!tok)
return true;
}
// skip executing scopes..
const Token *start = Tokenizer::startOfExecutableScope(tok);
if (start) {
@ -142,6 +146,8 @@ const Token* TemplateSimplifier::hasComplicatedSyntaxErrorsInTemplates(Token *to
}
}
if (!tok)
return true;
// not start of statement?
if (tok->previous() && !Token::Match(tok, "[;{}]"))
continue;

View File

@ -51,10 +51,11 @@ public:
static void cleanupAfterSimplify(Token *tokens);
/**
* @return 0 if there are no syntax errors or return token which identifies
* the location of syntax error.
* \param[in] tokens token list
* \param[out] errorToken which identifies the syntax error if any. Might be NULL anyway
* @return false if there are no syntax errors or true
*/
static const Token* hasComplicatedSyntaxErrorsInTemplates(Token *tokens);
static bool hasComplicatedSyntaxErrorsInTemplates(const Token *tokens, const Token *& errorToken);
/**
* is the token pointing at a template parameters block

View File

@ -1760,9 +1760,9 @@ bool Tokenizer::tokenizeCondition(const std::string &code)
void Tokenizer::findComplicatedSyntaxErrorsInTemplates()
{
const Token *tok = TemplateSimplifier::hasComplicatedSyntaxErrorsInTemplates(list.front());
if (tok)
syntaxError(tok);
const Token *errorTok = nullptr;
if (TemplateSimplifier::hasComplicatedSyntaxErrorsInTemplates(list.front(), errorTok))
syntaxError(errorTok);
}
bool Tokenizer::hasEnumsWithTypedef()

View File

@ -87,6 +87,7 @@ private:
TEST_CASE(garbageCode46); // #6705
TEST_CASE(garbageCode47); // #6706
TEST_CASE(garbageCode48); // #6712
TEST_CASE(garbageCode49); // #6715
TEST_CASE(garbageValueFlow);
TEST_CASE(garbageSymbolDatabase);
@ -500,6 +501,10 @@ private:
checkCode(" { d\n\" ) d ...\n\" } int main ( ) { ( ) catch ( A a ) { { } catch ( ) \"\" } }");
}
void garbageCode49() { // #6715
ASSERT_THROW(checkCode(" ( ( ) ) { } ( { ( __builtin_va_arg_pack ( ) ) ; } ) { ( int { ( ) ( ( ) ) } ( ) { } ( ) ) += ( ) }"), InternalError);
}
void garbageValueFlow() {
// #6089
const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"