Fixed #4907 (False positive 'uninitStructMember' on structs with unions)

This commit is contained in:
Daniel Marjamäki 2013-09-30 06:35:31 +02:00
parent cb4abd6f16
commit e3b7bce72b
2 changed files with 32 additions and 2 deletions

View File

@ -1103,13 +1103,29 @@ void CheckUninitVar::checkScope(const Scope* scope)
if (scope2->className == structname && scope2->numConstructors == 0U) {
for (std::list<Variable>::const_iterator it = scope2->varlist.begin(); it != scope2->varlist.end(); ++it) {
const Variable &var = *it;
if (!var.isArray())
if (!var.isArray()) {
// is the variable declared in a inner union?
bool innerunion = false;
for (std::list<Scope>::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());
}
}
}
}
}
}
}
static void conditionAlwaysTrueOrFalse(const Token *tok, const std::map<unsigned int, int> &variableValue, bool *alwaysTrue, bool *alwaysFalse)

View File

@ -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"