From 15a818cb897a3daef495c13eb2a747489cd106b8 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Sat, 6 Apr 2024 16:33:40 -0500 Subject: [PATCH] Fix 12461: False positive: uninitialized buffer, address of and function call (#6248) --- lib/astutils.cpp | 9 +++++++-- test/testuninitvar.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 1a672ef000b..5be309bb9e4 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -634,11 +634,13 @@ const Token* getParentLifetime(const Token* tok, const Library* library) std::vector members = getParentMembers(tok); if (members.size() < 2) return tok; - // Find the first local variable or temporary + // Find the first local variable, temporary, or array auto it = std::find_if(members.crbegin(), members.crend(), [&](const Token* tok2) { const Variable* var = tok2->variable(); if (var) return var->isLocal() || var->isArgument(); + if (Token::simpleMatch(tok2, "[")) + return true; return isTemporary(tok2, library); }); if (it == members.rend()) @@ -668,7 +670,10 @@ const Token* getParentLifetime(const Token* tok, const Library* library) return var && var->isReference(); })) return nullptr; - return *it; + const Token* result = *it; + if (Token::simpleMatch(result, "[") && result->astOperand1()) + return getParentLifetime(result->astOperand1()); + return result; } static bool isInConstructorList(const Token* tok) diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 91ec8ea28b5..215b5167428 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -7445,6 +7445,31 @@ class TestUninitVar : public TestFixture { " p->f();\n" "}\n"); ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:9]: (warning) Uninitialized variable: p\n", errout_str()); + + // #12461 + valueFlowUninit("struct stry_type {\n" + " void *out;\n" + "};\n" + "void bar(str_type *items);\n" + "void foo() {\n" + " str_type st_arr[1];\n" + " char arr[5];\n" + " st_arr[0].out = &arr;\n" + " bar(st_arr);\n" + " int len = strlen(arr);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + valueFlowUninit("struct stry_type {\n" + " void *out;\n" + "};\n" + "void foo() {\n" + " str_type st_arr[1];\n" + " char arr[5];\n" + " st_arr[0].out = &arr;\n" + " int len = strlen(arr);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:8]: (error) Uninitialized variable: arr\n", errout_str()); } void uninitvar_memberfunction() {