From 638cc976749652b17a65059645a90ca7bfea83e8 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Thu, 24 Sep 2026 20:08:38 +0200 Subject: [PATCH 1/3] Fix #15060 Nullptr dereference in exprDependsOnThis() --- lib/astutils.cpp | 4 ++-- lib/tokenize.cpp | 13 ++++++++++--- test/testsymboldatabase.cpp | 4 +--- test/testtokenize.cpp | 10 ++++++++++ 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 4ebbc8644da..415db846d07 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -1159,8 +1159,8 @@ bool exprDependsOnThis(const Token* expr, bool onVar, nonneg int depth) } if (expr->isOperatorKeyword() && !Token::simpleMatch(expr->next()->astParent(), ".")) return true; - if (expr->variable() && expr->variable()->isArgument() && !expr->variable()->type() && expr->variable()->scope()->function && expr->variable()->scope()->function->templateDef) - return true; + // if (expr->variable() && expr->variable()->isArgument() && !expr->variable()->type() && expr->variable()->scope()->function && expr->variable()->scope()->function->templateDef) + // return true; } if (onVar && expr->variable()) { const Variable* var = expr->variable(); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index d67356ad086..0e11de0a121 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9166,9 +9166,16 @@ void Tokenizer::findGarbageCode() const syntaxError(tok); if (Token::Match(tok, "==|!=|<=|>= %comp%") && tok->strAt(-1) != "operator") syntaxError(tok, tok->str() + " " + tok->strAt(1)); - if (Token::simpleMatch(tok, "::") && (!Token::Match(tok->next(), "%name%|*|~") || - (tok->next()->isKeyword() && !Token::Match(tok->next(), "new|delete|operator")))) - syntaxError(tok); + if (Token::simpleMatch(tok, "::")) { + if (!Token::Match(tok->next(), "%name%|*|~") || (tok->next()->isKeyword() && !Token::Match(tok->next(), "new|delete|operator"))) + syntaxError(tok); + if (Token::simpleMatch(tok->tokAt(-1), ")") && !Token::simpleMatch(tok->linkAt(-1)->tokAt(-1), "decltype (")) { + if (tok->linkAt(-1)->tokAt(-1) && tok->linkAt(-1)->tokAt(-1)->isUpperCaseName()) + unknownMacroError(tok); + else + syntaxError(tok); + } + } if (Token::Match(tok, "& %comp%|&&|%oror%|&|%or%") && tok->strAt(1) != ">") syntaxError(tok); if (Token::Match(tok, "%comp%|&&|%oror%|&|%or% }") && tok->str() != ">") diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index cbd9eafb8d3..979304348f0 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -3773,9 +3773,7 @@ class TestSymbolDatabase : public TestFixture { } void symboldatabase35() { // ticket #4806 and #4841 - check("class FragmentQueue : public CL_NS(util)::PriorityQueue >\n" - "{};\n"); - ASSERT_EQUALS("", errout_str()); + ASSERT_THROW_INTERNAL(check("class FragmentQueue : public CL_NS(util)::PriorityQueue >\n"), UNKNOWN_MACRO); } void symboldatabase36() { // ticket #4892 diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index a25ea9c4bd6..e8f369f318a 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -7910,6 +7910,16 @@ class TestTokenizer : public TestFixture { " return std::string{ g() + \"abc\" MACRO \"def\" };\n" "}\n"), UNKNOWN_MACRO); + ASSERT_THROW_INTERNAL(tokenizeAndStringify("namespace N {\n" + " struct C {\n" + " void f();\n" + " };\n" + " void C(abc)::f() {\n" + " X x;\n" + " N::Y([&] { x(); })->g();\n" + " }\n" + "}\n"), UNKNOWN_MACRO); + ASSERT_THROW_INTERNAL_EQUALS(tokenizeAndStringify("static void handle_toggle(void (*proc) PROTO_XT_CALLBACK_ARGS, int var) {}\n"), // #13198 UNKNOWN_MACRO, "There is an unknown macro here somewhere. Configuration is required. If PROTO_XT_CALLBACK_ARGS is a macro then please configure it."); From b798e9cfe06e51f1e2645841389e76ba8e958862 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Thu, 24 Sep 2026 20:16:59 +0200 Subject: [PATCH 2/3] Undo --- lib/astutils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 415db846d07..4ebbc8644da 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -1159,8 +1159,8 @@ bool exprDependsOnThis(const Token* expr, bool onVar, nonneg int depth) } if (expr->isOperatorKeyword() && !Token::simpleMatch(expr->next()->astParent(), ".")) return true; - // if (expr->variable() && expr->variable()->isArgument() && !expr->variable()->type() && expr->variable()->scope()->function && expr->variable()->scope()->function->templateDef) - // return true; + if (expr->variable() && expr->variable()->isArgument() && !expr->variable()->type() && expr->variable()->scope()->function && expr->variable()->scope()->function->templateDef) + return true; } if (onVar && expr->variable()) { const Variable* var = expr->variable(); From 33db4eb09dd6dea647959e6e8559f0a3792f3c4e Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Thu, 24 Sep 2026 20:52:46 +0200 Subject: [PATCH 3/3] Fix --- lib/tokenize.cpp | 13 ++++++++----- test/testsymboldatabase.cpp | 3 ++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 0e11de0a121..5a0e8335705 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9169,11 +9169,14 @@ void Tokenizer::findGarbageCode() const if (Token::simpleMatch(tok, "::")) { if (!Token::Match(tok->next(), "%name%|*|~") || (tok->next()->isKeyword() && !Token::Match(tok->next(), "new|delete|operator"))) syntaxError(tok); - if (Token::simpleMatch(tok->tokAt(-1), ")") && !Token::simpleMatch(tok->linkAt(-1)->tokAt(-1), "decltype (")) { - if (tok->linkAt(-1)->tokAt(-1) && tok->linkAt(-1)->tokAt(-1)->isUpperCaseName()) - unknownMacroError(tok); - else - syntaxError(tok); + if (Token::simpleMatch(tok->tokAt(-1), ")")) { + const Token* const prev = tok->linkAt(-1)->tokAt(-1); + if (!Token::Match(prev, "%name% (") || (!prev->isControlFlowKeyword() && prev->str() != "decltype")) { + if (prev && prev->isUpperCaseName()) + unknownMacroError(prev); + else + syntaxError(tok); + } } } if (Token::Match(tok, "& %comp%|&&|%oror%|&|%or%") && tok->strAt(1) != ">") diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 979304348f0..68f51e2c83b 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -3773,7 +3773,8 @@ class TestSymbolDatabase : public TestFixture { } void symboldatabase35() { // ticket #4806 and #4841 - ASSERT_THROW_INTERNAL(check("class FragmentQueue : public CL_NS(util)::PriorityQueue >\n"), UNKNOWN_MACRO); + ASSERT_THROW_INTERNAL(check("class FragmentQueue : public CL_NS(util)::PriorityQueue >\n" + "{};\n"), UNKNOWN_MACRO); } void symboldatabase36() { // ticket #4892