Skip to content

Commit 52e4bec

Browse files
authored
Fix 10537: FN: knownConditionTrueFalse (std::string::c_str() never returns nullptr) (#3498)
1 parent f309925 commit 52e4bec

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

lib/valueflow.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,6 +1560,25 @@ static void valueFlowImpossibleValues(TokenList* tokenList, const Settings* sett
15601560
value.bound = ValueFlow::Value::Bound::Upper;
15611561
value.setImpossible();
15621562
setTokenValue(tok->next(), value, settings);
1563+
} else if (Token::Match(tok, ". data|c_str (") && astIsContainerOwned(tok->astOperand1())) {
1564+
const Library::Container* container = tok->astOperand1()->valueType()->container;
1565+
if (!container)
1566+
continue;
1567+
if (!container->stdStringLike)
1568+
continue;
1569+
if (container->view)
1570+
continue;
1571+
ValueFlow::Value value{0};
1572+
value.setImpossible();
1573+
setTokenValue(tok->tokAt(2), value, settings);
1574+
} else if (Token::Match(tok, "make_shared|make_unique <") && Token::simpleMatch(tok->linkAt(1), "> (")) {
1575+
ValueFlow::Value value{0};
1576+
value.setImpossible();
1577+
setTokenValue(tok->linkAt(1)->next(), value, settings);
1578+
} else if (tokenList->isCPP() && Token::simpleMatch(tok, "this")) {
1579+
ValueFlow::Value value{0};
1580+
value.setImpossible();
1581+
setTokenValue(tok, value, settings);
15631582
}
15641583
}
15651584
}

test/testvalueflow.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ class TestValueFlow : public TestFixture {
142142
TEST_CASE(valueFlowIdempotent);
143143
TEST_CASE(valueFlowUnsigned);
144144
TEST_CASE(valueFlowMod);
145+
TEST_CASE(valueFlowNotNull);
145146
TEST_CASE(valueFlowSymbolic);
146147
TEST_CASE(valueFlowSmartPointer);
147148
}
@@ -6197,6 +6198,43 @@ class TestValueFlow : public TestFixture {
61976198
ASSERT_EQUALS(false, testValueOfXImpossible(code, 3U, 1));
61986199
}
61996200

6201+
void valueFlowNotNull()
6202+
{
6203+
const char* code;
6204+
6205+
code = "int f(const std::string &str) {\n"
6206+
" int x = str.c_str();\n"
6207+
" return x;\n"
6208+
"}\n";
6209+
ASSERT_EQUALS(true, testValueOfXImpossible(code, 3U, 0));
6210+
6211+
code = "int f(const std::string_view &str) {\n"
6212+
" int x = str.c_str();\n"
6213+
" return x;\n"
6214+
"}\n";
6215+
ASSERT_EQUALS(false, testValueOfXImpossible(code, 3U, 0));
6216+
6217+
code = "auto f() {\n"
6218+
" std::shared_ptr<int> x = std::make_shared<int>(1);\n"
6219+
" return x;\n"
6220+
"}\n";
6221+
ASSERT_EQUALS(true, testValueOfXImpossible(code, 3U, 0));
6222+
6223+
code = "auto f() {\n"
6224+
" std::unique_ptr<int> x = std::make_unique<int>(1);\n"
6225+
" return x;\n"
6226+
"}\n";
6227+
ASSERT_EQUALS(true, testValueOfXImpossible(code, 3U, 0));
6228+
6229+
code = "struct A {\n"
6230+
" A* f() {\n"
6231+
" A* x = this;\n"
6232+
" return x;\n"
6233+
" }\n"
6234+
"};\n";
6235+
ASSERT_EQUALS(true, testValueOfXImpossible(code, 4U, 0));
6236+
}
6237+
62006238
void valueFlowSymbolic() {
62016239
const char* code;
62026240

0 commit comments

Comments
 (0)