From 3cf0e88fbe4407cf38477ff7d536a841e9cbef21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=E4ki?= Date: Sat, 19 Jan 2013 10:09:58 +0100 Subject: [PATCH] Uninitialized struct members: Improved checking when struct member is used in expression --- lib/checkuninitvar.cpp | 12 +++++++++--- test/testuninitvar.cpp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index ce124feba..e098f612a 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1321,7 +1321,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok, while (tok && tok->str() != ";") { // variable is seen.. - if (tok->varId() == var.varId()) { + if (tok->varId() == var.varId() && (membervar == NULL)) { // Use variable if (!suppressErrors && isVariableUsage(scope, tok, var.isPointer())) uninitvarError(tok, tok->str()); @@ -1343,8 +1343,14 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok, // variable is seen.. if (tok->varId() == var.varId()) { if (membervar) { - if (Token::Match(tok, "%var% . %var% [=.[]") && tok->strAt(2) == membervar->name()) - return true; + if (Token::Match(tok, "%var% . %var%") && tok->strAt(2) == membervar->name()) { + if (Token::Match(tok->tokAt(3), "[=.[]")) + return true; + else if (Token::Match(tok->previous(), "%op%") || Token::Match(tok->previous(), "[|=")) + uninitStructMemberError(tok, tok->str() + "." + membervar->name()); + else + return true; + } else if (tok->strAt(1) == "=") return true; else if (tok->strAt(-1) == "&") diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index c6d65082d..429f5efd7 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -2564,6 +2564,20 @@ private: "}\n", "test.c", true); ASSERT_EQUALS("[test.c:6]: (error) Uninitialized struct member: ab.b\n", errout.str()); + checkUninitVar2("struct AB { int a; int b; };\n" + "void f(void) {\n" + " struct AB ab;\n" + " int a = ab.a;\n" + "}\n", "test.c", true); + ASSERT_EQUALS("[test.c:4]: (error) Uninitialized struct member: ab.a\n", errout.str()); + + checkUninitVar2("struct AB { int a; int b; };\n" + "void f(void) {\n" + " struct AB ab;\n" + " buf[ab.a] = 0;\n" + "}\n", "test.c", true); + ASSERT_EQUALS("[test.c:4]: (error) Uninitialized struct member: ab.a\n", errout.str()); + checkUninitVar2("struct AB { int a; int b; };\n" "void do_something(const struct AB ab);\n" "void f(void) {\n" @@ -2607,6 +2621,23 @@ private: "}\n", "test.c", true); ASSERT_EQUALS("", errout.str()); + // return + checkUninitVar2("struct AB { int a; int b; };\n" + "void f(void) {\n" + " struct AB ab;\n" + " ab.a = 0;\n" + " return ab.b;\n" + "}\n", "test.c", true); + TODO_ASSERT_EQUALS("error", "", errout.str()); + + checkUninitVar2("struct AB { int a; int b; };\n" + "void f(void) {\n" + " struct AB ab;\n" + " ab.a = 0;\n" + " return ab.a;\n" + "}\n", "test.c", true); + ASSERT_EQUALS("", errout.str()); + // checkIfForWhileHead checkUninitVar2("struct FRED {\n" " int a;\n"