diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 7e3a1b73e..65eac6a33 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -90,8 +90,21 @@ void CheckClass::constructors() for (std::size_t i = 0; i < classes; ++i) { const Scope * scope = symbolDatabase->classAndStructScopes[i]; + bool usedInUnion = false; + for (std::list::const_iterator it = symbolDatabase->scopeList.begin(); it != symbolDatabase->scopeList.end(); ++it) { + if (it->type != Scope::eUnion) + continue; + const Scope &unionScope = *it; + for (std::list::const_iterator var = unionScope.varlist.begin(); var != unionScope.varlist.end(); ++var) { + if (var->type() && var->type()->classScope == scope) { + usedInUnion = true; + break; + } + } + } + // There are no constructors. - if (scope->numConstructors == 0 && printStyle) { + if (scope->numConstructors == 0 && printStyle && !usedInUnion) { // If there is a private variable, there should be a constructor.. std::list::const_iterator var; for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) { diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 695030d88..d7bcdb7b1 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -75,6 +75,7 @@ private: TEST_CASE(noConstructor8); // ticket #4404 TEST_CASE(noConstructor9); // ticket #4419 TEST_CASE(noConstructor10); // ticket #6614 + TEST_CASE(noConstructor11); // ticket #3552 TEST_CASE(forwardDeclaration); // ticket #4290/#3190 @@ -561,6 +562,12 @@ private: ASSERT_EQUALS("", errout.str()); } + void noConstructor11() { // #3552 + check("class Fred { int x; };\n" + "union U { int y; Fred fred; };"); + ASSERT_EQUALS("", errout.str()); + } + // ticket #4290 "False Positive: style (noConstructor): The class 'foo' does not have a constructor." // ticket #3190 "SymbolDatabase: Parse of sub class constructor fails" void forwardDeclaration() {