Fixed crash #5991: Don't crash when lambda is incomplete

Fixed crash #6004: Support struct initializations in AST
This commit is contained in:
PKEuS 2014-07-31 23:14:44 +02:00
parent 5de1e35350
commit 95afa51b24
3 changed files with 27 additions and 4 deletions

View File

@ -997,7 +997,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
} else // addressof
variables.use(tok->next()->varId(), tok); // use = read + write
} else if (Token::Match(tok, ">>|>>= %var%")) {
if (_tokenizer->isC() || (tok->previous()->variable() && tok->previous()->variable()->typeEndToken()->isStandardType() && tok->astOperand1()->str() != ">>"))
if (_tokenizer->isC() || (tok->previous()->variable() && tok->previous()->variable()->typeEndToken()->isStandardType() && tok->astOperand1() && tok->astOperand1()->str() != ">>"))
variables.read(tok->next()->varId(), tok);
else
variables.use(tok->next()->varId(), tok); // use = read + write

View File

@ -402,8 +402,9 @@ bool TokenList::createTokens(std::istream &code, const std::string& file0)
struct AST_state {
std::stack<Token*> op;
unsigned int depth;
unsigned int inArrayAssignment;
bool cpp;
AST_state(bool cpp_) : depth(0), cpp(cpp_) {}
AST_state(bool cpp_) : depth(0), inArrayAssignment(0), cpp(cpp_) {}
};
static bool iscast(const Token *tok)
@ -487,6 +488,9 @@ static void compileTerm(Token *&tok, AST_state& state)
return;
if (Token::Match(tok, "L %str%|%char%"))
tok = tok->next();
if (state.inArrayAssignment && tok->str() == "." && (tok->strAt(-1) == "," || tok->strAt(-1) == "{")) // Jump over . in C style struct initialization
tok = tok->next();
if (tok->isLiteral()) {
state.op.push(tok);
tok = tok->next();
@ -503,8 +507,18 @@ static void compileTerm(Token *&tok, AST_state& state)
tok = tok->next();
}
} else if (tok->str() == "{") {
state.op.push(tok);
tok = tok->link()->next();
if (!state.inArrayAssignment && tok->strAt(-1) != "=") {
state.op.push(tok);
tok = tok->link()->next();
} else {
if (tok->link() != tok->next()) {
state.inArrayAssignment++;
compileUnaryOp(tok, state, compileExpression);
state.inArrayAssignment--;
} else {
state.op.push(tok);
}
}
}
}
@ -560,6 +574,8 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
Token* squareBracket = tok;
Token* roundBracket = squareBracket->link()->next();
Token* curlyBracket = Token::findsimplematch(roundBracket->link()->next(), "{");
if (!curlyBracket)
break;
tok = curlyBracket->next();
compileExpression(tok, state);
state.op.push(roundBracket);

View File

@ -10708,6 +10708,11 @@ private:
// function pointer
TODO_ASSERT_EQUALS("todo", "va_argapvoid((,(*0=", testAst("*va_arg(ap, void(**) ()) = 0;"));
// struct initialization
ASSERT_EQUALS("name_bytes[bits~unusedBits>>unusedBits<<{=", testAst("const uint8_t name_bytes[] = { (~bits >> unusedBits) << unusedBits };"));
ASSERT_EQUALS("abuf0{={=", testAst("a = { .buf = { 0 } };"));
ASSERT_EQUALS("tset{=", testAst("struct cgroup_taskset tset = {};"));
}
void astbrackets() const { // []
@ -10813,6 +10818,8 @@ private:
testAst("N 1024 float a[N], b[N + 3], c[N]; void N; (void) i;\n"
"int #define for (i = avx_test i < c[i]; i++)\n"
"b[i + 3] = a[i] * {}"); // Don't hang (#5787)
testAst("START_SECTION([EXTRA](bool isValid(const String &filename)))"); // Don't crash (#5991)
}
bool isStartOfExecutableScope(int offset, const char code[]) {