Index: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h =================================================================== --- clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h +++ clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h @@ -63,6 +63,9 @@ // Whether arrays need to be initialized or not. Default is false. bool IgnoreArrays; + // Whether fix-its for initializers of fundamental type use literals. Only + // effective in C++11 mode. Default is false. + bool LiteralInitializers; }; } // namespace cppcoreguidelines Index: clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp =================================================================== --- clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp +++ clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp @@ -251,7 +251,8 @@ ProTypeMemberInitCheck::ProTypeMemberInitCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - IgnoreArrays(Options.get("IgnoreArrays", false)) {} + IgnoreArrays(Options.get("IgnoreArrays", false)), + LiteralInitializers(Options.get("LiteralInitializers", false)) {} void ProTypeMemberInitCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().CPlusPlus) @@ -296,6 +297,7 @@ void ProTypeMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "IgnoreArrays", IgnoreArrays); + Options.store(Opts, "LiteralInitializers", LiteralInitializers); } void ProTypeMemberInitCheck::checkMissingMemberInitializer( @@ -366,9 +368,21 @@ // Use in-class initialization if possible. if (Context.getLangOpts().CPlusPlus11) { for (const FieldDecl *Field : FieldsToFix) { + QualType type = Field->getType(); + const char *Initializer = "{}"; + if (LiteralInitializers) { + if (type->isBooleanType()) + Initializer = " = false"; + else if (type->isIntegerType()) + Initializer = " = 0"; + else if (type->isFloatingType()) + Initializer = " = 0.0"; + else if (type->isPointerType()) + Initializer = " = nullptr"; + } Diag << FixItHint::CreateInsertion( getLocationForEndOfToken(Context, Field->getSourceRange().getEnd()), - "{}"); + Initializer); } } else { // Otherwise, rewrite the constructor's initializer list. Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-member-init.rst =================================================================== --- docs/clang-tidy/checks/cppcoreguidelines-pro-type-member-init.rst +++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-member-init.rst @@ -33,6 +33,10 @@ zero-initialized during construction. For performance critical code, it may be important to not initialize fixed-size array members. Default is `0`. +.. option:: LiteralInitializers + If set to non-zero, the check will provide fix-its with literal initializers + (``int i = 0;``) instead of curly braces (``int i{};``). + This rule is part of the "Type safety" profile of the C++ Core Guidelines, corresponding to rule Type.6. See https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-type-memberinit. Index: test/clang-tidy/cppcoreguidelines-pro-type-member-init-literal-initializers.cpp =================================================================== --- /dev/null +++ test/clang-tidy/cppcoreguidelines-pro-type-member-init-literal-initializers.cpp @@ -0,0 +1,21 @@ +// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init %t -- -config="{CheckOptions: [{key: "cppcoreguidelines-pro-type-member-init.LiteralInitializers", value: 1}]}" -- -std=c++11 + +struct T { + int i; +}; + +struct S { + bool b; + // CHECK-FIXES: bool b = false; + int i; + // CHECK-FIXES: int i = 0; + float f; + // CHECK-FIXES: float f = 0.0; + int* ptr; + // CHECK-FIXES: int* ptr = nullptr; + T t; + // CHECK-FIXES: T t{}; + S() {}; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: +}; +