* Fix #10852 FP unused struct member (inner struct in C code) * Redundant findType() call, add test
This commit is contained in:
parent
ff902369e0
commit
4c85ac0d7b
|
@ -5423,11 +5423,16 @@ const Scope *SymbolDatabase::findScopeByName(const std::string& name) const
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const Scope *Scope::findRecordInNestedList(const std::string & name) const
|
||||
const Scope *Scope::findRecordInNestedList(const std::string & name, bool isC) const
|
||||
{
|
||||
for (const Scope* scope: nestedList) {
|
||||
if (scope->className == name && scope->type != eFunction)
|
||||
return scope;
|
||||
if (isC) {
|
||||
const Scope* nestedScope = scope->findRecordInNestedList(name, isC);
|
||||
if (nestedScope)
|
||||
return nestedScope;
|
||||
}
|
||||
}
|
||||
|
||||
const Type * nested_type = findType(name);
|
||||
|
@ -5546,6 +5551,23 @@ const Type* SymbolDatabase::findType(const Token *startTok, const Scope *startSc
|
|||
if (startTok->str() == startScope->className && startScope->isClassOrStruct() && startTok->strAt(1) != "::")
|
||||
return startScope->definedType;
|
||||
|
||||
if (mTokenizer->isC()) {
|
||||
const Scope* scope = startScope;
|
||||
while (scope) {
|
||||
if (startTok->str() == scope->className && scope->isClassOrStruct())
|
||||
return scope->definedType;
|
||||
const Scope* typeScope = scope->findRecordInNestedList(startTok->str(), /*isC*/ true);
|
||||
if (typeScope) {
|
||||
if (startTok->str() == typeScope->className && typeScope->isClassOrStruct()) {
|
||||
if (const Type* type = typeScope->definedType)
|
||||
return type;
|
||||
}
|
||||
}
|
||||
scope = scope->nestedIn;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Scope* start_scope = startScope;
|
||||
|
||||
// absolute path - directly start in global scope
|
||||
|
|
|
@ -1129,7 +1129,7 @@ public:
|
|||
*/
|
||||
const Function *findFunction(const Token *tok, bool requireConst=false) const;
|
||||
|
||||
const Scope *findRecordInNestedList(const std::string & name) const;
|
||||
const Scope *findRecordInNestedList(const std::string & name, bool isC = false) const;
|
||||
Scope *findRecordInNestedList(const std::string & name) {
|
||||
return const_cast<Scope *>(const_cast<const Scope *>(this)->findRecordInNestedList(name));
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ private:
|
|||
TEST_CASE(structmember16); // #10485
|
||||
TEST_CASE(structmember17); // #10591
|
||||
TEST_CASE(structmember18); // #10684
|
||||
TEST_CASE(structmember19); // #10826, #10848
|
||||
TEST_CASE(structmember19); // #10826, #10848, #10852
|
||||
|
||||
TEST_CASE(localvar1);
|
||||
TEST_CASE(localvar2);
|
||||
|
@ -1710,6 +1710,37 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:1]: (style) struct member 'A::i' is never used.\n",
|
||||
errout.str());
|
||||
|
||||
settings.enforcedLang = Settings::C;
|
||||
checkStructMemberUsage("struct A {\n" // #10852
|
||||
" struct B {\n"
|
||||
" int x;\n"
|
||||
" } b;\n"
|
||||
"} a;\n"
|
||||
"void f() {\n"
|
||||
" struct B* pb = &a.b;\n"
|
||||
" pb->x = 1;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
checkStructMemberUsage("union U {\n"
|
||||
" struct A {\n"
|
||||
" struct B {\n"
|
||||
" int x;\n"
|
||||
" } b;\n"
|
||||
" } a;\n"
|
||||
" struct C {\n"
|
||||
" short s[2];\n"
|
||||
" } c;\n"
|
||||
"} u;\n"
|
||||
"void f() {\n"
|
||||
" struct B* pb = &u.a.b;\n"
|
||||
" pb->x = 1;\n"
|
||||
" struct C* pc = &u.c;\n"
|
||||
" pc->s[0] = 1;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
settings.enforcedLang = Settings::None;
|
||||
}
|
||||
|
||||
void functionVariableUsage_(const char* file, int line, const char code[], const char filename[] = "test.cpp") {
|
||||
|
|
Loading…
Reference in New Issue