Skip to content

Commit 1f58071

Browse files
Fix #13105 checkLibraryFunction for smart pointer to container (#6805)
1 parent d05b68d commit 1f58071

File tree

5 files changed

+33
-19
lines changed

5 files changed

+33
-19
lines changed

lib/astutils.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -273,35 +273,36 @@ bool astIsContainerString(const Token* tok)
273273
return container->stdStringLike;
274274
}
275275

276-
static const Token* getContainerFunction(const Token* tok)
276+
static std::pair<const Token*, const Library::Container*> getContainerFunction(const Token* tok, const Settings* settings)
277277
{
278-
if (!tok || !tok->valueType() || !tok->valueType()->container)
279-
return nullptr;
278+
const Library::Container* cont{};
279+
if (!tok || !tok->valueType() || (!tok->valueType()->container && (!settings || !(cont = settings->library.detectContainerOrIterator(tok->valueType()->smartPointerTypeToken)))))
280+
return {};
280281
const Token* parent = tok->astParent();
281282
if (Token::Match(parent, ". %name% (") && astIsLHS(tok)) {
282-
return parent->next();
283+
return { parent->next(), cont ? cont : tok->valueType()->container };
283284
}
284-
return nullptr;
285+
return {};
285286
}
286287

287-
Library::Container::Action astContainerAction(const Token* tok, const Token** ftok)
288+
Library::Container::Action astContainerAction(const Token* tok, const Token** ftok, const Settings* settings)
288289
{
289-
const Token* ftok2 = getContainerFunction(tok);
290+
const auto ftokCont = getContainerFunction(tok, settings);
290291
if (ftok)
291-
*ftok = ftok2;
292-
if (!ftok2)
292+
*ftok = ftokCont.first;
293+
if (!ftokCont.first)
293294
return Library::Container::Action::NO_ACTION;
294-
return tok->valueType()->container->getAction(ftok2->str());
295+
return ftokCont.second->getAction(ftokCont.first->str());
295296
}
296297

297-
Library::Container::Yield astContainerYield(const Token* tok, const Token** ftok)
298+
Library::Container::Yield astContainerYield(const Token* tok, const Token** ftok, const Settings* settings)
298299
{
299-
const Token* ftok2 = getContainerFunction(tok);
300+
const auto ftokCont = getContainerFunction(tok, settings);
300301
if (ftok)
301-
*ftok = ftok2;
302-
if (!ftok2)
302+
*ftok = ftokCont.first;
303+
if (!ftokCont.first)
303304
return Library::Container::Yield::NO_YIELD;
304-
return tok->valueType()->container->getYield(ftok2->str());
305+
return ftokCont.second->getYield(ftokCont.first->str());
305306
}
306307

307308
Library::Container::Yield astFunctionYield(const Token* tok, const Settings& settings, const Token** ftok)

lib/astutils.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ bool astIsContainerView(const Token* tok);
171171
bool astIsContainerOwned(const Token* tok);
172172
bool astIsContainerString(const Token* tok);
173173

174-
Library::Container::Action astContainerAction(const Token* tok, const Token** ftok = nullptr);
175-
Library::Container::Yield astContainerYield(const Token* tok, const Token** ftok = nullptr);
174+
Library::Container::Action astContainerAction(const Token* tok, const Token** ftok = nullptr, const Settings* settings = nullptr);
175+
Library::Container::Yield astContainerYield(const Token* tok, const Token** ftok = nullptr, const Settings* settings = nullptr);
176176

177177
Library::Container::Yield astFunctionYield(const Token* tok, const Settings& settings, const Token** ftok = nullptr);
178178

lib/checkfunctions.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,9 +642,9 @@ void CheckFunctions::checkLibraryMatchFunctions()
642642

643643
if (Token::simpleMatch(tok->astParent(), ".")) {
644644
const Token* contTok = tok->astParent()->astOperand1();
645-
if (astContainerAction(contTok) != Library::Container::Action::NO_ACTION)
645+
if (astContainerAction(contTok, nullptr, mSettings) != Library::Container::Action::NO_ACTION)
646646
continue;
647-
if (astContainerYield(contTok) != Library::Container::Yield::NO_YIELD)
647+
if (astContainerYield(contTok, nullptr, mSettings) != Library::Container::Yield::NO_YIELD)
648648
continue;
649649
}
650650

lib/library.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,8 @@ const std::unordered_map<std::string, Library::Container>& Library::containers()
13101310

13111311
const Library::Container* Library::detectContainerInternal(const Token* const typeStart, DetectContainer detect, bool* isIterator, bool withoutStd) const
13121312
{
1313+
if (!typeStart)
1314+
return nullptr;
13131315
const Token* firstLinkedTok = nullptr;
13141316
for (const Token* tok = typeStart; tok && !tok->varId(); tok = tok->next()) {
13151317
if (!tok->link())

test/testfunctions.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2049,6 +2049,17 @@ class TestFunctions : public TestFixture {
20492049
" void resize(size_t n) { std::vector<T>::resize(n); }\n"
20502050
"};\n", true, &s);
20512051
ASSERT_EQUALS("", errout_str());
2052+
2053+
check("struct P {\n" // #13105
2054+
" bool g(int i) const;\n"
2055+
" std::shared_ptr<std::map<int, int>> m;\n"
2056+
"};\n"
2057+
"bool P::g(int i) const {\n"
2058+
" auto it = m->find(i);\n"
2059+
" const bool b = it != m->end();\n"
2060+
" return b;\n"
2061+
"}\n", true, &s);
2062+
TODO_ASSERT_EQUALS("", "[test.cpp:6]: (debug) auto token with no type.\n", errout_str());
20522063
}
20532064

20542065
void checkUseStandardLibrary1() {

0 commit comments

Comments
 (0)