Fix 10555: FP knownConditionTrueFalse with non-const function in base class (#3559)
This commit is contained in:
parent
49d3e07b59
commit
13f5b560ce
|
@ -751,18 +751,20 @@ bool exprDependsOnThis(const Token* expr, bool onVar, nonneg int depth)
|
|||
return true;
|
||||
++depth;
|
||||
// calling nonstatic method?
|
||||
if (Token::Match(expr->previous(), "!!:: %name% (") && expr->function() && expr->function()->nestedIn && expr->function()->nestedIn->isClassOrStruct()) {
|
||||
if (Token::Match(expr->previous(), "!!:: %name% (") && expr->function() && expr->function()->nestedIn &&
|
||||
expr->function()->nestedIn->isClassOrStruct()) {
|
||||
// is it a method of this?
|
||||
const Scope* fScope = expr->scope();
|
||||
while (!fScope->functionOf && fScope->nestedIn)
|
||||
fScope = fScope->nestedIn;
|
||||
const Scope* nestedIn = fScope->functionOf;
|
||||
if (nestedIn && nestedIn->function)
|
||||
nestedIn = nestedIn->function->token->scope();
|
||||
while (nestedIn && nestedIn != expr->function()->nestedIn) {
|
||||
nestedIn = nestedIn->nestedIn;
|
||||
}
|
||||
return nestedIn == expr->function()->nestedIn;
|
||||
|
||||
const Scope* classScope = fScope->functionOf;
|
||||
if (classScope && classScope->function)
|
||||
classScope = classScope->function->token->scope();
|
||||
|
||||
if (classScope && classScope->isClassOrStruct())
|
||||
return contains(classScope->findAssociatedScopes(), expr->function()->nestedIn);
|
||||
return false;
|
||||
} else if (onVar && Token::Match(expr, "%var%") && expr->variable()) {
|
||||
const Variable* var = expr->variable();
|
||||
return (var->isPrivate() || var->isPublic() || var->isProtected());
|
||||
|
|
|
@ -4892,6 +4892,24 @@ const Scope *Scope::findRecordInBase(const std::string & name) const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<const Scope*> Scope::findAssociatedScopes() const
|
||||
{
|
||||
std::vector<const Scope*> result = {this};
|
||||
if (isClassOrStruct() && definedType && !definedType->derivedFrom.empty()) {
|
||||
const std::vector<Type::BaseInfo>& derivedFrom = definedType->derivedFrom;
|
||||
for (const Type::BaseInfo& i : derivedFrom) {
|
||||
const Type* base = i.type;
|
||||
if (base && base->classScope) {
|
||||
if (contains(result, base->classScope))
|
||||
continue;
|
||||
std::vector<const Scope*> baseScopes = base->classScope->findAssociatedScopes();
|
||||
result.insert(result.end(), baseScopes.begin(), baseScopes.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void checkVariableCallMatch(const Variable* callarg, const Variable* funcarg, size_t& same, size_t& fallback1, size_t& fallback2)
|
||||
|
|
|
@ -1192,6 +1192,8 @@ public:
|
|||
|
||||
const Scope *findRecordInBase(const std::string &name) const;
|
||||
|
||||
std::vector<const Scope*> findAssociatedScopes() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief helper function for getVariableList()
|
||||
|
|
|
@ -3894,6 +3894,25 @@ private:
|
|||
" return delta;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// #10555
|
||||
check("struct C {\n"
|
||||
" int GetI() const { return i; }\n"
|
||||
" int i{};\n"
|
||||
"};\n"
|
||||
"struct B {\n"
|
||||
" C *m_PC{};\n"
|
||||
" Modify();\n"
|
||||
"};\n"
|
||||
"struct D : B {\n"
|
||||
" void test(); \n"
|
||||
"};\n"
|
||||
"void D::test() {\n"
|
||||
" const int I = m_PC->GetI();\n"
|
||||
" Modify();\n"
|
||||
" if (m_PC->GetI() != I) {}\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void alwaysTrueInfer() {
|
||||
|
|
Loading…
Reference in New Issue