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

View File

@ -252,6 +252,7 @@ private:
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_class10);
TEST_CASE(varid_in_class11); // #4277 - anonymous union
TEST_CASE(varid_initList);
TEST_CASE(varid_operator);
TEST_CASE(varid_throw);
@ -3992,6 +3993,30 @@ private:
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() {
const char code[] = "class A {\n"