Fixed #6711 (Add namespace support to library files)
This commit is contained in:
parent
9627fccdc5
commit
b70fe4c609
13
cfg/std.cfg
13
cfg/std.cfg
|
@ -4520,6 +4520,19 @@
|
||||||
<strz/>
|
<strz/>
|
||||||
</arg>
|
</arg>
|
||||||
</function>
|
</function>
|
||||||
|
<function name="std::strcpy">
|
||||||
|
<noreturn>false</noreturn>
|
||||||
|
<leak-ignore/>
|
||||||
|
<arg nr="1">
|
||||||
|
<not-null/>
|
||||||
|
<minsize type="strlen" arg="2"/>
|
||||||
|
</arg>
|
||||||
|
<arg nr="2">
|
||||||
|
<not-null/>
|
||||||
|
<not-uninit/>
|
||||||
|
<strz/>
|
||||||
|
</arg>
|
||||||
|
</function>
|
||||||
<!-- wchar_t *wcscpy(wchar_t *deststr, const wchar_t *srcstr); -->
|
<!-- wchar_t *wcscpy(wchar_t *deststr, const wchar_t *srcstr); -->
|
||||||
<function name="wcscpy">
|
<function name="wcscpy">
|
||||||
<noreturn>false</noreturn>
|
<noreturn>false</noreturn>
|
||||||
|
|
|
@ -608,12 +608,27 @@ bool Library::isargvalid(const Token *ftok, int argnr, const MathLib::bigint arg
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string functionName(const Token *ftok)
|
||||||
|
{
|
||||||
|
if (Token::simpleMatch(ftok->previous(), "."))
|
||||||
|
return "";
|
||||||
|
if (!Token::Match(ftok->tokAt(-2), "%name% ::"))
|
||||||
|
return ftok->str();
|
||||||
|
std::string ret(ftok->str());
|
||||||
|
ftok = ftok->tokAt(-2);
|
||||||
|
while (Token::Match(ftok, "%name% ::")) {
|
||||||
|
ret = ftok->str() + "::" + ret;
|
||||||
|
ftok = ftok->tokAt(-2);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
const Library::ArgumentChecks * Library::getarg(const Token *ftok, int argnr) const
|
const Library::ArgumentChecks * Library::getarg(const Token *ftok, int argnr) const
|
||||||
{
|
{
|
||||||
if (isNotLibraryFunction(ftok))
|
if (isNotLibraryFunction(ftok))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it1;
|
std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it1;
|
||||||
it1 = argumentChecks.find(ftok->str());
|
it1 = argumentChecks.find(functionName(ftok));
|
||||||
if (it1 == argumentChecks.end())
|
if (it1 == argumentChecks.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
const std::map<int,ArgumentChecks>::const_iterator it2 = it1->second.find(argnr);
|
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
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if ftok is not a library function
|
// returns true if ftok is not a library function
|
||||||
bool Library::isNotLibraryFunction(const Token *ftok) const
|
bool Library::isNotLibraryFunction(const Token *ftok) const
|
||||||
{
|
{
|
||||||
// methods are not library functions
|
// methods are not library functions
|
||||||
// called from tokenizer, ast is not created properly yet
|
// called from tokenizer, ast is not created properly yet
|
||||||
if (Token::Match(ftok->previous(),"::|."))
|
if (Token::Match(ftok->previous(),"."))
|
||||||
return true;
|
return true;
|
||||||
if (ftok->function() && ftok->function()->nestedIn && ftok->function()->nestedIn->type != Scope::eGlobal)
|
if (ftok->function() && ftok->function()->nestedIn && ftok->function()->nestedIn->type != Scope::eGlobal)
|
||||||
return true;
|
return true;
|
||||||
|
@ -701,7 +717,7 @@ bool Library::isNotLibraryFunction(const Token *ftok) const
|
||||||
else if (tok->link() && Token::Match(tok, "<|(|["))
|
else if (tok->link() && Token::Match(tok, "<|(|["))
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
}
|
}
|
||||||
const std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it = argumentChecks.find(ftok->str());
|
const std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it = argumentChecks.find(functionName(ftok));
|
||||||
if (it == argumentChecks.end())
|
if (it == argumentChecks.end())
|
||||||
return (callargs != 0);
|
return (callargs != 0);
|
||||||
int args = 0;
|
int args = 0;
|
||||||
|
@ -720,7 +736,7 @@ bool Library::isnoreturn(const Token *ftok) const
|
||||||
return true;
|
return true;
|
||||||
if (isNotLibraryFunction(ftok))
|
if (isNotLibraryFunction(ftok))
|
||||||
return false;
|
return false;
|
||||||
std::map<std::string, bool>::const_iterator it = _noreturn.find(ftok->str());
|
std::map<std::string, bool>::const_iterator it = _noreturn.find(functionName(ftok));
|
||||||
return (it != _noreturn.end() && it->second);
|
return (it != _noreturn.end() && it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,7 +746,7 @@ bool Library::isnotnoreturn(const Token *ftok) const
|
||||||
return false;
|
return false;
|
||||||
if (isNotLibraryFunction(ftok))
|
if (isNotLibraryFunction(ftok))
|
||||||
return false;
|
return false;
|
||||||
std::map<std::string, bool>::const_iterator it = _noreturn.find(ftok->str());
|
std::map<std::string, bool>::const_iterator it = _noreturn.find(functionName(ftok));
|
||||||
return (it != _noreturn.end() && !it->second);
|
return (it != _noreturn.end() && !it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ private:
|
||||||
TEST_CASE(function_arg_any);
|
TEST_CASE(function_arg_any);
|
||||||
TEST_CASE(function_arg_valid);
|
TEST_CASE(function_arg_valid);
|
||||||
TEST_CASE(function_arg_minsize);
|
TEST_CASE(function_arg_minsize);
|
||||||
|
TEST_CASE(function_namespace);
|
||||||
TEST_CASE(memory);
|
TEST_CASE(memory);
|
||||||
TEST_CASE(memory2); // define extra "free" allocation functions
|
TEST_CASE(memory2); // define extra "free" allocation functions
|
||||||
TEST_CASE(resource);
|
TEST_CASE(resource);
|
||||||
|
@ -288,6 +289,28 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void function_namespace() const {
|
||||||
|
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
|
||||||
|
"<def>\n"
|
||||||
|
" <function name=\"Foo::foo\">\n"
|
||||||
|
" <noreturn>false</noreturn>\n"
|
||||||
|
" </function>\n"
|
||||||
|
"</def>";
|
||||||
|
tinyxml2::XMLDocument doc;
|
||||||
|
doc.Parse(xmldata, sizeof(xmldata));
|
||||||
|
|
||||||
|
TokenList tokenList(nullptr);
|
||||||
|
std::istringstream istr("Foo::foo();");
|
||||||
|
tokenList.createTokens(istr);
|
||||||
|
|
||||||
|
Library library;
|
||||||
|
library.load(doc);
|
||||||
|
ASSERT(library.use.empty());
|
||||||
|
ASSERT(library.leakignore.empty());
|
||||||
|
ASSERT(library.argumentChecks.empty());
|
||||||
|
ASSERT(library.isnotnoreturn(tokenList.front()->tokAt(2)));
|
||||||
|
}
|
||||||
|
|
||||||
void memory() const {
|
void memory() const {
|
||||||
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
|
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
|
||||||
"<def>\n"
|
"<def>\n"
|
||||||
|
|
Loading…
Reference in New Issue