Fixed #1374 (false negative: using uninitialized variable in printf)
This commit is contained in:
parent
d53a6ca2cd
commit
1d4839b8a6
|
@ -56,7 +56,7 @@
|
|||
<function name="wcstoul"> <leak-ignore/> <arg nr="3"><valid>0,2-36</valid></arg> </function>
|
||||
<function name="wcstoull"> <leak-ignore/> <arg nr="3"><valid>0,2-36</valid></arg> </function>
|
||||
|
||||
<function name="printf"> <noreturn>false</noreturn> <formatstr/> <arg nr="1"><formatstr/></arg> </function>
|
||||
<function name="printf"> <noreturn>false</noreturn> <formatstr/> <arg nr="1"><formatstr/></arg> <arg nr="any"><not-uninit/></arg> </function>
|
||||
<function name="wprintf"> <noreturn>false</noreturn> <formatstr/> <arg nr="1"><formatstr/></arg> </function>
|
||||
<function name="sprintf"> <noreturn>false</noreturn> <formatstr/> <arg nr="2"><formatstr/></arg> </function>
|
||||
<function name="fprintf"> <noreturn>false</noreturn> <formatstr/> <arg nr="2"><formatstr/></arg> </function>
|
||||
|
|
|
@ -137,7 +137,8 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
|
|||
else if (strcmp(functionnode->Name(),"leak-ignore")==0)
|
||||
leakignore.insert(name);
|
||||
else if (strcmp(functionnode->Name(), "arg") == 0 && functionnode->Attribute("nr") != nullptr) {
|
||||
const int nr = atoi(functionnode->Attribute("nr"));
|
||||
const bool bAnyArg = strcmp(functionnode->Attribute("nr"),"any")==0;
|
||||
const int nr = (bAnyArg) ? -1 : atoi(functionnode->Attribute("nr"));
|
||||
bool notbool = false;
|
||||
bool notnull = false;
|
||||
bool notuninit = false;
|
||||
|
@ -310,3 +311,17 @@ bool Library::isargvalid(const std::string &functionName, int argnr, const MathL
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const Library::ArgumentChecks * Library::getarg(const std::string &functionName, int argnr) const
|
||||
{
|
||||
std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it1;
|
||||
it1 = argumentChecks.find(functionName);
|
||||
if (it1 == argumentChecks.end())
|
||||
return nullptr;
|
||||
const std::map<int,ArgumentChecks>::const_iterator it2 = it1->second.find(argnr);
|
||||
if (it2 != it1->second.end())
|
||||
return &it2->second;
|
||||
const std::map<int,ArgumentChecks>::const_iterator it3 = it1->second.find(-1);
|
||||
if (it3 != it1->second.end())
|
||||
return &it3->second;
|
||||
}
|
||||
|
|
|
@ -342,16 +342,7 @@ private:
|
|||
std::map<std::string, std::pair<bool, bool> > _formatstr; // Parameters for format string checking
|
||||
|
||||
|
||||
const ArgumentChecks * getarg(const std::string &functionName, int argnr) const {
|
||||
std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it1;
|
||||
it1 = argumentChecks.find(functionName);
|
||||
if (it1 != argumentChecks.end()) {
|
||||
const std::map<int,ArgumentChecks>::const_iterator it2 = it1->second.find(argnr);
|
||||
if (it2 != it1->second.end())
|
||||
return &it2->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
const ArgumentChecks * getarg(const std::string &functionName, int argnr) const;
|
||||
|
||||
static int getid(const std::map<std::string,int> &data, const std::string &name) {
|
||||
const std::map<std::string,int>::const_iterator it = data.find(name);
|
||||
|
|
|
@ -971,6 +971,14 @@ Checking noreturn.c...
|
|||
<literal><not-null></literal> and
|
||||
<literal><not-uninit></literal> is correct.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Specifications for all arguments</title>
|
||||
|
||||
<para>Specifying <literal>-1</literal> as the argument number is going
|
||||
to apply a check to all arguments of that function. The specifications
|
||||
for individual arguments override this setting.</para>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
<chapter>
|
||||
|
|
|
@ -32,6 +32,7 @@ private:
|
|||
TEST_CASE(empty);
|
||||
TEST_CASE(function);
|
||||
TEST_CASE(function_arg);
|
||||
TEST_CASE(function_arg_any);
|
||||
TEST_CASE(memory);
|
||||
TEST_CASE(resource);
|
||||
}
|
||||
|
@ -91,6 +92,21 @@ private:
|
|||
ASSERT_EQUALS(true, library.argumentChecks["foo"][6].notbool);
|
||||
}
|
||||
|
||||
void function_arg_any() {
|
||||
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
|
||||
"<def>\n"
|
||||
"<function name=\"foo\">\n"
|
||||
" <arg nr=\"any\"><not-uninit/></arg>\n"
|
||||
"</function>\n"
|
||||
"</def>";
|
||||
tinyxml2::XMLDocument doc;
|
||||
doc.Parse(xmldata, sizeof(xmldata));
|
||||
|
||||
Library library;
|
||||
library.load(doc);
|
||||
ASSERT_EQUALS(true, library.argumentChecks["foo"][-1].notuninit);
|
||||
}
|
||||
|
||||
void memory() {
|
||||
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
|
||||
"<def>\n"
|
||||
|
|
Loading…
Reference in New Issue