From 60caefe0697978bc11e48f7f6fa6d99450b5c709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 7 Nov 2009 09:10:15 +0100 Subject: [PATCH] uninitialized data: added more checking for allocated data --- lib/checkother.cpp | 33 ++++++++++++++++++++++++++++++++- lib/checkother.h | 4 +++- test/testother.cpp | 9 +++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 95d9a980f..1acca3f77 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1412,7 +1412,33 @@ void CheckOther::uninitvar() break; --indentlevel; } - if (Token::Match(tok, "[{};] %type% *| %var% [;[]")) + + if (Token::Match(tok, "[{};] %var% = malloc|kmalloc (") || + Token::Match(tok, "[{};] %var% = new char [") ) + { + // check that the variable id is non-zero + const unsigned int varid = tok->next()->varId(); + if (varid == 0) + continue; + + // goto ')' + tok = tok->tokAt(4)->link(); + if (!tok) + break; + + // check if data is accessed uninitialized.. + for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) + { + if (tok2->str() == "{" || tok2->str() == "}") + break; + if (tok2->varId() == varid) + break; + if (Token::Match(tok2, "strcat|strncat|strlen ( %varid%", varid)) + uninitdataError(tok2, tok2->strAt(2)); + } + } + + else if (Token::Match(tok, "[{};] %type% *| %var% [;[]")) { if (Token::Match(tok->next(), "return|goto")) continue; @@ -1594,6 +1620,11 @@ void CheckOther::nullPointerError(const Token *tok, const std::string &varname, reportError(tok, Severity::error, "nullPointer", "Possible null pointer dereference: " + varname + " - otherwise it is redundant to check if " + varname + " is null at line " + MathLib::toString(line)); } +void CheckOther::uninitdataError(const Token *tok, const std::string &varname) +{ + reportError(tok, Severity::error, "uninitdata", "Data is allocated but not initialized: " + varname); +} + void CheckOther::uninitvarError(const Token *tok, const std::string &varname) { reportError(tok, Severity::error, "uninitvar", "Uninitialized variable: " + varname); diff --git a/lib/checkother.h b/lib/checkother.h index d75a6134c..3a6fdd856 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -147,6 +147,7 @@ public: void strPlusChar(const Token *tok); void nullPointerError(const Token *tok, const std::string &varname); void nullPointerError(const Token *tok, const std::string &varname, const int line); + void uninitdataError(const Token *tok, const std::string &varname); void uninitvarError(const Token *tok, const std::string &varname); void zerodivError(const Token *tok); void postIncrementError(const Token *tok, const std::string &var_name, const bool isIncrement); @@ -157,6 +158,7 @@ public: sprintfOverlappingDataError(0, "varname"); udivError(0); nullPointerError(0, "pointer"); + uninitdataError(0, "varname"); uninitvarError(0, "varname"); zerodivError(0); @@ -192,6 +194,7 @@ public: " * [[OverlappingData|bad usage of the function 'sprintf' (overlapping data)]]\n" " * division with zero\n" " * null pointer dereferencing\n" + " * using uninitialized variables and data\n" // style " * C-style pointer cast in cpp file\n" @@ -205,7 +208,6 @@ public: " * variable scope can be limited\n" " * condition that is always true/false\n" " * unusal pointer arithmetic. For example: \"abc\" + 'd'\n" - " * uninitialized variables\n" // optimisations " * optimisation: detect post increment/decrement\n"; diff --git a/test/testother.cpp b/test/testother.cpp index a88197a26..0b06e5771 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1136,6 +1136,15 @@ private: " strcat(s, \"abc\");\n" "};\n"); ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: s\n", errout.str()); + + // alloc.. + checkUninitVar("void f()\n" + "{\n" + " char *s = malloc(100);\n" + " strcat(s, \"abc\");\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:4]: (error) Data is allocated but not initialized: s\n", errout.str()); + }