diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 58f06150a..fd5de98d8 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -377,9 +377,10 @@ void CheckClass::checkExplicitConstructors() if (!func.isExplicit() && func.argCount() > 0 && func.minArgCount() < 2 && - func.argumentList.front().getTypeName() != "std::initializer_list" && func.type != Function::eCopyConstructor && - func.type != Function::eMoveConstructor) { + func.type != Function::eMoveConstructor && + !(func.templateDef && Token::simpleMatch(func.argumentList.front().typeEndToken(), "...")) && + func.argumentList.front().getTypeName() != "std::initializer_list") { noExplicitConstructorError(func.tokenDef, scope->className, scope->type == Scope::eStruct); } } diff --git a/test/testclass.cpp b/test/testclass.cpp index 131fcf868..0db854351 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -493,6 +493,22 @@ private: " std::vector v;\n" "};\n"); ASSERT_EQUALS("", errout.str()); + + checkExplicitConstructors("template\n" // #10977 + "struct A {\n" + " template\n" + " A(Ts&&... ts) {}\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + + checkExplicitConstructors("class Color {\n" // #7176 + "public:\n" + " Color(unsigned int rgba);\n" + " Color(std::uint8_t r = 0, std::uint8_t g = 0, std::uint8_t b = 0, std::uint8_t a = 255);\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3]: (style) Class 'Color' has a constructor with 1 argument that is not explicit.\n" + "[test.cpp:4]: (style) Class 'Color' has a constructor with 1 argument that is not explicit.\n", + errout.str()); } #define checkDuplInheritedMembers(code) checkDuplInheritedMembers_(code, __FILE__, __LINE__) diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index baf8ba5c8..eaaedfbd4 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -550,6 +550,21 @@ private: " S s;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + functionVariableUsage( // #11109 + "class D { public: D(); };\n" + "class E { public: ~E(); };\n" + "class F {\n" + "public:\n" + " F();\n" + " ~F();\n" + "};\n" + "void f() {\n" + " D d;\n" + " E e;\n" + " F f;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void cleanFunction() {