From e3b7bce72b550c25d90a770f83cdee3760158e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 30 Sep 2013 06:35:31 +0200 Subject: [PATCH] Fixed #4907 (False positive 'uninitStructMember' on structs with unions) --- lib/checkuninitvar.cpp | 20 ++++++++++++++++++-- test/testuninitvar.cpp | 14 ++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index b70754e24..f1b2e25cc 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1103,8 +1103,24 @@ void CheckUninitVar::checkScope(const Scope* scope) if (scope2->className == structname && scope2->numConstructors == 0U) { for (std::list::const_iterator it = scope2->varlist.begin(); it != scope2->varlist.end(); ++it) { const Variable &var = *it; - if (!var.isArray()) - checkScopeForVariable(scope, tok, *i, NULL, NULL, var.name()); + if (!var.isArray()) { + // is the variable declared in a inner union? + bool innerunion = false; + for (std::list::const_iterator it2 = symbolDatabase->scopeList.begin(); it2 != symbolDatabase->scopeList.end(); it2++) { + const Scope &innerScope = *it2; + if (innerScope.type == Scope::eUnion && innerScope.nestedIn == scope2) { + if (var.typeStartToken()->linenr() >= innerScope.classStart->linenr() && + var.typeStartToken()->linenr() <= innerScope.classEnd->linenr()) { + innerunion = true; + break; + } + + } + } + + if (!innerunion) + checkScopeForVariable(scope, tok, *i, NULL, NULL, var.name()); + } } } } diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 504338d58..f58617c9b 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -2788,6 +2788,20 @@ private: "}\n", "test.c"); ASSERT_EQUALS("", errout.str()); + checkUninitVar2("struct PIXEL {\n" + " union {\n" + " struct { unsigned char red,green,blue,alpha; };\n" + " unsigned int color;\n" + " };\n" + "};\n" + "\n" + "unsigned char f() {\n" + " struct PIXEL p1;\n" + " p1.color = 255;\n" + " return p1.red;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + // return checkUninitVar2("struct AB { int a; int b; };\n" "void f(void) {\n"