Fix 10309 and 10034: internalAstError with init lists (#3303)
This commit is contained in:
parent
6e74fc64b9
commit
b13e44fce5
|
@ -26,6 +26,7 @@
|
||||||
#include "standards.h"
|
#include "standards.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
#include <simplecpp.h>
|
#include <simplecpp.h>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -1349,35 +1350,22 @@ static void createAstAtTokenInner(Token * const tok1, const Token *endToken, boo
|
||||||
{
|
{
|
||||||
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)) {
|
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();
|
||||||
for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : nullptr)
|
bool hasAst = false;
|
||||||
tok = createAstAtToken(tok, cpp);
|
for (const Token *inner = tok->next(); inner != endToken2; inner = inner->next()) {
|
||||||
|
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();
|
||||||
|
@ -1635,8 +1623,23 @@ void TokenList::createAst() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct OnException {
|
||||||
|
std::function<void()> f;
|
||||||
|
|
||||||
|
~OnException() {
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
if (std::uncaught_exception())
|
||||||
|
f();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void TokenList::validateAst() const
|
void TokenList::validateAst() const
|
||||||
{
|
{
|
||||||
|
OnException oe{[&] {
|
||||||
|
if (mSettings->debugnormal)
|
||||||
|
mTokensFrontBack.front->printOut();
|
||||||
|
}};
|
||||||
// Check for some known issues in AST to avoid crash/hang later on
|
// Check for some known issues in AST to avoid crash/hang later on
|
||||||
std::set < const Token* > safeAstTokens; // list of "safe" AST tokens without endless recursion
|
std::set < const Token* > safeAstTokens; // list of "safe" AST tokens without endless recursion
|
||||||
for (const Token *tok = mTokensFrontBack.front; tok; tok = tok->next()) {
|
for (const Token *tok = mTokensFrontBack.front; tok; tok = tok->next()) {
|
||||||
|
|
|
@ -6023,6 +6023,7 @@ private:
|
||||||
ASSERT_EQUALS("a1{ b2{", testAst("auto a{1}; auto b{2};"));
|
ASSERT_EQUALS("a1{ b2{", testAst("auto a{1}; auto b{2};"));
|
||||||
ASSERT_EQUALS("var1ab::23,{,4ab::56,{,{,{{", testAst("auto var{{1,a::b{2,3}}, {4,a::b{5,6}}};"));
|
ASSERT_EQUALS("var1ab::23,{,4ab::56,{,{,{{", testAst("auto var{{1,a::b{2,3}}, {4,a::b{5,6}}};"));
|
||||||
ASSERT_EQUALS("var{{,{,{{", testAst("auto var{ {{},{}}, {} };"));
|
ASSERT_EQUALS("var{{,{,{{", testAst("auto var{ {{},{}}, {} };"));
|
||||||
|
ASSERT_EQUALS("fX{,{( abcfalse==CD:?", testAst("f({X, {Y, abc == false ? C : D}});"));
|
||||||
|
|
||||||
// Initialization with decltype(expr) instead of a type
|
// Initialization with decltype(expr) instead of a type
|
||||||
ASSERT_EQUALS("decltypex((", testAst("decltype(x)();"));
|
ASSERT_EQUALS("decltypex((", testAst("decltype(x)();"));
|
||||||
|
@ -6571,6 +6572,16 @@ private:
|
||||||
" ;\n"
|
" ;\n"
|
||||||
"}\n"));
|
"}\n"));
|
||||||
|
|
||||||
|
// #10309
|
||||||
|
ASSERT_NO_THROW(tokenizeAndStringify(
|
||||||
|
"using a = void *;\n"
|
||||||
|
"void b() {\n"
|
||||||
|
" std::unique_ptr<a, void (*)(a *)>(new a(0), [](a *c) {\n"
|
||||||
|
" if (c)\n"
|
||||||
|
" ;\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