Fix #11888 FP knownPointerToBool with incorrect overload match / FP unreadVariable (#5356)

This commit is contained in:
chrchr-github 2023-08-22 16:53:38 +02:00 committed by GitHub
parent d6beccc445
commit 05a2d88ec8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 3 deletions

View File

@ -6789,11 +6789,15 @@ static const Token* parsedecl(const Token* type,
valuetype->constness = vt->constness; valuetype->constness = vt->constness;
valuetype->originalTypeName = vt->originalTypeName; valuetype->originalTypeName = vt->originalTypeName;
const bool hasConst = Token::simpleMatch(type->previous(), "const"); const bool hasConst = Token::simpleMatch(type->previous(), "const");
while (Token::Match(type, "%name%|*|&|::") && !type->variable()) { while (Token::Match(type, "%name%|*|&|&&|::") && !type->variable()) {
if (type->str() == "*") { if (type->str() == "*") {
valuetype->pointer = 1; valuetype->pointer = 1;
if (hasConst) if (hasConst)
valuetype->constness = 1; valuetype->constness = 1;
} else if (type->str() == "&") {
valuetype->reference = Reference::LValue;
} else if (type->str() == "&&") {
valuetype->reference = Reference::RValue;
} }
if (type->str() == "const") if (type->str() == "const")
valuetype->constness |= (1 << valuetype->pointer); valuetype->constness |= (1 << valuetype->pointer);
@ -7686,7 +7690,8 @@ ValueType::MatchResult ValueType::matchParameter(const ValueType *call, const Va
} }
if (call->typeScope != nullptr || func->typeScope != nullptr) { if (call->typeScope != nullptr || func->typeScope != nullptr) {
if (call->typeScope != func->typeScope) if (call->typeScope != func->typeScope &&
!(call->typeScope && func->typeScope && call->typeScope->definedType && call->typeScope->definedType->isDerivedFrom(func->typeScope->className)))
return ValueType::MatchResult::NOMATCH; return ValueType::MatchResult::NOMATCH;
} }

View File

@ -441,6 +441,7 @@ private:
TEST_CASE(findFunction46); TEST_CASE(findFunction46);
TEST_CASE(findFunction47); TEST_CASE(findFunction47);
TEST_CASE(findFunction48); TEST_CASE(findFunction48);
TEST_CASE(findFunction49); // #11888
TEST_CASE(findFunctionContainer); TEST_CASE(findFunctionContainer);
TEST_CASE(findFunctionExternC); TEST_CASE(findFunctionExternC);
TEST_CASE(findFunctionGlobalScope); // ::foo TEST_CASE(findFunctionGlobalScope); // ::foo
@ -511,6 +512,7 @@ private:
TEST_CASE(auto19); TEST_CASE(auto19);
TEST_CASE(auto20); TEST_CASE(auto20);
TEST_CASE(auto21); TEST_CASE(auto21);
TEST_CASE(auto22);
TEST_CASE(unionWithConstructor); TEST_CASE(unionWithConstructor);
@ -7286,6 +7288,22 @@ private:
ASSERT_EQUALS(1, typeTok->type()->classDef->linenr()); ASSERT_EQUALS(1, typeTok->type()->classDef->linenr());
} }
void findFunction49() {
GET_SYMBOL_DB("struct B {};\n"
"struct D : B {};\n"
"void f(bool = false, bool = true);\n"
"void f(B*, bool, bool = true);\n"
"void g() {\n"
" D d;\n"
" f(&d, true);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
const Token* ftok = Token::findsimplematch(tokenizer.tokens(), "f ( &");
ASSERT(ftok && ftok->function());
ASSERT(ftok->function()->name() == "f");
ASSERT_EQUALS(4, ftok->function()->tokenDef->linenr());
}
void findFunctionContainer() { void findFunctionContainer() {
{ {
GET_SYMBOL_DB("void dostuff(std::vector<int> v);\n" GET_SYMBOL_DB("void dostuff(std::vector<int> v);\n"
@ -8395,7 +8413,7 @@ private:
const Token* tok = tokenizer.tokens(); const Token* tok = tokenizer.tokens();
tok = Token::findsimplematch(tok, "s ."); tok = Token::findsimplematch(tok, "s .");
ASSERT(tok && tok->valueType()); ASSERT(tok && tok->valueType());
ASSERT_EQUALS("container(std :: set|unordered_set <)", tok->valueType()->str()); ASSERT_EQUALS("container(std :: set|unordered_set <) &", tok->valueType()->str());
} }
{ {
GET_SYMBOL_DB("void f(std::vector<int> v) {\n" GET_SYMBOL_DB("void f(std::vector<int> v) {\n"
@ -9470,6 +9488,22 @@ private:
ASSERT(v->variable() && v->variable()->isReference()); ASSERT(v->variable() && v->variable()->isReference());
} }
void auto22() {
GET_SYMBOL_DB("void f(std::vector<std::string>& v, bool b) {\n"
" auto& s = b ? v[0] : v[1];\n"
" s += \"abc\";\n"
"}\n");
ASSERT_EQUALS("", errout.str());
const Token* a = Token::findsimplematch(tokenizer.tokens(), "auto");
ASSERT(a && a->valueType());
ASSERT_EQUALS(a->valueType()->type, ValueType::CONTAINER);
const Token* s = Token::findsimplematch(a, "s +=");
ASSERT(s && s->valueType());
ASSERT_EQUALS(s->valueType()->type, ValueType::CONTAINER);
ASSERT(s->valueType()->reference == Reference::LValue);
ASSERT(s->variable() && s->variable()->isReference());
}
void unionWithConstructor() { void unionWithConstructor() {
GET_SYMBOL_DB("union Fred {\n" GET_SYMBOL_DB("union Fred {\n"
" Fred(int x) : i(x) { }\n" " Fred(int x) : i(x) { }\n"