From 33f604a233077c316b7a9b0a26706ffd7f28a4f9 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Fri, 1 Dec 2023 11:54:56 +0100 Subject: [PATCH 1/4] Fix FN uninitvar with POD struct (refs #6933) --- lib/astutils.cpp | 3 +++ test/testuninitvar.cpp | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 2da5f3f219e..8af5feeb974 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3257,6 +3257,9 @@ 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()) { + if (ftok->variable()->type() && ftok->variable()->type()->needInitialization == Type::NeedInitialization::True) + return ExprUsage::Used; } else { const bool isnullbad = settings->library.isnullargbad(ftok, argnr + 1); if (indirect == 0 && astIsPointer(tok) && !addressOf && isnullbad) diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 37b2100f547..3b0e1d51a2a 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -7251,6 +7251,19 @@ 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"); + ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n" + "[test.cpp:8]: (error) Uninitialized variable: i\n", + errout.str()); } void uninitvar_memberfunction() { From 15c167c4850d054ee8a0c207745819497dde432d Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Fri, 1 Dec 2023 12:08:44 +0100 Subject: [PATCH 2/4] Warn for STL types --- lib/astutils.cpp | 4 +++- test/testuninitvar.cpp | 12 +++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 8af5feeb974..97359b101db 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3257,9 +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()) { + } 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()) // STL types 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/testuninitvar.cpp b/test/testuninitvar.cpp index 3b0e1d51a2a..b303d24dd1d 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -7260,9 +7260,19 @@ class TestUninitVar : public TestFixture { "void g() {\n" " int i;\n" " S t{ i };\n" + "}\n" + "void h() {\n" + " int i;\n" + " std::vector v(i);\n" + "}\n" + "void k() {\n" + " double d;\n" + " std::complex c(d, d);\n" "}\n"); ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n" - "[test.cpp:8]: (error) Uninitialized variable: i\n", + "[test.cpp:8]: (error) Uninitialized variable: i\n" + "[test.cpp:12]: (error) Uninitialized variable: i\n" + "[test.cpp:16]: (error) Uninitialized variable: d\n", errout.str()); } From fedac972e220cd5d18c2bf22865d1f3f53f12670 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Fri, 1 Dec 2023 12:15:02 +0100 Subject: [PATCH 3/4] Fix TODO --- test/cfg/std.cpp | 2 +- test/testuninitvar.cpp | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) 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 b303d24dd1d..ff6490afb85 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -7264,15 +7264,10 @@ class TestUninitVar : public TestFixture { "void h() {\n" " int i;\n" " std::vector v(i);\n" - "}\n" - "void k() {\n" - " double d;\n" - " std::complex c(d, d);\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" - "[test.cpp:16]: (error) Uninitialized variable: d\n", + "[test.cpp:12]: (error) Uninitialized variable: i\n", errout.str()); } From a6dc812bd8ce47860b673ca1c77fd52618088f17 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Fri, 1 Dec 2023 12:41:45 +0100 Subject: [PATCH 4/4] Support non-STL containers --- lib/astutils.cpp | 2 +- test/cfg/qt.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 97359b101db..62a616ee671 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3260,7 +3260,7 @@ static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Settings } 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()) // STL types don't initialize external variables + 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); 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) {