From a05990f13a54314b9666ec1cf51101d1a3e7609e Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sun, 8 Nov 2026 19:01:12 +0100 Subject: [PATCH 1/2] Fix #15183 Syntax error with -!! --- lib/tokenize.cpp | 2 +- test/testtokenize.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 436a6655284..06a8edf6e78 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3778,7 +3778,7 @@ void Tokenizer::concatenateNegativeNumberAndAnyPositive() if (tok->findOpeningBracket()) continue; - if (!tok->tokAt(2) || (tok->tokAt(2)->isOp() && !Token::Match(tok->tokAt(2), "[+-*]"))) + if (!tok->tokAt(2) || (tok->tokAt(2)->isOp() && !Token::Match(tok->tokAt(2), "[+-*!~]"))) syntaxError(tok); while ((tok->isArithmeticalOp() || tok->isComparisonOp()) && tok->str() != ">" && tok->next() && tok->strAt(1) == "+" && diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index d5c770169e4..63bf525dea6 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -8195,6 +8195,17 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS(";", tokenizeAndStringify("typedef std::size_t size_t;\n")); // #14809 ASSERT_EQUALS("struct S { int i { 0 } ; } ;", tokenizeAndStringify("struct S { int i : 1{0}; };\n")); // #15070 + + ASSERT_EQUALS( // #15183 + "int f ( int i ) {\n" + "if ( i > 0 ) {\n" + "return - ! ! i ; }\n" + "return - ~ i ;\n" + "}", tokenizeAndStringify("int f(int i) {\n" + " if (i > 0)\n" + " return -!!i;\n" + " return -~i;\n" + "}\n")); } From f623f9a901048b77c844644b60131725cd28d5f9 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Mon, 9 Nov 2026 19:30:00 +0100 Subject: [PATCH 2/2] Fix --- lib/tokenize.cpp | 2 +- test/testtokenize.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 06a8edf6e78..b855756da6a 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3778,7 +3778,7 @@ void Tokenizer::concatenateNegativeNumberAndAnyPositive() if (tok->findOpeningBracket()) continue; - if (!tok->tokAt(2) || (tok->tokAt(2)->isOp() && !Token::Match(tok->tokAt(2), "[+-*!~]"))) + if (!tok->tokAt(2) || (tok->tokAt(2)->isOp() && !Token::Match(tok->tokAt(2), "+|-|*|!|~|&|--|++"))) syntaxError(tok); while ((tok->isArithmeticalOp() || tok->isComparisonOp()) && tok->str() != ">" && tok->next() && tok->strAt(1) == "+" && diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 63bf525dea6..f5a6111a31d 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -8201,10 +8201,20 @@ class TestTokenizer : public TestFixture { "if ( i > 0 ) {\n" "return - ! ! i ; }\n" "return - ~ i ;\n" + "}\n" + "int * g ( int & i ) {\n" + "if ( - -- i ) { }\n" + "if ( - ++ i ) { }\n" + "return + & i ;\n" "}", tokenizeAndStringify("int f(int i) {\n" " if (i > 0)\n" " return -!!i;\n" " return -~i;\n" + "}\n" + "int* g(int& i) {\n" + " if (- --i) {}\n" + " if (- ++i) {}\n" + " return +&i;\n" "}\n")); }