From a65f427195c9e65b1144caf8b0256a00c30c83b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 22 Sep 2012 08:16:16 +0200 Subject: [PATCH] Fixed #3836 (False positive: variable not initialized in copy constructor/operator (attached example code) --- lib/checkclass.cpp | 17 ++++++++++------- test/testconstructors.cpp | 23 ++++++----------------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 58fb7aab7..2df800ec1 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -270,17 +270,20 @@ void CheckClass::noCopyConstructorError(const Token *tok, const std::string &cla bool CheckClass::canNotCopy(const Scope *scope) { std::list::const_iterator func; - bool privateAssign = false; - bool privateCopy = false; + bool constructor = false; + bool publicAssign = false; + bool publicCopy = false; for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { - if (func->type == Function::eCopyConstructor && func->access == Private) - privateCopy = true; - else if (func->type == Function::eOperatorEqual && func->access == Private) - privateAssign = true; + if (func->type == Function::eConstructor || func->type == Function::eCopyConstructor) + constructor = true; + if (func->type == Function::eCopyConstructor && func->access == Public) + publicCopy = true; + else if (func->type == Function::eOperatorEqual && func->access == Public) + publicAssign = true; } - return privateAssign && privateCopy; + return constructor && !(publicAssign | publicCopy); } void CheckClass::assignVar(const std::string &varname, const Scope *scope, std::vector &usage) diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index b6466bb8b..9f27466e4 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -739,8 +739,9 @@ private: "A::B::B(int x){}\n" "A::B::C::C(int y){}\n" "A::B::C::D::D(int z){}\n"); + // Note that the example code is not compilable. The A constructor must + // explicitly initialize A::b. A warning for A::b is not necessary. ASSERT_EQUALS("[test.cpp:20]: (warning) Member variable 'A::a' is not initialized in the constructor.\n" - "[test.cpp:20]: (warning) Member variable 'A::b' is not initialized in the constructor.\n" "[test.cpp:21]: (warning) Member variable 'B::b' is not initialized in the constructor.\n" "[test.cpp:22]: (warning) Member variable 'C::c' is not initialized in the constructor.\n" "[test.cpp:23]: (warning) Member variable 'D::d' is not initialized in the constructor.\n", errout.str()); @@ -768,8 +769,9 @@ private: "A::B::B(int x){}\n" "A::B::C::C(int y){}\n" "A::B::C::D::D(const A::B::C::D & d){}\n"); + // Note that the example code is not compilable. The A constructor must + // explicitly initialize A::b. A warning for A::b is not necessary. ASSERT_EQUALS("[test.cpp:20]: (warning) Member variable 'A::a' is not initialized in the constructor.\n" - "[test.cpp:20]: (warning) Member variable 'A::b' is not initialized in the constructor.\n" "[test.cpp:21]: (warning) Member variable 'B::b' is not initialized in the constructor.\n" "[test.cpp:22]: (warning) Member variable 'C::c' is not initialized in the constructor.\n" "[test.cpp:23]: (warning) Member variable 'D::d' is not initialized in the constructor.\n", errout.str()); @@ -798,8 +800,9 @@ private: "A::B::B(int x){}\n" "A::B::C::C(int y){}\n" "A::B::C::D::D(const A::B::C::D::E & e){}\n"); + // Note that the example code is not compilable. The A constructor must + // explicitly initialize A::b. A warning for A::b is not necessary. ASSERT_EQUALS("[test.cpp:21]: (warning) Member variable 'A::a' is not initialized in the constructor.\n" - "[test.cpp:21]: (warning) Member variable 'A::b' is not initialized in the constructor.\n" "[test.cpp:22]: (warning) Member variable 'B::b' is not initialized in the constructor.\n" "[test.cpp:23]: (warning) Member variable 'C::c' is not initialized in the constructor.\n" "[test.cpp:24]: (warning) Member variable 'D::d' is not initialized in the constructor.\n", errout.str()); @@ -1430,20 +1433,6 @@ private: " Altren value;\n" "};"); ASSERT_EQUALS("", errout.str()); - - check("struct Altren\n" - "{\n" - " explicit Altren(int _a) : value(0) { }\n" - " int value;\n" - "};\n" - "class A\n" - "{\n" - "public:\n" - " A() { }\n" - "private:\n" - " Altren value;\n" - "};"); - ASSERT_EQUALS("[test.cpp:9]: (warning) Member variable 'A::value' is not initialized in the constructor.\n", errout.str()); } void uninitVar19() { // ticket #2792