Fix #11497 debug: CheckClass::isMemberVar found used member variable 'x' with varid 0 (inconclusive) (#4736)
This commit is contained in:
parent
a0f51d1e21
commit
b5a06d045e
|
@ -2173,6 +2173,9 @@ bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) const
|
|||
}
|
||||
} while (again);
|
||||
|
||||
if (tok->isKeyword() || tok->isStandardType())
|
||||
return false;
|
||||
|
||||
for (const Variable& var : scope->varlist) {
|
||||
if (var.name() == tok->str()) {
|
||||
if (Token::Match(tok, "%name% ::"))
|
||||
|
|
|
@ -1208,6 +1208,8 @@ void SymbolDatabase::fixVarId(VarIdMap & varIds, const Token * vartok, Token * m
|
|||
membertok->varId(memberId->second);
|
||||
}
|
||||
|
||||
static bool isContainerYieldElement(Library::Container::Yield yield);
|
||||
|
||||
void SymbolDatabase::createSymbolDatabaseSetVariablePointers()
|
||||
{
|
||||
VarIdMap varIds;
|
||||
|
@ -1222,6 +1224,8 @@ void SymbolDatabase::createSymbolDatabaseSetVariablePointers()
|
|||
|
||||
// Set variable pointers
|
||||
for (const Token* tok = mTokenizer->list.front(); tok != mTokenizer->list.back(); tok = tok->next()) {
|
||||
if (!tok->isName() || tok->isKeyword() || tok->isStandardType())
|
||||
continue;
|
||||
if (tok->varId())
|
||||
const_cast<Token*>(tok)->variable(getVariableFromVarId(tok->varId()));
|
||||
|
||||
|
@ -1310,6 +1314,16 @@ void SymbolDatabase::createSymbolDatabaseSetVariablePointers()
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (Token::simpleMatch(tok->astParent(), ".") && tok->next()->str() == "(" &&
|
||||
astIsContainer(tok->astParent()->astOperand1()) && Token::Match(tok->next()->link(), ") . %name% !!(")) {
|
||||
const ValueType* vt = tok->astParent()->astOperand1()->valueType();
|
||||
const Library::Container* cont = vt->container;
|
||||
auto it = cont->functions.find(tok->str());
|
||||
if (it != cont->functions.end() && isContainerYieldElement(it->second.yield) && vt->containerTypeToken && vt->containerTypeToken->scope()) {
|
||||
Token* memberTok = tok->next()->link()->tokAt(2);
|
||||
setMemberVar(vt->containerTypeToken->scope()->getVariable(memberTok->str()), memberTok, vt->containerTypeToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6052,7 +6066,7 @@ static void setAutoTokenProperties(Token * const autoTok)
|
|||
autoTok->isStandardType(true);
|
||||
}
|
||||
|
||||
static bool isContainerYieldElement(Library::Container::Yield yield)
|
||||
bool isContainerYieldElement(Library::Container::Yield yield)
|
||||
{
|
||||
return yield == Library::Container::Yield::ITEM || yield == Library::Container::Yield::AT_INDEX ||
|
||||
yield == Library::Container::Yield::BUFFER || yield == Library::Container::Yield::BUFFER_NT;
|
||||
|
|
|
@ -32,9 +32,15 @@ struct InternalError;
|
|||
|
||||
class TestVarID : public TestFixture {
|
||||
public:
|
||||
TestVarID() : TestFixture("TestVarID") {}
|
||||
TestVarID() : TestFixture("TestVarID") {
|
||||
settings.platform(Settings::Unix64);
|
||||
settings.standards.c = Standards::C89;
|
||||
settings.standards.cpp = Standards::CPPLatest;
|
||||
settings.checkUnusedTemplates = true;
|
||||
}
|
||||
|
||||
private:
|
||||
Settings settings;
|
||||
void run() override {
|
||||
TEST_CASE(varid1);
|
||||
TEST_CASE(varid2);
|
||||
|
@ -137,6 +143,7 @@ private:
|
|||
TEST_CASE(varid_in_class22); // #10872
|
||||
TEST_CASE(varid_in_class23); // #11293
|
||||
TEST_CASE(varid_in_class24);
|
||||
TEST_CASE(varid_in_class25);
|
||||
TEST_CASE(varid_namespace_1); // #7272
|
||||
TEST_CASE(varid_namespace_2); // #7000
|
||||
TEST_CASE(varid_namespace_3); // #8627
|
||||
|
@ -235,12 +242,6 @@ private:
|
|||
std::string tokenize_(const char* file, int line, const char code[], const char filename[] = "test.cpp") {
|
||||
errout.str("");
|
||||
|
||||
Settings settings;
|
||||
settings.platform(Settings::Unix64);
|
||||
settings.standards.c = Standards::C89;
|
||||
settings.standards.cpp = Standards::CPPLatest;
|
||||
settings.checkUnusedTemplates = true;
|
||||
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
ASSERT_LOC((tokenizer.tokenize)(istr, filename), file, line);
|
||||
|
@ -255,12 +256,6 @@ private:
|
|||
std::string tokenizeExpr_(const char* file, int line, const char code[], const char filename[] = "test.cpp") {
|
||||
errout.str("");
|
||||
|
||||
Settings settings;
|
||||
settings.platform(Settings::Unix64);
|
||||
settings.standards.c = Standards::C89;
|
||||
settings.standards.cpp = Standards::CPPLatest;
|
||||
settings.checkUnusedTemplates = true;
|
||||
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
ASSERT_LOC((tokenizer.tokenize)(istr, filename), file, line);
|
||||
|
@ -275,12 +270,6 @@ private:
|
|||
std::string compareVaridsForVariable_(const char* file, int line, const char code[], const char varname[], const char filename[] = "test.cpp") {
|
||||
errout.str("");
|
||||
|
||||
Settings settings;
|
||||
settings.platform(Settings::Unix64);
|
||||
settings.standards.c = Standards::C89;
|
||||
settings.standards.cpp = Standards::CPP11;
|
||||
settings.checkUnusedTemplates = true;
|
||||
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
ASSERT_LOC((tokenizer.tokenize)(istr, filename), file, line);
|
||||
|
@ -2015,6 +2004,27 @@ private:
|
|||
ASSERT_EQUALS(expected, tokenize(code, "test.cpp"));
|
||||
}
|
||||
|
||||
void varid_in_class25() { // #11497
|
||||
const char *code{}, *expected{};
|
||||
Settings oldSettings = settings;
|
||||
LOAD_LIB_2(settings.library, "std.cfg");
|
||||
|
||||
code = "struct F {\n"
|
||||
" int i;\n"
|
||||
" void f(const std::vector<F>&v) {\n"
|
||||
" if (v.front().i) {}\n"
|
||||
" }\n"
|
||||
"};\n";
|
||||
expected = "1: struct F {\n"
|
||||
"2: int i@1 ;\n"
|
||||
"3: void f ( const std :: vector < F > & v@2 ) {\n"
|
||||
"4: if ( v@2 . front ( ) . i@3 ) { }\n"
|
||||
"5: }\n"
|
||||
"6: } ;\n";
|
||||
ASSERT_EQUALS(expected, tokenize(code, "test.cpp"));
|
||||
settings = oldSettings;
|
||||
}
|
||||
|
||||
void varid_namespace_1() { // #7272
|
||||
const char code[] = "namespace Blah {\n"
|
||||
" struct foo { int x;};\n"
|
||||
|
|
Loading…
Reference in New Issue