[clang-tools-extra] r290202 - [clang-tidy] Add modernize-use-default-member-init check

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 20 14:32:08 PST 2016


On Tue, Dec 20, 2016 at 4:26 PM, Malcolm Parsons via cfe-commits
<cfe-commits at lists.llvm.org> wrote:
> Author: malcolm.parsons
> Date: Tue Dec 20 15:26:07 2016
> New Revision: 290202
>
> URL: http://llvm.org/viewvc/llvm-project?rev=290202&view=rev
> Log:
> [clang-tidy] Add modernize-use-default-member-init check
>
> Summary: Fixes PR18858

This appears to have broken one of the bots:

http://bb.pgr.jp/builders/ninja-x64-msvc-RA-centos6/builds/33046

~Aaron

>
> Reviewers: alexfh, hokein, aaron.ballman
>
> Subscribers: JDevlieghere, Eugene.Zelenko, Prazek, mgorny, cfe-commits, modocache
>
> Differential Revision: https://reviews.llvm.org/D26750
>
> Added:
>     clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp
>     clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultMemberInitCheck.h
>     clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default-member-init.rst
>     clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-member-init-assignment.cpp
>     clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-member-init.cpp
> Modified:
>     clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt
>     clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp
>     clang-tools-extra/trunk/docs/ReleaseNotes.rst
>     clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
>
> Modified: clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt?rev=290202&r1=290201&r2=290202&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt (original)
> +++ clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt Tue Dec 20 15:26:07 2016
> @@ -16,6 +16,7 @@ add_clang_library(clangTidyModernizeModu
>    ShrinkToFitCheck.cpp
>    UseAutoCheck.cpp
>    UseBoolLiteralsCheck.cpp
> +  UseDefaultMemberInitCheck.cpp
>    UseEmplaceCheck.cpp
>    UseEqualsDefaultCheck.cpp
>    UseEqualsDeleteCheck.cpp
>
> Modified: clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp?rev=290202&r1=290201&r2=290202&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp (original)
> +++ clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp Tue Dec 20 15:26:07 2016
> @@ -22,6 +22,7 @@
>  #include "ShrinkToFitCheck.h"
>  #include "UseAutoCheck.h"
>  #include "UseBoolLiteralsCheck.h"
> +#include "UseDefaultMemberInitCheck.h"
>  #include "UseEmplaceCheck.h"
>  #include "UseEqualsDefaultCheck.h"
>  #include "UseEqualsDeleteCheck.h"
> @@ -56,6 +57,8 @@ public:
>      CheckFactories.registerCheck<UseAutoCheck>("modernize-use-auto");
>      CheckFactories.registerCheck<UseBoolLiteralsCheck>(
>          "modernize-use-bool-literals");
> +    CheckFactories.registerCheck<UseDefaultMemberInitCheck>(
> +        "modernize-use-default-member-init");
>      CheckFactories.registerCheck<UseEmplaceCheck>("modernize-use-emplace");
>      CheckFactories.registerCheck<UseEqualsDefaultCheck>("modernize-use-equals-default");
>      CheckFactories.registerCheck<UseEqualsDeleteCheck>(
>
> Added: clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp?rev=290202&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp (added)
> +++ clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp Tue Dec 20 15:26:07 2016
> @@ -0,0 +1,241 @@
> +//===--- UseDefaultMemberInitCheck.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 "UseDefaultMemberInitCheck.h"
> +#include "clang/AST/ASTContext.h"
> +#include "clang/ASTMatchers/ASTMatchFinder.h"
> +#include "clang/Lex/Lexer.h"
> +
> +using namespace clang::ast_matchers;
> +
> +namespace clang {
> +namespace tidy {
> +namespace modernize {
> +
> +static StringRef getValueOfValueInit(const QualType InitType) {
> +  switch (InitType->getScalarTypeKind()) {
> +  case Type::STK_CPointer:
> +  case Type::STK_BlockPointer:
> +  case Type::STK_ObjCObjectPointer:
> +  case Type::STK_MemberPointer:
> +    return "nullptr";
> +
> +  case Type::STK_Bool:
> +    return "false";
> +
> +  case Type::STK_Integral:
> +    switch (InitType->getAs<BuiltinType>()->getKind()) {
> +    case BuiltinType::Char_U:
> +    case BuiltinType::UChar:
> +    case BuiltinType::Char_S:
> +    case BuiltinType::SChar:
> +      return "'\\0'";
> +    case BuiltinType::WChar_U:
> +    case BuiltinType::WChar_S:
> +      return "L'\\0'";
> +    case BuiltinType::Char16:
> +      return "u'\\0'";
> +    case BuiltinType::Char32:
> +      return "U'\\0'";
> +    default:
> +      return "0";
> +    }
> +
> +  case Type::STK_Floating:
> +    switch (InitType->getAs<BuiltinType>()->getKind()) {
> +    case BuiltinType::Half:
> +    case BuiltinType::Float:
> +      return "0.0f";
> +    default:
> +      return "0.0";
> +    }
> +
> +  case Type::STK_FloatingComplex:
> +  case Type::STK_IntegralComplex:
> +    return getValueOfValueInit(
> +        InitType->getAs<ComplexType>()->getElementType());
> +  }
> +  llvm_unreachable("Invalid scalar type kind");
> +}
> +
> +static bool isZero(const Expr *E) {
> +  switch (E->getStmtClass()) {
> +  case Stmt::CXXNullPtrLiteralExprClass:
> +  case Stmt::ImplicitValueInitExprClass:
> +    return true;
> +  case Stmt::InitListExprClass:
> +    return cast<InitListExpr>(E)->getNumInits() == 0;
> +  case Stmt::CharacterLiteralClass:
> +    return !cast<CharacterLiteral>(E)->getValue();
> +  case Stmt::CXXBoolLiteralExprClass:
> +    return !cast<CXXBoolLiteralExpr>(E)->getValue();
> +  case Stmt::IntegerLiteralClass:
> +    return !cast<IntegerLiteral>(E)->getValue();
> +  case Stmt::FloatingLiteralClass: {
> +    llvm::APFloat Value = cast<FloatingLiteral>(E)->getValue();
> +    return Value.isZero() && !Value.isNegative();
> +  }
> +  default:
> +    return false;
> +  }
> +}
> +
> +static const Expr *ignoreUnaryPlus(const Expr *E) {
> +  auto *UnaryOp = dyn_cast<UnaryOperator>(E);
> +  if (UnaryOp && UnaryOp->getOpcode() == UO_Plus)
> +    return UnaryOp->getSubExpr();
> +  return E;
> +}
> +
> +static const Expr *getInitializer(const Expr *E) {
> +  auto *InitList = dyn_cast<InitListExpr>(E);
> +  if (InitList && InitList->getNumInits() == 1)
> +    return InitList->getInit(0);
> +  return E;
> +}
> +
> +static bool sameValue(const Expr *E1, const Expr *E2) {
> +  E1 = ignoreUnaryPlus(getInitializer(E1->IgnoreParenImpCasts()));
> +  E2 = ignoreUnaryPlus(getInitializer(E2->IgnoreParenImpCasts()));
> +
> +  if (isZero(E1) && isZero(E2))
> +    return true;
> +
> +  if (E1->getStmtClass() != E2->getStmtClass())
> +    return false;
> +
> +  switch (E1->getStmtClass()) {
> +  case Stmt::UnaryOperatorClass:
> +    return sameValue(cast<UnaryOperator>(E1)->getSubExpr(),
> +                     cast<UnaryOperator>(E2)->getSubExpr());
> +  case Stmt::CharacterLiteralClass:
> +    return cast<CharacterLiteral>(E1)->getValue() ==
> +           cast<CharacterLiteral>(E2)->getValue();
> +  case Stmt::CXXBoolLiteralExprClass:
> +    return cast<CXXBoolLiteralExpr>(E1)->getValue() ==
> +           cast<CXXBoolLiteralExpr>(E2)->getValue();
> +  case Stmt::IntegerLiteralClass:
> +    return cast<IntegerLiteral>(E1)->getValue() ==
> +           cast<IntegerLiteral>(E2)->getValue();
> +  case Stmt::FloatingLiteralClass:
> +    return cast<FloatingLiteral>(E1)->getValue().bitwiseIsEqual(
> +        cast<FloatingLiteral>(E2)->getValue());
> +  case Stmt::StringLiteralClass:
> +    return cast<StringLiteral>(E1)->getString() ==
> +           cast<StringLiteral>(E2)->getString();
> +  case Stmt::DeclRefExprClass:
> +    return cast<DeclRefExpr>(E1)->getDecl() == cast<DeclRefExpr>(E2)->getDecl();
> +  default:
> +    return false;
> +  }
> +}
> +
> +UseDefaultMemberInitCheck::UseDefaultMemberInitCheck(StringRef Name,
> +                                                     ClangTidyContext *Context)
> +    : ClangTidyCheck(Name, Context),
> +      UseAssignment(Options.get("UseAssignment", 0) != 0) {}
> +
> +void UseDefaultMemberInitCheck::storeOptions(
> +    ClangTidyOptions::OptionMap &Opts) {
> +  Options.store(Opts, "UseAssignment", UseAssignment);
> +}
> +
> +AST_MATCHER(FieldDecl, hasInClassInitializer) {
> +  return Node.hasInClassInitializer();
> +}
> +
> +void UseDefaultMemberInitCheck::registerMatchers(MatchFinder *Finder) {
> +  if (!getLangOpts().CPlusPlus11)
> +    return;
> +
> +  auto Init =
> +      anyOf(stringLiteral(), characterLiteral(), integerLiteral(),
> +            unaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("-")),
> +                          hasUnaryOperand(integerLiteral())),
> +            floatLiteral(),
> +            unaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("-")),
> +                          hasUnaryOperand(floatLiteral())),
> +            cxxBoolLiteral(), cxxNullPtrLiteralExpr(), implicitValueInitExpr(),
> +            declRefExpr());
> +
> +  Finder->addMatcher(
> +      cxxConstructorDecl(
> +          isDefaultConstructor(), unless(isInstantiated()),
> +          forEachConstructorInitializer(allOf(
> +              forField(unless(anyOf(isBitField(), hasInClassInitializer()))),
> +              cxxCtorInitializer(isWritten(),
> +                                 withInitializer(ignoringImplicit(Init)))
> +                  .bind("default")))),
> +      this);
> +
> +  Finder->addMatcher(
> +      cxxConstructorDecl(
> +          unless(ast_matchers::isTemplateInstantiation()),
> +          forEachConstructorInitializer(
> +              allOf(forField(hasInClassInitializer()),
> +                    cxxCtorInitializer(isWritten(),
> +                                       withInitializer(ignoringImplicit(Init)))
> +                        .bind("existing")))),
> +      this);
> +}
> +
> +void UseDefaultMemberInitCheck::check(const MatchFinder::MatchResult &Result) {
> +  if (const auto *Default =
> +          Result.Nodes.getNodeAs<CXXCtorInitializer>("default"))
> +    checkDefaultInit(Result, Default);
> +  else if (const auto *Existing =
> +               Result.Nodes.getNodeAs<CXXCtorInitializer>("existing"))
> +    checkExistingInit(Result, Existing);
> +  else
> +    llvm_unreachable("Bad Callback. No node provided.");
> +}
> +
> +void UseDefaultMemberInitCheck::checkDefaultInit(
> +    const MatchFinder::MatchResult &Result, const CXXCtorInitializer *Init) {
> +  const FieldDecl *Field = Init->getMember();
> +
> +  SourceLocation FieldEnd =
> +      Lexer::getLocForEndOfToken(Field->getSourceRange().getEnd(), 0,
> +                                 *Result.SourceManager, getLangOpts());
> +  SourceLocation LParenEnd = Lexer::getLocForEndOfToken(
> +      Init->getLParenLoc(), 0, *Result.SourceManager, getLangOpts());
> +  CharSourceRange InitRange =
> +      CharSourceRange::getCharRange(LParenEnd, Init->getRParenLoc());
> +
> +  auto Diag =
> +      diag(Field->getLocation(), "use default member initializer for %0")
> +      << Field
> +      << FixItHint::CreateInsertion(FieldEnd, UseAssignment ? " = " : "{")
> +      << FixItHint::CreateInsertionFromRange(FieldEnd, InitRange);
> +
> +  if (UseAssignment && isa<ImplicitValueInitExpr>(Init->getInit()))
> +    Diag << FixItHint::CreateInsertion(
> +        FieldEnd, getValueOfValueInit(Init->getInit()->getType()));
> +
> +  if (!UseAssignment)
> +    Diag << FixItHint::CreateInsertion(FieldEnd, "}");
> +
> +  Diag << FixItHint::CreateRemoval(Init->getSourceRange());
> +}
> +
> +void UseDefaultMemberInitCheck::checkExistingInit(
> +    const MatchFinder::MatchResult &Result, const CXXCtorInitializer *Init) {
> +  const FieldDecl *Field = Init->getMember();
> +
> +  if (!sameValue(Field->getInClassInitializer(), Init->getInit()))
> +    return;
> +
> +  diag(Init->getSourceLocation(), "member initializer for %0 is redundant")
> +      << Field
> +      << FixItHint::CreateRemoval(Init->getSourceRange());
> +}
> +
> +} // namespace modernize
> +} // namespace tidy
> +} // namespace clang
>
> Added: clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultMemberInitCheck.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultMemberInitCheck.h?rev=290202&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultMemberInitCheck.h (added)
> +++ clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultMemberInitCheck.h Tue Dec 20 15:26:07 2016
> @@ -0,0 +1,45 @@
> +//===--- UseDefaultMemberInitCheck.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_MODERNIZE_USE_DEFAULT_MEMBER_INIT_H
> +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_DEFAULT_MEMBER_INIT_H
> +
> +#include "../ClangTidy.h"
> +
> +namespace clang {
> +namespace tidy {
> +namespace modernize {
> +
> +/// Convert a default constructor's member initializers into default member
> +/// initializers.  Remove member initializers that are the same as a default
> +/// member initializer.
> +///
> +/// For the user-facing documentation see:
> +/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-default-member-init.html
> +class UseDefaultMemberInitCheck : public ClangTidyCheck {
> +public:
> +  UseDefaultMemberInitCheck(StringRef Name, ClangTidyContext *Context);
> +  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
> +  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
> +  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
> +
> +private:
> +  void checkDefaultInit(const ast_matchers::MatchFinder::MatchResult &Result,
> +                        const CXXCtorInitializer *Init);
> +  void checkExistingInit(const ast_matchers::MatchFinder::MatchResult &Result,
> +                         const CXXCtorInitializer *Init);
> +
> +  const bool UseAssignment;
> +};
> +
> +} // namespace modernize
> +} // namespace tidy
> +} // namespace clang
> +
> +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_DEFAULT_MEMBER_INIT_H
>
> Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=290202&r1=290201&r2=290202&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
> +++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Tue Dec 20 15:26:07 2016
> @@ -108,6 +108,12 @@ Improvements to clang-tidy
>
>  - The modernize-use-default check has been renamed to `modernize-use-equals-default
>    <http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-equals-default.html>`_.
> +
> +- New `modernize-use-default-member-init
> +  <http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-default-member-init.html>`_ check
> +
> +  Converts a default constructor's member initializers into default member initializers.
> +  Removes member initializers that are the same as a default member initializer.
>
>  - New `modernize-use-equals-delete
>    <http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-equals-delete.html>`_ check
>
> Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=290202&r1=290201&r2=290202&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
> +++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Tue Dec 20 15:26:07 2016
> @@ -110,6 +110,7 @@ Clang-Tidy Checks
>     modernize-shrink-to-fit
>     modernize-use-auto
>     modernize-use-bool-literals
> +   modernize-use-default-member-init
>     modernize-use-emplace
>     modernize-use-equals-default
>     modernize-use-equals-delete
>
> Added: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default-member-init.rst
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default-member-init.rst?rev=290202&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default-member-init.rst (added)
> +++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default-member-init.rst Tue Dec 20 15:26:07 2016
> @@ -0,0 +1,49 @@
> +.. title:: clang-tidy - modernize-use-default-member-init
> +
> +modernize-use-default-member-init
> +=================================
> +
> +This check converts a default constructor's member initializers into the new
> +default member initializers in C++11. Other member initializers that match the
> +default member initializer are removed. This can reduce repeated code or allow
> +use of '= default'.
> +
> +.. code-block:: c++
> +
> +  struct A {
> +    A() : i(5), j(10.0) {}
> +    A(int i) : i(i), j(10.0) {}
> +    int i;
> +    double j;
> +  };
> +
> +  // becomes
> +
> +  struct A {
> +    A() {}
> +    A(int i) : i(i) {}
> +    int i{5};
> +    double j{10.0};
> +  };
> +
> +.. note::
> +  Only converts member initializers for built-in types, enums, and pointers.
> +  The `readability-redundant-member-init` check will remove redundant member
> +  initializers for classes.
> +
> +Options
> +-------
> +
> +.. option:: UseAssignment
> +
> +   If this option is set to non-zero (default is `0`), the check will initialise
> +   members with an assignment. For example:
> +
> +.. code-block:: c++
> +
> +  struct A {
> +    A() {}
> +    A(int i) : i(i) {}
> +    int i = 5;
> +    double j = 10.0;
> +  };
>
> Added: clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-member-init-assignment.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-member-init-assignment.cpp?rev=290202&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-member-init-assignment.cpp (added)
> +++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-member-init-assignment.cpp Tue Dec 20 15:26:07 2016
> @@ -0,0 +1,184 @@
> +// RUN: %check_clang_tidy %s modernize-use-default-member-init %t -- \
> +// RUN: -config="{CheckOptions: [{key: modernize-use-default-member-init.UseAssignment, value: 1}]}" -- -std=c++11
> +
> +struct S {
> +};
> +
> +struct PositiveValueChar {
> +  PositiveValueChar() : c0(), c1(), c2(), c3() {}
> +  // CHECK-FIXES: PositiveValueChar()  {}
> +  const char c0;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use default member initializer for 'c0' [modernize-use-default-member-init]
> +  // CHECK-FIXES: const char c0 = '\0';
> +  wchar_t c1;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use default member initializer for 'c1'
> +  // CHECK-FIXES: wchar_t c1 = L'\0';
> +  char16_t c2;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use default member initializer for 'c2'
> +  // CHECK-FIXES: char16_t c2 = u'\0';
> +  char32_t c3;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use default member initializer for 'c3'
> +  // CHECK-FIXES: char32_t c3 = U'\0';
> +};
> +
> +struct PositiveChar {
> +  PositiveChar() : d('a') {}
> +  // CHECK-FIXES: PositiveChar()  {}
> +  char d;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'd'
> +  // CHECK-FIXES: char d = 'a';
> +};
> +
> +struct PositiveValueInt {
> +  PositiveValueInt() : i() {}
> +  // CHECK-FIXES: PositiveValueInt()  {}
> +  const int i;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use default member initializer for 'i'
> +  // CHECK-FIXES: const int i = 0;
> +};
> +
> +struct PositiveInt {
> +  PositiveInt() : j(1) {}
> +  // CHECK-FIXES: PositiveInt()  {}
> +  int j;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j'
> +  // CHECK-FIXES: int j = 1;
> +};
> +
> +struct PositiveUnaryMinusInt {
> +  PositiveUnaryMinusInt() : j(-1) {}
> +  // CHECK-FIXES: PositiveUnaryMinusInt()  {}
> +  int j;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j'
> +  // CHECK-FIXES: int j = -1;
> +};
> +
> +struct PositiveUnaryPlusInt {
> +  PositiveUnaryPlusInt() : j(+1) {}
> +  // CHECK-FIXES: PositiveUnaryPlusInt()  {}
> +  int j;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j'
> +  // CHECK-FIXES: int j = +1;
> +};
> +
> +struct PositiveValueComplexInt {
> +  PositiveValueComplexInt() : i() {}
> +  // CHECK-FIXES: PositiveValueComplexInt()  {}
> +  _Complex int i;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use default member initializer for 'i'
> +  // CHECK-FIXES: _Complex int i = 0;
> +};
> +
> +struct PositiveValueFloat {
> +  PositiveValueFloat() : f() {}
> +  // CHECK-FIXES: PositiveValueFloat()  {}
> +  float f;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use default member initializer for 'f'
> +  // CHECK-FIXES: float f = 0.0f;
> +};
> +
> +struct PositiveValueDouble {
> +  PositiveValueDouble() : d() {}
> +  // CHECK-FIXES: PositiveValueDouble()  {}
> +  double d;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'd'
> +  // CHECK-FIXES: double d = 0.0;
> +};
> +
> +struct PositiveDouble {
> +  PositiveDouble() : f(2.5463e43) {}
> +  // CHECK-FIXES: PositiveDouble()  {}
> +  double f;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f'
> +  // CHECK-FIXES: double f = 2.5463e43;
> +};
> +
> +struct PositiveValueComplexFloat {
> +  PositiveValueComplexFloat() : f() {}
> +  // CHECK-FIXES: PositiveValueComplexFloat()  {}
> +  _Complex float f;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use default member initializer for 'f'
> +  // CHECK-FIXES: _Complex float f = 0.0f;
> +};
> +
> +struct PositiveValueComplexDouble {
> +  PositiveValueComplexDouble() : f() {}
> +  // CHECK-FIXES: PositiveValueComplexDouble()  {}
> +  _Complex double f;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use default member initializer for 'f'
> +  // CHECK-FIXES: _Complex double f = 0.0;
> +};
> +
> +struct PositiveUnaryMinusDouble {
> +  PositiveUnaryMinusDouble() : f(-2.5463e43) {}
> +  // CHECK-FIXES: PositiveUnaryMinusDouble()  {}
> +  double f;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f'
> +  // CHECK-FIXES: double f = -2.5463e43;
> +};
> +
> +struct PositiveUnaryPlusDouble {
> +  PositiveUnaryPlusDouble() : f(+2.5463e43) {}
> +  // CHECK-FIXES: PositiveUnaryPlusDouble()  {}
> +  double f;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f'
> +  // CHECK-FIXES: double f = +2.5463e43;
> +};
> +
> +struct PositiveValueBool {
> +  PositiveValueBool() : b() {}
> +  // CHECK-FIXES: PositiveValueBool()  {}
> +  bool b;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'b'
> +  // CHECK-FIXES: bool b = false;
> +};
> +
> +struct PositiveBool {
> +  PositiveBool() : a(true) {}
> +  // CHECK-FIXES: PositiveBool()  {}
> +  bool a;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'a'
> +  // CHECK-FIXES: bool a = true;
> +};
> +
> +struct PositiveValuePointer {
> +  PositiveValuePointer() : p() {}
> +  // CHECK-FIXES: PositiveValuePointer()  {}
> +  int *p;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'p'
> +  // CHECK-FIXES: int *p = nullptr;
> +};
> +
> +struct PositiveNullPointer {
> +  PositiveNullPointer() : q(nullptr) {}
> +  // CHECK-FIXES: PositiveNullPointer()  {}
> +  int *q;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'q'
> +  // CHECK-FIXES: int *q = nullptr;
> +};
> +
> +enum Enum { Foo };
> +struct PositiveEnum {
> +  PositiveEnum() : e(Foo) {}
> +  // CHECK-FIXES: PositiveEnum()  {}
> +  Enum e;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e'
> +  // CHECK-FIXES: Enum e = Foo;
> +};
> +
> +struct PositiveString {
> +  PositiveString() : s("foo") {}
> +  // CHECK-FIXES: PositiveString()  {}
> +  const char *s;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use default member initializer for 's'
> +  // CHECK-FIXES: const char *s = "foo";
> +};
> +
> +template <typename T>
> +struct NegativeTemplate {
> +    NegativeTemplate() : t() {}
> +    T t;
> +};
> +
> +NegativeTemplate<int> nti;
> +NegativeTemplate<double> ntd;
>
> Added: clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-member-init.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-member-init.cpp?rev=290202&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-member-init.cpp (added)
> +++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-member-init.cpp Tue Dec 20 15:26:07 2016
> @@ -0,0 +1,376 @@
> +// RUN: %check_clang_tidy %s modernize-use-default-member-init %t -- -- -std=c++11
> +
> +struct S {
> +};
> +
> +struct PositiveValueChar {
> +  PositiveValueChar() : c0(), c1(), c2(), c3() {}
> +  // CHECK-FIXES: PositiveValueChar()  {}
> +  const char c0;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use default member initializer for 'c0' [modernize-use-default-member-init]
> +  // CHECK-FIXES: const char c0{};
> +  wchar_t c1;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use default member initializer for 'c1'
> +  // CHECK-FIXES: wchar_t c1{};
> +  char16_t c2;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use default member initializer for 'c2'
> +  // CHECK-FIXES: char16_t c2{};
> +  char32_t c3;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use default member initializer for 'c3'
> +  // CHECK-FIXES: char32_t c3{};
> +};
> +
> +struct PositiveChar {
> +  PositiveChar() : d('a') {}
> +  // CHECK-FIXES: PositiveChar()  {}
> +  char d;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'd'
> +  // CHECK-FIXES: char d{'a'};
> +};
> +
> +struct PositiveValueInt {
> +  PositiveValueInt() : i() {}
> +  // CHECK-FIXES: PositiveValueInt()  {}
> +  const int i;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use default member initializer for 'i'
> +  // CHECK-FIXES: const int i{};
> +};
> +
> +struct PositiveInt {
> +  PositiveInt() : j(1) {}
> +  // CHECK-FIXES: PositiveInt()  {}
> +  int j;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j'
> +  // CHECK-FIXES: int j{1};
> +};
> +
> +struct PositiveUnaryMinusInt {
> +  PositiveUnaryMinusInt() : j(-1) {}
> +  // CHECK-FIXES: PositiveUnaryMinusInt()  {}
> +  int j;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j'
> +  // CHECK-FIXES: int j{-1};
> +};
> +
> +struct PositiveUnaryPlusInt {
> +  PositiveUnaryPlusInt() : j(+1) {}
> +  // CHECK-FIXES: PositiveUnaryPlusInt()  {}
> +  int j;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j'
> +  // CHECK-FIXES: int j{+1};
> +};
> +
> +struct PositiveValueComplexInt {
> +  PositiveValueComplexInt() : i() {}
> +  // CHECK-FIXES: PositiveValueComplexInt()  {}
> +  _Complex int i;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use default member initializer for 'i'
> +  // CHECK-FIXES: _Complex int i{};
> +};
> +
> +struct PositiveValueFloat {
> +  PositiveValueFloat() : f() {}
> +  // CHECK-FIXES: PositiveValueFloat()  {}
> +  float f;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use default member initializer for 'f'
> +  // CHECK-FIXES: float f{};
> +};
> +
> +struct PositiveValueDouble {
> +  PositiveValueDouble() : d() {}
> +  // CHECK-FIXES: PositiveValueDouble()  {}
> +  double d;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'd'
> +  // CHECK-FIXES: double d{};
> +};
> +
> +struct PositiveDouble {
> +  PositiveDouble() : f(2.5463e43) {}
> +  // CHECK-FIXES: PositiveDouble()  {}
> +  double f;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f'
> +  // CHECK-FIXES: double f{2.5463e43};
> +};
> +
> +struct PositiveValueComplexFloat {
> +  PositiveValueComplexFloat() : f() {}
> +  // CHECK-FIXES: PositiveValueComplexFloat()  {}
> +  _Complex float f;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use default member initializer for 'f'
> +  // CHECK-FIXES: _Complex float f{};
> +};
> +
> +struct PositiveValueComplexDouble {
> +  PositiveValueComplexDouble() : f() {}
> +  // CHECK-FIXES: PositiveValueComplexDouble()  {}
> +  _Complex double f;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use default member initializer for 'f'
> +  // CHECK-FIXES: _Complex double f{};
> +};
> +
> +struct PositiveUnaryMinusDouble {
> +  PositiveUnaryMinusDouble() : f(-2.5463e43) {}
> +  // CHECK-FIXES: PositiveUnaryMinusDouble()  {}
> +  double f;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f'
> +  // CHECK-FIXES: double f{-2.5463e43};
> +};
> +
> +struct PositiveUnaryPlusDouble {
> +  PositiveUnaryPlusDouble() : f(+2.5463e43) {}
> +  // CHECK-FIXES: PositiveUnaryPlusDouble()  {}
> +  double f;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f'
> +  // CHECK-FIXES: double f{+2.5463e43};
> +};
> +
> +struct PositiveValueBool {
> +  PositiveValueBool() : b() {}
> +  // CHECK-FIXES: PositiveValueBool()  {}
> +  bool b;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'b'
> +  // CHECK-FIXES: bool b{};
> +};
> +
> +struct PositiveBool {
> +  PositiveBool() : a(true) {}
> +  // CHECK-FIXES: PositiveBool()  {}
> +  bool a;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'a'
> +  // CHECK-FIXES: bool a{true};
> +};
> +
> +struct PositiveValuePointer {
> +  PositiveValuePointer() : p() {}
> +  // CHECK-FIXES: PositiveValuePointer()  {}
> +  int *p;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'p'
> +  // CHECK-FIXES: int *p{};
> +};
> +
> +struct PositiveNullPointer {
> +  PositiveNullPointer() : q(nullptr) {}
> +  // CHECK-FIXES: PositiveNullPointer()  {}
> +  int *q;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'q'
> +  // CHECK-FIXES: int *q{nullptr};
> +};
> +
> +enum Enum { Foo, Bar };
> +struct PositiveEnum {
> +  PositiveEnum() : e(Foo) {}
> +  // CHECK-FIXES: PositiveEnum()  {}
> +  Enum e;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e'
> +  // CHECK-FIXES: Enum e{Foo};
> +};
> +
> +struct PositiveString {
> +  PositiveString() : s("foo") {}
> +  // CHECK-FIXES: PositiveString()  {}
> +  const char *s;
> +  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use default member initializer for 's'
> +  // CHECK-FIXES: const char *s{"foo"};
> +};
> +
> +template <typename T>
> +struct NegativeTemplate {
> +    NegativeTemplate() : t() {}
> +    T t;
> +};
> +
> +NegativeTemplate<int> nti;
> +NegativeTemplate<double> ntd;
> +
> +struct NegativeDefaultMember {
> +  NegativeDefaultMember() {}
> +  int i = 2;
> +};
> +
> +struct NegativeClass : S {
> +  NegativeClass() : s() {}
> +  S s;
> +};
> +
> +struct NegativeBase : S {
> +  NegativeBase() : S() {}
> +};
> +
> +struct NegativeDefaultOtherMember{
> +  NegativeDefaultOtherMember() : i(3) {}
> +  int i = 4;
> +};
> +
> +struct NegativeUnion {
> +  NegativeUnion() : d(5.0) {}
> +  union {
> +    int i;
> +    double d;
> +  };
> +};
> +
> +struct NegativeBitField
> +{
> +  NegativeBitField() : i(6) {}
> +  int i : 5;
> +};
> +
> +struct NegativeNotDefaultInt
> +{
> +  NegativeNotDefaultInt(int) : i(7) {}
> +  int i;
> +};
> +
> +struct ExistingChar {
> +  ExistingChar(short) : e1(), e2(), e3(), e4() {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant [modernize-use-default-member-init]
> +  // CHECK-MESSAGES: :[[@LINE-2]]:31: warning: member initializer for 'e2' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-3]]:37: warning: member initializer for 'e3' is redundant
> +  // CHECK-FIXES: ExistingChar(short) :  e4() {}
> +  ExistingChar(int) : e1(0), e2(0), e3(0), e4(0) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: member initializer for 'e1' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:30: warning: member initializer for 'e2' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-3]]:37: warning: member initializer for 'e3' is redundant
> +  // CHECK-FIXES: ExistingChar(int) :  e4(0) {}
> +  ExistingChar(long) : e1('\0'), e2('\0'), e3('\0'), e4('\0') {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: member initializer for 'e1' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: member initializer for 'e2' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-3]]:44: warning: member initializer for 'e3' is redundant
> +  // CHECK-FIXES: ExistingChar(long) :  e4('\0') {}
> +  ExistingChar(char) : e1('a'), e2('a'), e3('a'), e4('a') {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:51: warning: member initializer for 'e4' is redundant
> +  // CHECK-FIXES: ExistingChar(char) : e1('a'), e2('a'), e3('a') {}
> +  char e1{};
> +  char e2 = 0;
> +  char e3 = '\0';
> +  char e4 = 'a';
> +};
> +
> +struct ExistingInt {
> +  ExistingInt(short) : e1(), e2(), e3(), e4(), e5(), e6() {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: member initializer for 'e1' is redundant [modernize-use-default-member-init]
> +  // CHECK-MESSAGES: :[[@LINE-2]]:30: warning: member initializer for 'e2' is redundant
> +  // CHECK-FIXES: ExistingInt(short) :  e3(), e4(), e5(), e6() {}
> +  ExistingInt(int) : e1(0), e2(0), e3(0), e4(0), e5(0), e6(0) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: member initializer for 'e1' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:29: warning: member initializer for 'e2' is redundant
> +  // CHECK-FIXES: ExistingInt(int) :  e3(0), e4(0), e5(0), e6(0) {}
> +  ExistingInt(long) : e1(5), e2(5), e3(5), e4(5), e5(5), e6(5) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: member initializer for 'e3' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:44: warning: member initializer for 'e4' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-3]]:58: warning: member initializer for 'e6' is redundant
> +  // CHECK-FIXES: ExistingInt(long) : e1(5), e2(5),  e5(5) {}
> +  ExistingInt(char) : e1(-5), e2(-5), e3(-5), e4(-5), e5(-5), e6(-5) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:55: warning: member initializer for 'e5' is redundant
> +  // CHECK-FIXES: ExistingInt(char) : e1(-5), e2(-5), e3(-5), e4(-5),  e6(-5) {}
> +  int e1{};
> +  int e2 = 0;
> +  int e3 = {5};
> +  int e4 = 5;
> +  int e5 = -5;
> +  int e6 = +5;
> +};
> +
> +struct ExistingDouble {
> +  ExistingDouble(short) : e1(), e2(), e3(), e4(), e5() {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: member initializer for 'e1' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: member initializer for 'e2' is redundant
> +  // CHECK-FIXES: ExistingDouble(short) :  e3(), e4(), e5() {}
> +  ExistingDouble(int) : e1(0.0), e2(0.0), e3(0.0), e4(0.0), e5(0.0) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: member initializer for 'e2' is redundant
> +  // CHECK-FIXES: ExistingDouble(int) :  e3(0.0), e4(0.0), e5(0.0) {}
> +  ExistingDouble(long) : e1(5.0), e2(5.0), e3(5.0), e4(5.0), e5(5.0) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: member initializer for 'e3' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:62: warning: member initializer for 'e5' is redundant
> +  // CHECK-FIXES: ExistingDouble(long) : e1(5.0), e2(5.0),  e4(5.0) {}
> +  ExistingDouble(char) : e1(-5.0), e2(-5.0), e3(-5.0), e4(-5.0), e5(-5.0) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: member initializer for 'e4' is redundant
> +  // CHECK-FIXES: ExistingDouble(char) : e1(-5.0), e2(-5.0), e3(-5.0),  e5(-5.0) {}
> +  double e1{};
> +  double e2 = 0.0;
> +  double e3 = 5.0;
> +  double e4 = -5.0;
> +  double e5 = +5.0;
> +};
> +
> +struct ExistingBool {
> +  ExistingBool(short) : e1(), e2(), e3() {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:31: warning: member initializer for 'e2' is redundant
> +  // CHECK-FIXES: ExistingBool(short) :  e3() {}
> +  ExistingBool(int) : e1(false), e2(false), e3(false) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: member initializer for 'e1' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: member initializer for 'e2' is redundant
> +  // CHECK-FIXES: ExistingBool(int) :  e3(false) {}
> +  ExistingBool(long) : e1(true), e2(true), e3(true) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: member initializer for 'e3' is redundant
> +  // CHECK-FIXES: ExistingBool(long) : e1(true), e2(true) {}
> +  bool e1{};
> +  bool e2 = false;
> +  bool e3 = true;
> +};
> +
> +struct ExistingEnum {
> +  ExistingEnum(short) : e1(Foo), e2(Foo) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant
> +  // CHECK-FIXES: ExistingEnum(short) :  e2(Foo) {}
> +  ExistingEnum(int) : e1(Bar), e2(Bar) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: member initializer for 'e2' is redundant
> +  // CHECK-FIXES: ExistingEnum(int) : e1(Bar) {}
> +  Enum e1 = Foo;
> +  Enum e2{Bar};
> +};
> +
> +struct ExistingPointer {
> +  ExistingPointer(short) : e1(), e2(), e3(), e4() {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: member initializer for 'e1' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: member initializer for 'e2' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-3]]:40: warning: member initializer for 'e3' is redundant
> +  // CHECK-FIXES: ExistingPointer(short) :  e4() {}
> +  ExistingPointer(int) : e1(0), e2(0), e3(0), e4(&e1) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: member initializer for 'e1' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: member initializer for 'e2' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-3]]:40: warning: member initializer for 'e3' is redundant
> +  // CHECK-FIXES: ExistingPointer(int) :  e4(&e1) {}
> +  ExistingPointer(long) : e1(nullptr), e2(nullptr), e3(nullptr), e4(&e2) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: member initializer for 'e1' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:40: warning: member initializer for 'e2' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-3]]:53: warning: member initializer for 'e3' is redundant
> +  // CHECK-FIXES: ExistingPointer(long) :  e4(&e2) {}
> +  int *e1{};
> +  int *e2 = 0;
> +  int *e3 = nullptr;
> +  int **e4 = &e1;
> +};
> +
> +struct ExistingString {
> +  ExistingString(short) : e1(), e2(), e3(), e4() {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: member initializer for 'e1' is redundant [modernize-use-default-member-init]
> +  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: member initializer for 'e2' is redundant
> +  // CHECK-FIXES: ExistingString(short) :  e3(), e4() {}
> +  ExistingString(int) : e1(0), e2(0), e3(0), e4(0) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: member initializer for 'e2' is redundant
> +  // CHECK-FIXES: ExistingString(int) :  e3(0), e4(0) {}
> +  ExistingString(long) : e1(nullptr), e2(nullptr), e3(nullptr), e4(nullptr) {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: member initializer for 'e1' is redundant
> +  // CHECK-MESSAGES: :[[@LINE-2]]:39: warning: member initializer for 'e2' is redundant
> +  // CHECK-FIXES: ExistingString(long) :  e3(nullptr), e4(nullptr) {}
> +  ExistingString(char) : e1("foo"), e2("foo"), e3("foo"), e4("foo") {}
> +  // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: member initializer for 'e3' is redundant
> +  // CHECK-FIXES: ExistingString(char) : e1("foo"), e2("foo"),  e4("foo") {}
> +  const char *e1{};
> +  const char *e2 = nullptr;
> +  const char *e3 = "foo";
> +  const char *e4 = "bar";
> +};
> +
> +template <typename T>
> +struct NegativeTemplateExisting {
> +  NegativeTemplateExisting(int) : t(0) {}
> +  T t{};
> +};
> +
> +NegativeTemplateExisting<int> ntei(0);
> +NegativeTemplateExisting<double> nted(0);
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


More information about the cfe-commits mailing list