Skip to content

Commit b70fe4c

Browse files
committed
Fixed danmar#6711 (Add namespace support to library files)
1 parent 9627fcc commit b70fe4c

3 files changed

Lines changed: 57 additions & 5 deletions

File tree

cfg/std.cfg

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4520,6 +4520,19 @@
45204520
<strz/>
45214521
</arg>
45224522
</function>
4523+
<function name="std::strcpy">
4524+
<noreturn>false</noreturn>
4525+
<leak-ignore/>
4526+
<arg nr="1">
4527+
<not-null/>
4528+
<minsize type="strlen" arg="2"/>
4529+
</arg>
4530+
<arg nr="2">
4531+
<not-null/>
4532+
<not-uninit/>
4533+
<strz/>
4534+
</arg>
4535+
</function>
45234536
<!-- wchar_t *wcscpy(wchar_t *deststr, const wchar_t *srcstr); -->
45244537
<function name="wcscpy">
45254538
<noreturn>false</noreturn>

lib/library.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -608,12 +608,27 @@ bool Library::isargvalid(const Token *ftok, int argnr, const MathLib::bigint arg
608608
return false;
609609
}
610610

611+
static std::string functionName(const Token *ftok)
612+
{
613+
if (Token::simpleMatch(ftok->previous(), "."))
614+
return "";
615+
if (!Token::Match(ftok->tokAt(-2), "%name% ::"))
616+
return ftok->str();
617+
std::string ret(ftok->str());
618+
ftok = ftok->tokAt(-2);
619+
while (Token::Match(ftok, "%name% ::")) {
620+
ret = ftok->str() + "::" + ret;
621+
ftok = ftok->tokAt(-2);
622+
}
623+
return ret;
624+
}
625+
611626
const Library::ArgumentChecks * Library::getarg(const Token *ftok, int argnr) const
612627
{
613628
if (isNotLibraryFunction(ftok))
614629
return nullptr;
615630
std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it1;
616-
it1 = argumentChecks.find(ftok->str());
631+
it1 = argumentChecks.find(functionName(ftok));
617632
if (it1 == argumentChecks.end())
618633
return nullptr;
619634
const std::map<int,ArgumentChecks>::const_iterator it2 = it1->second.find(argnr);
@@ -678,12 +693,13 @@ const Library::Container* Library::detectContainer(const Token* typeStart) const
678693
}
679694
return nullptr;
680695
}
696+
681697
// returns true if ftok is not a library function
682698
bool Library::isNotLibraryFunction(const Token *ftok) const
683699
{
684700
// methods are not library functions
685701
// called from tokenizer, ast is not created properly yet
686-
if (Token::Match(ftok->previous(),"::|."))
702+
if (Token::Match(ftok->previous(),"."))
687703
return true;
688704
if (ftok->function() && ftok->function()->nestedIn && ftok->function()->nestedIn->type != Scope::eGlobal)
689705
return true;
@@ -701,7 +717,7 @@ bool Library::isNotLibraryFunction(const Token *ftok) const
701717
else if (tok->link() && Token::Match(tok, "<|(|["))
702718
tok = tok->link();
703719
}
704-
const std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it = argumentChecks.find(ftok->str());
720+
const std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it = argumentChecks.find(functionName(ftok));
705721
if (it == argumentChecks.end())
706722
return (callargs != 0);
707723
int args = 0;
@@ -720,7 +736,7 @@ bool Library::isnoreturn(const Token *ftok) const
720736
return true;
721737
if (isNotLibraryFunction(ftok))
722738
return false;
723-
std::map<std::string, bool>::const_iterator it = _noreturn.find(ftok->str());
739+
std::map<std::string, bool>::const_iterator it = _noreturn.find(functionName(ftok));
724740
return (it != _noreturn.end() && it->second);
725741
}
726742

@@ -730,7 +746,7 @@ bool Library::isnotnoreturn(const Token *ftok) const
730746
return false;
731747
if (isNotLibraryFunction(ftok))
732748
return false;
733-
std::map<std::string, bool>::const_iterator it = _noreturn.find(ftok->str());
749+
std::map<std::string, bool>::const_iterator it = _noreturn.find(functionName(ftok));
734750
return (it != _noreturn.end() && !it->second);
735751
}
736752

test/testlibrary.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class TestLibrary : public TestFixture {
3939
TEST_CASE(function_arg_any);
4040
TEST_CASE(function_arg_valid);
4141
TEST_CASE(function_arg_minsize);
42+
TEST_CASE(function_namespace);
4243
TEST_CASE(memory);
4344
TEST_CASE(memory2); // define extra "free" allocation functions
4445
TEST_CASE(resource);
@@ -288,6 +289,28 @@ class TestLibrary : public TestFixture {
288289
}
289290
}
290291

292+
void function_namespace() const {
293+
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
294+
"<def>\n"
295+
" <function name=\"Foo::foo\">\n"
296+
" <noreturn>false</noreturn>\n"
297+
" </function>\n"
298+
"</def>";
299+
tinyxml2::XMLDocument doc;
300+
doc.Parse(xmldata, sizeof(xmldata));
301+
302+
TokenList tokenList(nullptr);
303+
std::istringstream istr("Foo::foo();");
304+
tokenList.createTokens(istr);
305+
306+
Library library;
307+
library.load(doc);
308+
ASSERT(library.use.empty());
309+
ASSERT(library.leakignore.empty());
310+
ASSERT(library.argumentChecks.empty());
311+
ASSERT(library.isnotnoreturn(tokenList.front()->tokAt(2)));
312+
}
313+
291314
void memory() const {
292315
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
293316
"<def>\n"

0 commit comments

Comments
 (0)