diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 89efeb006..43f7c6f2a 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1324,7 +1324,7 @@ private: const bool array; bool alloc; - + // p = malloc .. static void alloc_pointer(std::list &checks, unsigned int varid) { std::list::const_iterator it; @@ -1339,6 +1339,39 @@ private: } } + // *p = .. + static void init_pointer(bool &foundError, std::list &checks, const Token *tok) + { + const unsigned int varid(tok->varId()); + if (!varid) + return; + + std::list::iterator it = checks.begin(); + while (it != checks.end()) + { + if (!(*it)->bailOut()) + { + CheckUninitVar *c = dynamic_cast(*it); + if (c && c->varId == varid) + { + if (c->alloc) + { + delete c; + checks.erase(it++); + continue; + } + else + { + use_pointer(foundError, checks, tok); + } + } + } + + ++it; + } + } + + // free p; static void dealloc_pointer(bool &foundError, std::list &checks, const Token *tok) { const unsigned int varid(tok->varId()); @@ -1447,13 +1480,18 @@ private: { if (Token::Match(tok.tokAt(-2), "[;{}] *")) { - use_pointer(foundError, checks, &tok); + if (Token::simpleMatch(tok.next(), "=")) + init_pointer(foundError, checks, &tok); + else + use_pointer(foundError, checks, &tok); return &tok; } if (Token::Match(tok.next(), "= malloc|kmalloc") || Token::simpleMatch(tok.next(), "= new char [")) { alloc_pointer(checks, tok.varId()); + if (tok.tokAt(3)->str() == "(") + return tok.tokAt(3)->link(); } else if (Token::simpleMatch(tok.previous(), ">>") || Token::simpleMatch(tok.next(), "=")) diff --git a/test/testother.cpp b/test/testother.cpp index 1abd3a817..23b4b369c 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1307,6 +1307,13 @@ private: "};\n"); ASSERT_EQUALS("", errout.str()); + checkUninitVar("void foo(char *s)\n" + "{\n" + " char *a = malloc(100);\n" + " *a = *s;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + // struct.. checkUninitVar("void f()\n" "{\n"