From e18b7ba34109edd52936e10c4be80793ebb943f5 Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Thu, 21 Aug 2025 08:38:20 +0000 Subject: [PATCH 1/3] Fix #14085 Add isExplicit attribute to operators --- lib/symboldatabase.cpp | 2 ++ test/testsymboldatabase.cpp | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 6d723b60246..8b22db6ce84 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2555,6 +2555,8 @@ Function::Function(const Token *tok, if (::isOperator(tokenDef)) { isOperator(true); + isExplicit(tokenDef->strAt(-1) == "explicit" || tokenDef->strAt(-2) == "explicit"); + // 'operator =' is special if (tokenDef->str() == "operator=") type = FunctionType::eOperatorEqual; diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index ca23ecea050..9aaa7359abf 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -430,6 +430,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(symboldatabase109); // #13553 TEST_CASE(symboldatabase110); TEST_CASE(symboldatabase111); // [[fallthrough]] + TEST_CASE(symboldatabase112); // explicit operator TEST_CASE(createSymbolDatabaseFindAllScopes1); TEST_CASE(createSymbolDatabaseFindAllScopes2); @@ -5841,6 +5842,17 @@ class TestSymbolDatabase : public TestFixture { ASSERT(case3 && case3->isAttributeFallthrough()); } + void symboldatabase112() { // explicit operator + GET_SYMBOL_DB("class S {\n" + " explicit constexpr operator bool() const noexcept { return ptr_ != nullptr; }\n" + "private:\n" + " void *ptr_{nullptr};\n" + "};\n"); + const Token *f = db ? Token::findsimplematch(tokenizer.tokens(), "operatorbool") : nullptr; + ASSERT(f != nullptr); + ASSERT(f && f->function() && f->function()->isExplicit()); + } + void createSymbolDatabaseFindAllScopes1() { GET_SYMBOL_DB("void f() { union {int x; char *p;} a={0}; }"); ASSERT(db->scopeList.size() == 3); From 8ee9d3d45593ef10eee99b5945ae438f5995b58f Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Thu, 21 Aug 2025 09:47:21 +0000 Subject: [PATCH 2/3] Nit --- lib/symboldatabase.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 8b22db6ce84..0005c539f1a 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2555,8 +2555,6 @@ Function::Function(const Token *tok, if (::isOperator(tokenDef)) { isOperator(true); - isExplicit(tokenDef->strAt(-1) == "explicit" || tokenDef->strAt(-2) == "explicit"); - // 'operator =' is special if (tokenDef->str() == "operator=") type = FunctionType::eOperatorEqual; @@ -2580,8 +2578,6 @@ Function::Function(const Token *tok, // constructor of any kind else type = FunctionType::eConstructor; - - isExplicit(tokenDef->strAt(-1) == "explicit" || tokenDef->strAt(-2) == "explicit"); } const Token *tok1 = setFlags(tok, scope); @@ -2655,6 +2651,12 @@ Function::Function(const Token *tok, isInline(true); hasBody(true); } + + for (tok = tokenDef->previous(); Token::Match(tok, "&|&&|*|::|)|[|(|]|%name%"); tok = tok->previous()) { + // We should set other keywords here as well + if (tok->str() == "explicit") + isExplicit(true); + } } Function::Function(const Token *tokenDef, const std::string &clangType) From b0ac098007e4dda879fb55ac076dc8ed41c1c36a Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Thu, 21 Aug 2025 12:32:42 +0000 Subject: [PATCH 3/3] Nit 2 --- lib/symboldatabase.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 0005c539f1a..e05001b6896 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2652,10 +2652,12 @@ Function::Function(const Token *tok, hasBody(true); } - for (tok = tokenDef->previous(); Token::Match(tok, "&|&&|*|::|)|[|(|]|%name%"); tok = tok->previous()) { + for (tok = tokenDef->previous(); Token::Match(tok, "&|&&|*|::|)|]|%name%"); tok = tok->previous()) { // We should set other keywords here as well if (tok->str() == "explicit") isExplicit(true); + if (tok->str() == "]" || tok->str() == ")") + tok = tok->link(); } }