Fixed #4277 (duplicateExpression finds false positive for floats in a union as a member of a class)

This commit is contained in:
Daniel Marjamäki 2012-12-03 17:05:37 +01:00
parent ab82cc6305
commit c91250cd6e
2 changed files with 58 additions and 27 deletions

View File

@ -2668,38 +2668,44 @@ void Tokenizer::setVarId()
(Token::simpleMatch(tok->link(), ") {") || Token::Match(tok->link(), ") %type% {"))) { (Token::simpleMatch(tok->link(), ") {") || Token::Match(tok->link(), ") %type% {"))) {
scopeInfo.push(variableId); scopeInfo.push(variableId);
} else if (tok->str() == "{") { } else if (tok->str() == "{") {
scopestartvarid.push(_varId); // parse anonymous unions as part of the current scope
if (Token::simpleMatch(tok->previous(), ")") || Token::Match(tok->tokAt(-2), ") %type%")) { if (!(Token::simpleMatch(tok->previous(), "union") && Token::simpleMatch(tok->link(), "} ;"))) {
executableScope.push(true); scopestartvarid.push(_varId);
} else { if (Token::simpleMatch(tok->previous(), ")") || Token::Match(tok->tokAt(-2), ") %type%")) {
executableScope.push(executableScope.top()); executableScope.push(true);
scopeInfo.push(variableId); } else {
executableScope.push(executableScope.top());
scopeInfo.push(variableId);
}
} }
} else if (tok->str() == "}") { } else if (tok->str() == "}") {
// Set variable ids in class declaration.. // parse anonymous unions as part of the current scope
if (!isC() && !executableScope.top() && tok->link()) { if (!(Token::simpleMatch(tok, "} ;") && Token::simpleMatch(tok->link()->previous(), "union {"))) {
setVarIdClassDeclaration(tok->link(), // Set variable ids in class declaration..
variableId, if (!isC() && !executableScope.top() && tok->link()) {
scopestartvarid.top(), setVarIdClassDeclaration(tok->link(),
&structMembers, variableId,
&_varId); scopestartvarid.top(),
} &structMembers,
&_varId);
}
scopestartvarid.pop(); scopestartvarid.pop();
if (scopestartvarid.empty()) { // should be impossible if (scopestartvarid.empty()) { // should be impossible
scopestartvarid.push(0); scopestartvarid.push(0);
} }
if (scopeInfo.empty()) { if (scopeInfo.empty()) {
variableId.clear(); variableId.clear();
} else { } else {
variableId.swap(scopeInfo.top()); variableId.swap(scopeInfo.top());
scopeInfo.pop(); scopeInfo.pop();
} }
executableScope.pop(); executableScope.pop();
if (executableScope.empty()) { // should not possibly happen if (executableScope.empty()) { // should not possibly happen
executableScope.push(false); executableScope.push(false);
}
} }
} }

View File

@ -252,6 +252,7 @@ private:
TEST_CASE(varid_in_class8); // unknown macro in class TEST_CASE(varid_in_class8); // unknown macro in class
TEST_CASE(varid_in_class9); // #4291 - id for variables accessed through 'this' TEST_CASE(varid_in_class9); // #4291 - id for variables accessed through 'this'
TEST_CASE(varid_in_class10); TEST_CASE(varid_in_class10);
TEST_CASE(varid_in_class11); // #4277 - anonymous union
TEST_CASE(varid_initList); TEST_CASE(varid_initList);
TEST_CASE(varid_operator); TEST_CASE(varid_operator);
TEST_CASE(varid_throw); TEST_CASE(varid_throw);
@ -3992,6 +3993,30 @@ private:
tokenizeDebugListing(code)); tokenizeDebugListing(code));
} }
void varid_in_class11() { // #4277 - anonymous union
const char code1[] = "class Foo {\n"
" union { float a; int b; };\n"
" void f() { a=0; }\n"
"};";
ASSERT_EQUALS("\n\n##file 0\n"
"1: class Foo {\n"
"2: union { float a@1 ; int b@2 ; } ;\n"
"3: void f ( ) { a@1 = 0 ; }\n"
"4: } ;\n",
tokenizeDebugListing(code1));
const char code2[] = "class Foo {\n"
" void f() { a=0; }\n"
" union { float a; int b; };\n"
"};";
ASSERT_EQUALS("\n\n##file 0\n"
"1: class Foo {\n"
"2: void f ( ) { a@1 = 0 ; }\n"
"3: union { float a@1 ; int b@2 ; } ;\n"
"4: } ;\n",
tokenizeDebugListing(code2));
}
void varid_initList() { void varid_initList() {
const char code[] = "class A {\n" const char code[] = "class A {\n"