Fixed crash #5991: Don't crash when lambda is incomplete
Fixed crash #6004: Support struct initializations in AST
This commit is contained in:
parent
5de1e35350
commit
95afa51b24
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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[]) {
|
||||
|
|
Loading…
Reference in New Issue