Index: clang-tidy/readability/CMakeLists.txt =================================================================== --- clang-tidy/readability/CMakeLists.txt +++ clang-tidy/readability/CMakeLists.txt @@ -15,6 +15,7 @@ NonConstParameterCheck.cpp ReadabilityTidyModule.cpp RedundantControlFlowCheck.cpp + RedundantMemberInitCheck.cpp RedundantStringCStrCheck.cpp RedundantSmartptrGetCheck.cpp RedundantStringInitCheck.cpp Index: clang-tidy/readability/ReadabilityTidyModule.cpp =================================================================== --- clang-tidy/readability/ReadabilityTidyModule.cpp +++ clang-tidy/readability/ReadabilityTidyModule.cpp @@ -22,6 +22,7 @@ #include "NamedParameterCheck.h" #include "NonConstParameterCheck.h" #include "RedundantControlFlowCheck.h" +#include "RedundantMemberInitCheck.h" #include "RedundantSmartptrGetCheck.h" #include "RedundantStringCStrCheck.h" #include "RedundantStringInitCheck.h" @@ -54,6 +55,8 @@ "readability-implicit-bool-cast"); CheckFactories.registerCheck( "readability-inconsistent-declaration-parameter-name"); + CheckFactories.registerCheck( + "readability-redundant-member-init"); CheckFactories.registerCheck( "readability-static-definition-in-anonymous-namespace"); CheckFactories.registerCheck( Index: clang-tidy/readability/RedundantMemberInitCheck.h =================================================================== --- /dev/null +++ clang-tidy/readability/RedundantMemberInitCheck.h @@ -0,0 +1,35 @@ +//===--- RedundantMemberInitCheck.h - clang-tidy----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_MEMBER_INIT_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_MEMBER_INIT_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace readability { + +/// Find unnecessary member initializers +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/readability-redundant-member-init.html +class RedundantMemberInitCheck : public ClangTidyCheck { +public: + RedundantMemberInitCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace readability +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_MEMBER_INIT_H Index: clang-tidy/readability/RedundantMemberInitCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/readability/RedundantMemberInitCheck.cpp @@ -0,0 +1,49 @@ +//===--- RedundantMemberInitCheck.cpp - clang-tidy-------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RedundantMemberInitCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace readability { + +void RedundantMemberInitCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxConstructorDecl(forEachConstructorInitializer( + cxxCtorInitializer( + isWritten(), + withInitializer(cxxConstructExpr().bind("construct"))) + .bind("init"))), + this); +} + +void RedundantMemberInitCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Init = Result.Nodes.getNodeAs("init"); + const auto *Construct = Result.Nodes.getNodeAs("construct"); + const auto arguments = Construct->arguments(); + + using std::begin; + using std::end; + + if (std::find_if(begin(arguments), end(arguments), [](const Expr *expr) { + return !expr->isDefaultArgument(); + }) == end(arguments)) { + diag(Init->getSourceLocation(), "initializer for %0 is redundant") + << Init->getMember(); + } +} + +} // namespace readability +} // namespace tidy +} // namespace clang Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -131,6 +131,7 @@ readability-named-parameter readability-non-const-parameter readability-redundant-control-flow + readability-redundant-member-init readability-redundant-smartptr-get readability-redundant-string-cstr readability-redundant-string-init Index: docs/clang-tidy/checks/readability-redundant-member-init.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/readability-redundant-member-init.rst @@ -0,0 +1,18 @@ +.. title:: clang-tidy - readability-redundant-member-init + +readability-redundant-member-init +================================== + +Finds unnecessary member initializations. + +Example: + +.. code-block:: c++ + + // Explicitly initializing the member s is unnecessary. + class Foo { + public: + Foo() : s() {} + private: + std::string s; + }; Index: test/clang-tidy/readability-redundant-member-init.cpp =================================================================== --- /dev/null +++ test/clang-tidy/readability-redundant-member-init.cpp @@ -0,0 +1,57 @@ +// RUN: %check_clang_tidy %s readability-redundant-member-init %t + +struct S { + S() = default; + S(int i) : i(i) {} + int i = 1; +}; + +struct T { + T(int i = 1) : i(i) {} + int i; +}; + +struct F1 { + F1() : f() {} + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for 'f' is redundant [readability-redundant-member-init] + S f; +}; + +struct F2 { + F2() : f() {} + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for 'f' is redundant [readability-redundant-member-init] + T f; +}; + +struct F3 { + F3() : f(), g(1), h() {} + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for 'f' is redundant [readability-redundant-member-init] + // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: initializer for 'h' is redundant [readability-redundant-member-init] + S f, g, h; +}; + + +struct NF1 { + NF1() {} + S f; +}; + +struct NF2 { + NF2() : f(1) {} + S f; +}; + +struct NF3 { + NF3() : f(1) {} + T f; +}; + +struct NF4 { + NF4() : i() {} + int i; +}; + +struct NF5 { + NF5() : i(1) {} + int i; +};