diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index e1bc3b974..c21aa37e5 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -898,6 +898,16 @@ void Variable::evaluate() bool Function::argsMatch(const Scope *scope, const Token *first, const Token *second, const std::string &path, unsigned int depth) { + const bool isCPP = scope->check->isCPP(); + + // skip "struct" if it is C++ + if (isCPP) { + if (first->str() == "struct") + first = first->next(); + if (second->str() == "struct") + second = second->next(); + } + while (first->str() == second->str()) { // at end of argument list if (first->str() == ")") { @@ -975,6 +985,14 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se first = first->next(); second = second->next(); + + // skip "struct" if it is C++ + if (isCPP) { + if (first->str() == "struct") + first = first->next(); + if (second->str() == "struct") + second = second->next(); + } } return false; @@ -2281,3 +2299,10 @@ unsigned int Scope::getNestedNonFunctions() const } return nested; } + +//--------------------------------------------------------------------------- + +bool SymbolDatabase::isCPP() const +{ + return _tokenizer->isCPP(); +} diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 46e1d2252..3e0e75c2e 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -614,6 +614,8 @@ public: void printOut(const char * title = NULL) const; void printVariable(const Variable *var, const char *indent) const; + bool isCPP() const; + private: // Needed by Borland C++: diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 3ab2b1e8d..ca52e2cfd 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -107,6 +107,7 @@ private: TEST_CASE(uninitVar20); // ticket #2867 TEST_CASE(uninitVar21); // ticket #2947 TEST_CASE(uninitVar22); // ticket #3043 + TEST_CASE(uninitVar23); // ticket #3702 TEST_CASE(uninitVarEnum); TEST_CASE(uninitVarStream); TEST_CASE(uninitVarTypedef); @@ -1561,6 +1562,29 @@ private: ASSERT_EQUALS("[test.cpp:7]: (warning) Member variable 'Fred::x' is not assigned a value in 'Fred::operator='.\n", errout.str()); } + void uninitVar23() { // ticket #3702 + check("class Fred {\n" + " int x;\n" + "public:\n" + " Fred(struct A a, struct B b);\n" + " Fred(C c, struct D d);\n" + " Fred(struct E e, F f);\n" + " Fred(struct G, struct H);\n" + " Fred(I, J);\n" + "};\n" + "Fred::Fred(A a, B b) { }\n" + "Fred::Fred(struct C c, D d) { }\n" + "Fred::Fred(E e, struct F f) { }\n" + "Fred::Fred(G g, H h) { }\n" + "Fred::Fred(struct I i, struct J j) { }\n" + ); + ASSERT_EQUALS("[test.cpp:10]: (warning) Member variable 'Fred::x' is not initialized in the constructor.\n" + "[test.cpp:11]: (warning) Member variable 'Fred::x' is not initialized in the constructor.\n" + "[test.cpp:12]: (warning) Member variable 'Fred::x' is not initialized in the constructor.\n" + "[test.cpp:13]: (warning) Member variable 'Fred::x' is not initialized in the constructor.\n" + "[test.cpp:14]: (warning) Member variable 'Fred::x' is not initialized in the constructor.\n", errout.str()); + } + void uninitVarArray1() { check("class John\n" "{\n"