From 388413dcf6e05d57b3eecc1059d4a596414bbbd0 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Tue, 11 Nov 2025 22:16:48 +0100 Subject: [PATCH] Fix #14260 Crash in valueFlowLifetimeClassConstructor() --- lib/valueflow.cpp | 12 ++++++++---- test/testautovariables.cpp | 6 ++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index ee34251e15b..a89af243608 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2860,7 +2860,6 @@ static void valueFlowLifetimeClassConstructor(Token* tok, std::vector args = getArguments(tok); if (scope->numConstructors == 0) { auto it = scope->varlist.cbegin(); - const bool hasDesignatedInitializers = !args.empty() && isDesignatedInitializer(args[0]->astOperand1()); LifetimeStore::forEach( tokenlist, errorLogger, @@ -2869,13 +2868,18 @@ static void valueFlowLifetimeClassConstructor(Token* tok, "Passed to constructor of '" + t->name() + "'.", ValueFlow::Value::LifetimeKind::SubObject, [&](LifetimeStore& ls) { + const bool isDesignatedInitializerArg = isDesignatedInitializer(ls.argtok->astOperand1()); // Skip static variable it = std::find_if(it, scope->varlist.cend(), [&](const Variable &var) { - return !var.isStatic() && (!hasDesignatedInitializers || var.name() == ls.argtok->astOperand1()->astOperand1()->str()); + if (var.isStatic()) + return false; + if (!isDesignatedInitializerArg) + return true; + return var.name() == ls.argtok->astOperand1()->astOperand1()->str(); }); if (it == scope->varlist.cend()) return; - if (hasDesignatedInitializers) + if (isDesignatedInitializerArg) ls.argtok = ls.argtok->astOperand2(); const Variable &var = *it; if (var.valueType() && var.valueType()->container && var.valueType()->container->stdStringLike && !var.valueType()->container->view) @@ -2885,7 +2889,7 @@ static void valueFlowLifetimeClassConstructor(Token* tok, } else if (ValueFlow::isLifetimeBorrowed(ls.argtok, settings)) { ls.byVal(tok, tokenlist, errorLogger, settings); } - if (hasDesignatedInitializers) + if (isDesignatedInitializerArg) // TODO: handle mixed initialization? it = scope->varlist.cbegin(); else it++; diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 73380699255..36062107d17 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -3985,6 +3985,12 @@ class TestAutoVariables : public TestFixture { " return a;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("struct S { int i; bool b; };\n" // #14260 + "void f() {\n" + " struct S s = { .i = 0, true };\n" + "}\n"); // don't crash + ASSERT_EQUALS("", errout_str()); } void danglingLifetimeInitList() {