Fix 10537: FN: knownConditionTrueFalse (std::string::c_str() never returns nullptr) (#3498)

This commit is contained in:
Paul Fultz II 2021-10-11 12:16:12 -05:00 committed by GitHub
parent f309925a7b
commit 52e4bec50a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 0 deletions

View File

@ -1560,6 +1560,25 @@ static void valueFlowImpossibleValues(TokenList* tokenList, const Settings* sett
value.bound = ValueFlow::Value::Bound::Upper;
value.setImpossible();
setTokenValue(tok->next(), value, settings);
} else if (Token::Match(tok, ". data|c_str (") && astIsContainerOwned(tok->astOperand1())) {
const Library::Container* container = tok->astOperand1()->valueType()->container;
if (!container)
continue;
if (!container->stdStringLike)
continue;
if (container->view)
continue;
ValueFlow::Value value{0};
value.setImpossible();
setTokenValue(tok->tokAt(2), value, settings);
} else if (Token::Match(tok, "make_shared|make_unique <") && Token::simpleMatch(tok->linkAt(1), "> (")) {
ValueFlow::Value value{0};
value.setImpossible();
setTokenValue(tok->linkAt(1)->next(), value, settings);
} else if (tokenList->isCPP() && Token::simpleMatch(tok, "this")) {
ValueFlow::Value value{0};
value.setImpossible();
setTokenValue(tok, value, settings);
}
}
}

View File

@ -142,6 +142,7 @@ private:
TEST_CASE(valueFlowIdempotent);
TEST_CASE(valueFlowUnsigned);
TEST_CASE(valueFlowMod);
TEST_CASE(valueFlowNotNull);
TEST_CASE(valueFlowSymbolic);
TEST_CASE(valueFlowSmartPointer);
}
@ -6197,6 +6198,43 @@ private:
ASSERT_EQUALS(false, testValueOfXImpossible(code, 3U, 1));
}
void valueFlowNotNull()
{
const char* code;
code = "int f(const std::string &str) {\n"
" int x = str.c_str();\n"
" return x;\n"
"}\n";
ASSERT_EQUALS(true, testValueOfXImpossible(code, 3U, 0));
code = "int f(const std::string_view &str) {\n"
" int x = str.c_str();\n"
" return x;\n"
"}\n";
ASSERT_EQUALS(false, testValueOfXImpossible(code, 3U, 0));
code = "auto f() {\n"
" std::shared_ptr<int> x = std::make_shared<int>(1);\n"
" return x;\n"
"}\n";
ASSERT_EQUALS(true, testValueOfXImpossible(code, 3U, 0));
code = "auto f() {\n"
" std::unique_ptr<int> x = std::make_unique<int>(1);\n"
" return x;\n"
"}\n";
ASSERT_EQUALS(true, testValueOfXImpossible(code, 3U, 0));
code = "struct A {\n"
" A* f() {\n"
" A* x = this;\n"
" return x;\n"
" }\n"
"};\n";
ASSERT_EQUALS(true, testValueOfXImpossible(code, 4U, 0));
}
void valueFlowSymbolic() {
const char* code;