Skip to content

Commit 204c821

Browse files
Fix #13167 FP invalidLifetime when constructing string from c_str() (#7231)
1 parent c59a00e commit 204c821

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

lib/valueflow.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2647,6 +2647,8 @@ static void valueFlowLifetimeClassConstructor(Token* tok,
26472647
if (it == scope->varlist.cend())
26482648
return;
26492649
const Variable& var = *it;
2650+
if (var.valueType() && var.valueType()->container && var.valueType()->container->stdStringLike && !var.valueType()->container->view)
2651+
return; // TODO: check in isLifetimeBorrowed()?
26502652
if (var.isReference() || var.isRValueReference()) {
26512653
ls.byRef(tok, tokenlist, errorLogger, settings);
26522654
} else if (ValueFlow::isLifetimeBorrowed(ls.argtok, settings)) {

test/testautovariables.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class TestAutoVariables : public TestFixture {
148148
TEST_CASE(danglingLifetime);
149149
TEST_CASE(danglingLifetimeFunction);
150150
TEST_CASE(danglingLifetimeUserConstructor);
151-
TEST_CASE(danglingLifetimeAggegrateConstructor);
151+
TEST_CASE(danglingLifetimeAggregateConstructor);
152152
TEST_CASE(danglingLifetimeInitList);
153153
TEST_CASE(danglingLifetimeImplicitConversion);
154154
TEST_CASE(danglingTemporaryLifetime);
@@ -3796,7 +3796,7 @@ class TestAutoVariables : public TestFixture {
37963796
ASSERT_EQUALS("", errout_str());
37973797
}
37983798

3799-
void danglingLifetimeAggegrateConstructor() {
3799+
void danglingLifetimeAggregateConstructor() {
38003800
check("struct A {\n"
38013801
" const int& x;\n"
38023802
" int y;\n"
@@ -3893,6 +3893,30 @@ class TestAutoVariables : public TestFixture {
38933893
" return { m.data() };\n"
38943894
"}\n");
38953895
ASSERT_EQUALS("", errout_str());
3896+
3897+
check("struct S { std::string s; };\n" // #13167
3898+
"std::vector<S> f() {\n"
3899+
" std::vector<S> v;\n"
3900+
" {\n"
3901+
" std::string a{ \"abc\" };\n"
3902+
" v.push_back({ a.c_str() });\n"
3903+
" }\n"
3904+
" return v;\n"
3905+
"}\n");
3906+
ASSERT_EQUALS("", errout_str());
3907+
3908+
check("struct S { std::string_view sv; };\n"
3909+
"std::vector<S> f() {\n"
3910+
" std::vector<S> v;\n"
3911+
" {\n"
3912+
" std::string a{ \"abc\" };\n"
3913+
" v.push_back({ a.c_str() });\n"
3914+
" }\n"
3915+
" return v;\n"
3916+
"}\n");
3917+
ASSERT_EQUALS(
3918+
"[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",
3919+
errout_str());
38963920
}
38973921

38983922
void danglingLifetimeInitList() {

0 commit comments

Comments
 (0)