From 46578c52caf5c71e83b26a4f4523bd24470784ef Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 26 Sep 2022 20:20:22 +0200 Subject: [PATCH 1/3] Fix internalAstError with new --- lib/tokenlist.cpp | 34 ++++++++++++++++++++++++++-------- test/testtokenize.cpp | 5 ++++- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 33f867d7d78..1fc81a60ba2 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -912,8 +912,20 @@ static bool isPrefixUnary(const Token* tok, bool cpp) static void compilePrecedence2(Token *&tok, AST_state& state) { - const bool isStartOfCpp11Init = state.cpp && tok && tok->str() == "{" && iscpp11init(tok); - if (!(isStartOfCpp11Init && Token::Match(tok->tokAt(-2), "new %type% {"))) + auto doCompileScope = [&](const Token* tok) -> bool { + const bool isStartOfCpp11Init = state.cpp && tok && tok->str() == "{" && iscpp11init(tok); + if (isStartOfCpp11Init) { + tok = tok->previous(); + while (Token::Match(tok->previous(), ":: %type%")) + tok = tok->tokAt(-2); + if (tok && !tok->isKeyword()) + tok = tok->previous(); + return !Token::Match(tok, "new ::| %type%"); + } + return true; + }; + + if (doCompileScope(tok)) compileScope(tok, state); while (tok) { if (tok->tokType() == Token::eIncDecOp && !isPrefixUnary(tok, state.cpp)) { @@ -1069,12 +1081,18 @@ static void compilePrecedence3(Token *&tok, AST_state& state) } Token* leftToken = tok; - while (Token::Match(tok->next(), ":: %name%")) { - Token* scopeToken = tok->next(); //The :: - scopeToken->astOperand1(leftToken); - scopeToken->astOperand2(scopeToken->next()); - leftToken = scopeToken; - tok = scopeToken->next(); + if (Token::simpleMatch(tok, "::")) { + tok->astOperand1(tok->next()); + tok = tok->next(); + } + else { + while (Token::Match(tok->next(), ":: %name%")) { + Token* scopeToken = tok->next(); //The :: + scopeToken->astOperand1(leftToken); + scopeToken->astOperand2(scopeToken->next()); + leftToken = scopeToken; + tok = scopeToken->next(); + } } state.op.push(tok); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index bc86eec3f33..fee6f894ddd 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -6071,10 +6071,13 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("Aa*A12,{new=", testAst("A* a = new A{ 1, 2 };")); ASSERT_EQUALS("Sv0[(new", testAst("new S(v[0]);")); // #10929 ASSERT_EQUALS("SS::x(px0>intx[{newint1[{new:?(:", testAst("S::S(int x) : p(x > 0 ? new int[x]{} : new int[1]{}) {}")); // #10793 + ASSERT_EQUALS("a0[T{new=", testAst("a[0] = new T{};")); + ASSERT_EQUALS("a0[T::{new=", testAst("a[0] = new ::T{};")); + ASSERT_EQUALS("a0[ST::{new=", testAst("a[0] = new S::T{};")); // placement new ASSERT_EQUALS("X12,3,(new ab,c,", testAst("new (a,b,c) X(1,2,3);")); - ASSERT_EQUALS("a::new=", testAst("a = new (b) ::X;")); + ASSERT_EQUALS("aX::new=", testAst("a = new (b) ::X;")); ASSERT_EQUALS("cCnew= abc:?", testAst("c = new(a ? b : c) C;")); // invalid code (libreoffice), don't hang From f981c1011db2326104a123e1e5c8c705eeb4bef3 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 26 Sep 2022 20:22:43 +0200 Subject: [PATCH 2/3] Format --- lib/tokenlist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 1fc81a60ba2..139e04d0990 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -924,7 +924,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state) } return true; }; - + if (doCompileScope(tok)) compileScope(tok, state); while (tok) { From ac7503d95228901a5e1a007e8abc003edbc51158 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Mon, 26 Sep 2022 21:24:17 +0200 Subject: [PATCH 3/3] nullptr check --- lib/tokenlist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 139e04d0990..e95f5219671 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -916,7 +916,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state) const bool isStartOfCpp11Init = state.cpp && tok && tok->str() == "{" && iscpp11init(tok); if (isStartOfCpp11Init) { tok = tok->previous(); - while (Token::Match(tok->previous(), ":: %type%")) + while (tok && Token::Match(tok->previous(), ":: %type%")) tok = tok->tokAt(-2); if (tok && !tok->isKeyword()) tok = tok->previous();