Skip to content

Commit 9ab1585

Browse files
Fix #14260 Crash in valueFlowLifetimeClassConstructor() (danmar#7957)
Co-authored-by: chrchr-github <noreply@github.com>
1 parent 3747685 commit 9ab1585

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

lib/valueflow.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2860,7 +2860,6 @@ static void valueFlowLifetimeClassConstructor(Token* tok,
28602860
std::vector<const Token*> args = getArguments(tok);
28612861
if (scope->numConstructors == 0) {
28622862
auto it = scope->varlist.cbegin();
2863-
const bool hasDesignatedInitializers = !args.empty() && isDesignatedInitializer(args[0]->astOperand1());
28642863
LifetimeStore::forEach(
28652864
tokenlist,
28662865
errorLogger,
@@ -2869,13 +2868,18 @@ static void valueFlowLifetimeClassConstructor(Token* tok,
28692868
"Passed to constructor of '" + t->name() + "'.",
28702869
ValueFlow::Value::LifetimeKind::SubObject,
28712870
[&](LifetimeStore& ls) {
2871+
const bool isDesignatedInitializerArg = isDesignatedInitializer(ls.argtok->astOperand1());
28722872
// Skip static variable
28732873
it = std::find_if(it, scope->varlist.cend(), [&](const Variable &var) {
2874-
return !var.isStatic() && (!hasDesignatedInitializers || var.name() == ls.argtok->astOperand1()->astOperand1()->str());
2874+
if (var.isStatic())
2875+
return false;
2876+
if (!isDesignatedInitializerArg)
2877+
return true;
2878+
return var.name() == ls.argtok->astOperand1()->astOperand1()->str();
28752879
});
28762880
if (it == scope->varlist.cend())
28772881
return;
2878-
if (hasDesignatedInitializers)
2882+
if (isDesignatedInitializerArg)
28792883
ls.argtok = ls.argtok->astOperand2();
28802884
const Variable &var = *it;
28812885
if (var.valueType() && var.valueType()->container && var.valueType()->container->stdStringLike && !var.valueType()->container->view)
@@ -2885,7 +2889,7 @@ static void valueFlowLifetimeClassConstructor(Token* tok,
28852889
} else if (ValueFlow::isLifetimeBorrowed(ls.argtok, settings)) {
28862890
ls.byVal(tok, tokenlist, errorLogger, settings);
28872891
}
2888-
if (hasDesignatedInitializers)
2892+
if (isDesignatedInitializerArg) // TODO: handle mixed initialization?
28892893
it = scope->varlist.cbegin();
28902894
else
28912895
it++;

test/testautovariables.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3985,6 +3985,12 @@ class TestAutoVariables : public TestFixture {
39853985
" return a;\n"
39863986
"}\n");
39873987
ASSERT_EQUALS("", errout_str());
3988+
3989+
check("struct S { int i; bool b; };\n" // #14260
3990+
"void f() {\n"
3991+
" struct S s = { .i = 0, true };\n"
3992+
"}\n"); // don't crash
3993+
ASSERT_EQUALS("", errout_str());
39883994
}
39893995

39903996
void danglingLifetimeInitList() {

0 commit comments

Comments
 (0)