Fix 10537: FN: knownConditionTrueFalse (std::string::c_str() never returns nullptr) (#3498)
This commit is contained in:
parent
f309925a7b
commit
52e4bec50a
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue