From 55c2b75c2e0481db4779153f2792e7cf3f5cfb94 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 1 Dec 2023 17:42:27 +0100 Subject: [PATCH] Fix #6933 FN uninitvar with POD struct and STL types (#5713) Co-authored-by: chrchr-github --- lib/astutils.cpp | 5 +++++ test/cfg/qt.cpp | 7 +++++++ test/cfg/std.cpp | 2 +- test/testuninitvar.cpp | 18 ++++++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 2da5f3f219e..62a616ee671 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3257,6 +3257,11 @@ static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Settings return ExprUsage::Used; } else if (ftok->str() == "{") { return indirect == 0 ? ExprUsage::Used : ExprUsage::Inconclusive; + } else if (ftok->variable() && ftok == ftok->variable()->nameToken()) { // variable init/constructor call + if (ftok->variable()->type() && ftok->variable()->type()->needInitialization == Type::NeedInitialization::True) + return ExprUsage::Used; + if (ftok->variable()->isStlType() || (ftok->variable()->valueType() && ftok->variable()->valueType()->container)) // STL types or containers don't initialize external variables + return ExprUsage::Used; } else { const bool isnullbad = settings->library.isnullargbad(ftok, argnr + 1); if (indirect == 0 && astIsPointer(tok) && !addressOf && isnullbad) diff --git a/test/cfg/qt.cpp b/test/cfg/qt.cpp index 63ccf3b1d72..46310e32171 100644 --- a/test/cfg/qt.cpp +++ b/test/cfg/qt.cpp @@ -321,6 +321,13 @@ void duplicateExpression_QString_Compare(QString style) //#8723 {} } +void QVector_uninit() +{ + int i; + // cppcheck-suppress [uninitvar, unreadVariable] + QVector v(i); +} + void QStack1(QStack intStackArg) { for (int i = 0; i <= intStackArg.size(); ++i) { diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index b0926a0eed5..b8305bb62bf 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -1043,8 +1043,8 @@ void uninitvar_isxdigit(void) void uninitvar_proj(void) { double d; + // cppcheck-suppress uninitvar const std::complex dc(d,d); - // TODO cppcheck-suppress uninitvar (void)std::proj(dc); } diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 37b2100f547..ff6490afb85 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -7251,6 +7251,24 @@ class TestUninitVar : public TestFixture { "[test.cpp:23]: (error) Uninitialized variable: s.t.j\n" "[test.cpp:27]: (error) Uninitialized variable: s.t.j\n", errout.str()); + + valueFlowUninit("struct S { int x; };\n" + "void f() {\n" + " int i;\n" + " S s(i);\n" + "}\n" + "void g() {\n" + " int i;\n" + " S t{ i };\n" + "}\n" + "void h() {\n" + " int i;\n" + " std::vector v(i);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n" + "[test.cpp:8]: (error) Uninitialized variable: i\n" + "[test.cpp:12]: (error) Uninitialized variable: i\n", + errout.str()); } void uninitvar_memberfunction() {