diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 6fd15dafc72..3c461c0ab44 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -319,6 +319,11 @@ void CheckClass::constructors() } } +static bool isPermissibleConversion(const std::string& type) +{ + return type == "std::initializer_list" || type == "std::nullptr_t"; +} + void CheckClass::checkExplicitConstructors() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("noExplicitConstructor")) @@ -357,7 +362,7 @@ void CheckClass::checkExplicitConstructors() func.type != FunctionType::eCopyConstructor && func.type != FunctionType::eMoveConstructor && !(func.templateDef && Token::simpleMatch(func.argumentList.front().typeEndToken(), "...")) && - func.argumentList.front().getTypeName() != "std::initializer_list") { + !isPermissibleConversion(func.argumentList.front().getTypeName())) { noExplicitConstructorError(func.tokenDef, scope->className, scope->type == ScopeType::eStruct); } } diff --git a/test/testclass.cpp b/test/testclass.cpp index 8eeb7eb7696..2f37c579816 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -503,6 +503,14 @@ class TestClass : public TestFixture { ASSERT_EQUALS("[test.cpp:3:5]: (style) Class 'Color' has a constructor with 1 argument that is not explicit. [noExplicitConstructor]\n" "[test.cpp:4:5]: (style) Class 'Color' has a constructor with 1 argument that is not explicit. [noExplicitConstructor]\n", errout_str()); + + checkExplicitConstructors("template \n" // #13878 + "struct S {\n" + " S(std::nullptr_t) {}\n" + " explicit S(T* p) : m(p) {}\n" + " T* m{};\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); } #define checkDuplInheritedMembers(...) checkDuplInheritedMembers_( __FILE__, __LINE__, __VA_ARGS__)