Skip to content

Commit

Permalink
Fix #13167 FP invalidLifetime when constructing string from c_str() (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github authored Jan 18, 2025
1 parent c59a00e commit 204c821
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
2 changes: 2 additions & 0 deletions lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2647,6 +2647,8 @@ static void valueFlowLifetimeClassConstructor(Token* tok,
if (it == scope->varlist.cend())
return;
const Variable& var = *it;
if (var.valueType() && var.valueType()->container && var.valueType()->container->stdStringLike && !var.valueType()->container->view)
return; // TODO: check in isLifetimeBorrowed()?
if (var.isReference() || var.isRValueReference()) {
ls.byRef(tok, tokenlist, errorLogger, settings);
} else if (ValueFlow::isLifetimeBorrowed(ls.argtok, settings)) {
Expand Down
28 changes: 26 additions & 2 deletions test/testautovariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class TestAutoVariables : public TestFixture {
TEST_CASE(danglingLifetime);
TEST_CASE(danglingLifetimeFunction);
TEST_CASE(danglingLifetimeUserConstructor);
TEST_CASE(danglingLifetimeAggegrateConstructor);
TEST_CASE(danglingLifetimeAggregateConstructor);
TEST_CASE(danglingLifetimeInitList);
TEST_CASE(danglingLifetimeImplicitConversion);
TEST_CASE(danglingTemporaryLifetime);
Expand Down Expand Up @@ -3796,7 +3796,7 @@ class TestAutoVariables : public TestFixture {
ASSERT_EQUALS("", errout_str());
}

void danglingLifetimeAggegrateConstructor() {
void danglingLifetimeAggregateConstructor() {
check("struct A {\n"
" const int& x;\n"
" int y;\n"
Expand Down Expand Up @@ -3893,6 +3893,30 @@ class TestAutoVariables : public TestFixture {
" return { m.data() };\n"
"}\n");
ASSERT_EQUALS("", errout_str());

check("struct S { std::string s; };\n" // #13167
"std::vector<S> f() {\n"
" std::vector<S> v;\n"
" {\n"
" std::string a{ \"abc\" };\n"
" v.push_back({ a.c_str() });\n"
" }\n"
" return v;\n"
"}\n");
ASSERT_EQUALS("", errout_str());

check("struct S { std::string_view sv; };\n"
"std::vector<S> f() {\n"
" std::vector<S> v;\n"
" {\n"
" std::string a{ \"abc\" };\n"
" v.push_back({ a.c_str() });\n"
" }\n"
" return v;\n"
"}\n");
ASSERT_EQUALS(
"[test.cpp:6] -> [test.cpp:6] -> [test.cpp:6] -> [test.cpp:5] -> [test.cpp:8]: (error) Returning object that points to local variable 'a' that will be invalid when returning.\n",
errout_str());
}

void danglingLifetimeInitList() {
Expand Down

0 comments on commit 204c821

Please sign in to comment.