From 9819b75e175f5574d5727b094fb1c80a78d60c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 25 Dec 2009 20:50:23 +0100 Subject: [PATCH] ExecutionPath: Refactoring if-handling --- lib/checkother.cpp | 4 ++-- lib/executionpath.cpp | 26 ++++++++++++++++---------- lib/executionpath.h | 8 ++++++-- test/testother.cpp | 11 ++++++++++- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 2210dda5e..89efeb006 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1278,7 +1278,7 @@ private: return &tok; } - bool parseCondition(const Token &tok, std::list &checks) const + bool parseCondition(const Token &tok, std::list &checks) { if (Token::Match(&tok, "!| %var% (")) { @@ -1607,7 +1607,7 @@ private: return &tok; } - bool parseCondition(const Token &tok, std::list &checks) const + bool parseCondition(const Token &tok, std::list &checks) { bool foundError = false; diff --git a/lib/executionpath.cpp b/lib/executionpath.cpp index 26b1f9f3d..71363fdec 100644 --- a/lib/executionpath.cpp +++ b/lib/executionpath.cpp @@ -23,8 +23,13 @@ // default : bail out if the condition is has variable handling -bool ExecutionPath::parseCondition(const Token &tok, std::list & /*checks*/) const +bool ExecutionPath::parseCondition(const Token &tok, std::list & checks) { + if (Token::Match(tok.tokAt(-3), "!!else if (")) + { + ++ifinfo; + } + unsigned int parlevel = 0; for (const Token *tok2 = &tok; tok2; tok2 = tok2->next()) { @@ -40,7 +45,10 @@ bool ExecutionPath::parseCondition(const Token &tok, std::list break; if (tok2->varId() != 0) { - return true; + if (ifinfo > 1) + return true; + else + bailOutVar(checks, tok2->varId()); } } @@ -52,9 +60,6 @@ static const Token *checkExecutionPaths_(const Token *tok, std::list check(checks.front()->copy()); - // Number of "if" blocks in current scope - unsigned int numberOfIf = 0; - for (; tok; tok = tok->next()) { if (tok->str() == "}") @@ -86,10 +91,6 @@ static const Token *checkExecutionPaths_(const Token *tok, std::liststr() == "if") { - ++numberOfIf; - if (numberOfIf > 1) - return 0; - std::list newchecks; while (tok->str() == "if") { @@ -99,7 +100,12 @@ static const Token *checkExecutionPaths_(const Token *tok, std::listparseCondition(*tok->next(), checks)) { - ExecutionPath::bailOut(checks); + while (!checks.empty()) + { + delete checks.back(); + checks.pop_back(); + } + return 0; } diff --git a/lib/executionpath.h b/lib/executionpath.h index 1a60ea497..d89b08373 100644 --- a/lib/executionpath.h +++ b/lib/executionpath.h @@ -41,14 +41,18 @@ protected: Check * const owner; public: - ExecutionPath(Check *c, unsigned int id) : bailout_(false), varId(id), owner(c) + ExecutionPath(Check *c, unsigned int id) : bailout_(false), varId(id), owner(c), ifinfo(0) { } virtual ~ExecutionPath() { } + /** Implement this in each derived class. This function must create a copy of the current instance */ virtual ExecutionPath *copy() = 0; + /** Some kind of if-information */ + unsigned int ifinfo; + bool bailOut() const { return bailout_; @@ -92,7 +96,7 @@ public: * @param checks The execution paths. All execution paths in the list are executed in the current scope * @return true => bail out all checking **/ - virtual bool parseCondition(const Token &tok, std::list &checks) const; + virtual bool parseCondition(const Token &tok, std::list &checks); /** going out of scope - all execution paths end */ virtual void end(const std::list & /*checks*/, const Token * /*tok*/) const diff --git a/test/testother.cpp b/test/testother.cpp index afb58e0e2..1abd3a817 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1005,6 +1005,15 @@ private: "}\n"); ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str()); + checkUninitVar("static int foo(int x)\n" + "{\n" + " int i;\n" + " if (x)\n" + " i = 0;\n" + " return i;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: i\n", errout.str()); + checkUninitVar("static void foo()\n" "{\n" " int x, y;\n" @@ -1139,7 +1148,7 @@ private: "}\n"); ASSERT_EQUALS("", errout.str()); - checkUninitVar("static void foo()\n" + checkUninitVar("static void foo(int x)\n" "{\n" " Foo *p;\n" " if (x)\n"