Permalink
Browse files

Fixed #1374 (false negative: using uninitialized variable in printf)

  • Loading branch information...
1 parent d53a6ca commit 1d4839b8a6693e5e2f3a0d0c0401fe34b6012334 @amai2012 amai2012 committed with Mar 6, 2014
Showing with 42 additions and 12 deletions.
  1. +1 −1 cfg/std.cfg
  2. +16 −1 lib/library.cpp
  3. +1 −10 lib/library.h
  4. +8 −0 man/manual.docbook
  5. +16 −0 test/testlibrary.cpp
View
@@ -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>
View
@@ -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;
+}
View
@@ -342,16 +342,7 @@ class CPPCHECKLIB Library {
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);
View
@@ -971,6 +971,14 @@ Checking noreturn.c...
<literal>&lt;not-null&gt;</literal> and
<literal>&lt;not-uninit&gt;</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>
View
@@ -32,6 +32,7 @@ class TestLibrary : public TestFixture {
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 @@ class TestLibrary : public TestFixture {
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"

0 comments on commit 1d4839b

Please sign in to comment.