Fix issue 9858: Token::astOperand1() cyclic dependency on valid C++ code (#2784)
This commit is contained in:
parent
362ab44c40
commit
ac67049661
|
@ -1302,23 +1302,36 @@ static Token * createAstAtToken(Token *tok, bool cpp);
|
||||||
static void createAstAtTokenInner(Token * const tok1, const Token *endToken, bool cpp)
|
static void createAstAtTokenInner(Token * const tok1, const Token *endToken, bool cpp)
|
||||||
{
|
{
|
||||||
for (Token *tok = tok1; tok && tok != endToken; tok = tok ? tok->next() : nullptr) {
|
for (Token *tok = tok1; tok && tok != endToken; tok = tok ? tok->next() : nullptr) {
|
||||||
if (tok->str() == "{" && !iscpp11init(tok) && !tok->astOperand1()) {
|
if (tok->str() == "{" && !iscpp11init(tok)) {
|
||||||
|
if (Token::simpleMatch(tok->astOperand1(), ","))
|
||||||
|
continue;
|
||||||
|
if (Token::simpleMatch(tok->previous(), "( {"))
|
||||||
|
;
|
||||||
|
// struct assignment
|
||||||
|
else if (Token::simpleMatch(tok->previous(), ") {") && Token::simpleMatch(tok->linkAt(-1), "( struct"))
|
||||||
|
continue;
|
||||||
|
// Lambda function
|
||||||
|
else if (Token::simpleMatch(tok->astParent(), "(") &&
|
||||||
|
Token::simpleMatch(tok->astParent()->astParent(), "[") &&
|
||||||
|
tok->astParent()->astParent()->astOperand1() &&
|
||||||
|
tok == tok->astParent()->astParent()->astOperand1()->astOperand1())
|
||||||
|
;
|
||||||
|
else {
|
||||||
|
// function argument is initializer list?
|
||||||
|
const Token *parent = tok->astParent();
|
||||||
|
while (Token::simpleMatch(parent, ","))
|
||||||
|
parent = parent->astParent();
|
||||||
|
if (!parent || !Token::Match(parent->previous(), "%name% ("))
|
||||||
|
// not function argument..
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Token::simpleMatch(tok->previous(), "( { ."))
|
||||||
|
break;
|
||||||
|
|
||||||
const Token * const endToken2 = tok->link();
|
const Token * const endToken2 = tok->link();
|
||||||
bool hasAst = false;
|
for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : nullptr)
|
||||||
for (const Token *inner = tok->next(); inner != endToken2; inner = inner->next()) {
|
tok = createAstAtToken(tok, cpp);
|
||||||
if (inner->astOperand1()) {
|
|
||||||
hasAst = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (tok->isConstOp())
|
|
||||||
break;
|
|
||||||
if (inner->str() == "{")
|
|
||||||
inner = inner->link();
|
|
||||||
}
|
|
||||||
if (!hasAst) {
|
|
||||||
for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : nullptr)
|
|
||||||
tok = createAstAtToken(tok, cpp);
|
|
||||||
}
|
|
||||||
} else if (cpp && tok->str() == "[") {
|
} else if (cpp && tok->str() == "[") {
|
||||||
if (isLambdaCaptureList(tok)) {
|
if (isLambdaCaptureList(tok)) {
|
||||||
tok = tok->astOperand1();
|
tok = tok->astOperand1();
|
||||||
|
|
|
@ -8292,6 +8292,19 @@ private:
|
||||||
" }\n"
|
" }\n"
|
||||||
"};\n"));
|
"};\n"));
|
||||||
|
|
||||||
|
// #9858
|
||||||
|
ASSERT_NO_THROW(tokenizeAndStringify(
|
||||||
|
"struct a {\n"
|
||||||
|
" struct b {};\n"
|
||||||
|
"};\n"
|
||||||
|
"void c(a::b, a::b);\n"
|
||||||
|
"void g(a::b f) { c(f, {a::b{}}); }\n"
|
||||||
|
"template <class> void h() {\n"
|
||||||
|
" int e;\n"
|
||||||
|
" for (int d = 0; d < e; d++)\n"
|
||||||
|
" ;\n"
|
||||||
|
"}\n"));
|
||||||
|
|
||||||
ASSERT_NO_THROW(tokenizeAndStringify("a<b?0:1>()==3;"));
|
ASSERT_NO_THROW(tokenizeAndStringify("a<b?0:1>()==3;"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue