Fixed #3092 (Tokenizer::setVarId : shadow variable in member function gets the wrong varid)
This commit is contained in:
parent
dc29d43e83
commit
92333b585a
|
@ -3474,6 +3474,13 @@ void Tokenizer::setVarId()
|
|||
varname = tok2->str();
|
||||
else if (tok2->str() != "*" && tok2->str() != "&")
|
||||
break;
|
||||
|
||||
// a type can't have varid
|
||||
if (tok2->previous()->varId() > 0) {
|
||||
tok2 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
tok2 = tok2->next();
|
||||
}
|
||||
|
||||
|
@ -3498,6 +3505,7 @@ void Tokenizer::setVarId()
|
|||
Token::Match(tok2->next(), "%bool%") ||
|
||||
tok2->next()->str()[0] == '"' ||
|
||||
tok2->next()->str()[0] == '\'' ||
|
||||
tok2->next()->str() == "*" ||
|
||||
tok2->next()->varId() != 0) {
|
||||
// This is not a function
|
||||
} else {
|
||||
|
@ -3557,7 +3565,7 @@ void Tokenizer::setVarId()
|
|||
while (NULL != (tok2 = tok2->next())) {
|
||||
const char c = tok2->str()[0];
|
||||
if (c == varname[0]) {
|
||||
if (tok2->str() == varname) {
|
||||
if (tok2->str() == varname && (className.empty() || tok2->varId() == 0)) {
|
||||
const std::string &prev = tok2->previous()->str();
|
||||
|
||||
/** @todo better handling when classes in different scopes have the same name */
|
||||
|
|
|
@ -184,6 +184,7 @@ private:
|
|||
TEST_CASE(varid34); // ticket #2825
|
||||
TEST_CASE(varid35); // ticket #2937
|
||||
TEST_CASE(varid36); // ticket #2980 (segmentation fault)
|
||||
TEST_CASE(varid37); // ticket #3092 (varid for 'Bar bar(*this);')
|
||||
TEST_CASE(varidFunctionCall1);
|
||||
TEST_CASE(varidFunctionCall2);
|
||||
TEST_CASE(varidFunctionCall3);
|
||||
|
@ -193,6 +194,7 @@ private:
|
|||
TEST_CASE(varid_reference_to_containers);
|
||||
TEST_CASE(varid_in_class1);
|
||||
TEST_CASE(varid_in_class2);
|
||||
TEST_CASE(varid_in_class3); // #3092 - shadow variable in member function
|
||||
TEST_CASE(varid_operator);
|
||||
TEST_CASE(varid_throw);
|
||||
TEST_CASE(varid_unknown_macro); // #2638 - unknown macro is not type
|
||||
|
@ -2854,13 +2856,9 @@ private:
|
|||
"}\n");
|
||||
const std::string expected2("\n\n##file 0\n"
|
||||
"1: void f ( int b@1 , int c@2 ) {\n"
|
||||
"2: x ( a@3 * b@1 * c@2 , 10 ) ;\n"
|
||||
"2: x ( a * b@1 * c@2 , 10 ) ;\n"
|
||||
"3: }\n");
|
||||
const std::string actual2("\n\n##file 0\n"
|
||||
"1: void f ( int b@1 , int c@2 ) {\n"
|
||||
"2: x ( a * b@1 * c@3 , 10 ) ;\n"
|
||||
"3: }\n");
|
||||
TODO_ASSERT_EQUALS(expected2, actual2, tokenizeDebugListing(code2));
|
||||
ASSERT_EQUALS(expected2, tokenizeDebugListing(code2));
|
||||
|
||||
const std::string code3("class Nullpointer : public ExecutionPath\n"
|
||||
" {\n"
|
||||
|
@ -2939,6 +2937,16 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void varid37() {
|
||||
const std::string code = "void blah() {"
|
||||
" Bar bar(*x);"
|
||||
"}";
|
||||
ASSERT_EQUALS("\n\n##file 0\n1: "
|
||||
"void blah ( ) { Bar bar@1 ( * x ) ; }\n",
|
||||
tokenizeDebugListing(code));
|
||||
}
|
||||
|
||||
|
||||
void varidFunctionCall1() {
|
||||
const std::string code("void f() {\n"
|
||||
" int x;\n"
|
||||
|
@ -3200,6 +3208,23 @@ private:
|
|||
ASSERT_EQUALS(expected, actual);
|
||||
}
|
||||
|
||||
void varid_in_class3() {
|
||||
const std::string code = "class Foo {\n"
|
||||
" void blah() {\n"
|
||||
" Bar x(*this);\n" // <- ..
|
||||
" }\n"
|
||||
" int x;\n" // <- .. don't assign same varid
|
||||
"};";
|
||||
ASSERT_EQUALS("\n\n##file 0\n"
|
||||
"1: class Foo {\n"
|
||||
"2: void blah ( ) {\n"
|
||||
"3: Bar x@1 ( * this ) ;\n"
|
||||
"4: }\n"
|
||||
"5: int x@2 ;\n"
|
||||
"6: } ;\n", tokenizeDebugListing(code));
|
||||
}
|
||||
|
||||
|
||||
void varid_operator() {
|
||||
{
|
||||
const std::string actual = tokenizeDebugListing(
|
||||
|
|
Loading…
Reference in New Issue