diff --git a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp index 015347ee9294..601ff44cdd10 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp @@ -41,25 +41,35 @@ void RedundantMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { void RedundantMemberInitCheck::registerMatchers(MatchFinder *Finder) { auto ConstructorMatcher = - cxxConstructExpr(argumentCountIs(0), - hasDeclaration(cxxConstructorDecl(ofClass(cxxRecordDecl( - unless(isTriviallyDefaultConstructible())))))) + cxxConstructExpr( + argumentCountIs(0), + hasDeclaration(cxxConstructorDecl( + ofClass(cxxRecordDecl(unless(isTriviallyDefaultConstructible())) + .bind("class"))))) .bind("construct"); + auto HasUnionAsParent = hasParent(recordDecl(isUnion())); + + auto HasTypeEqualToConstructorClass = hasType(qualType( + hasCanonicalType(qualType(hasDeclaration(equalsBoundNode("class")))))); + Finder->addMatcher( cxxConstructorDecl( unless(isDelegatingConstructor()), ofClass(unless(isUnion())), forEachConstructorInitializer( - cxxCtorInitializer(withInitializer(ConstructorMatcher), - unless(forField(fieldDecl( - anyOf(hasType(isConstQualified()), - hasParent(recordDecl(isUnion()))))))) + cxxCtorInitializer( + withInitializer(ConstructorMatcher), + anyOf(isBaseInitializer(), + forField(fieldDecl(unless(hasType(isConstQualified())), + unless(HasUnionAsParent), + HasTypeEqualToConstructorClass)))) .bind("init"))) .bind("constructor"), this); Finder->addMatcher(fieldDecl(hasInClassInitializer(ConstructorMatcher), - unless(hasParent(recordDecl(isUnion())))) + HasTypeEqualToConstructorClass, + unless(HasUnionAsParent)) .bind("field"), this); } diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 33b65caf2b02..6947cf06f6e5 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -403,6 +403,11 @@ Changes in existing checks ` check to properly emit warnings for static data member with an in-class initializer. +- Improved :doc:`readability-redundant-member-init + ` check to avoid + false-positives when type of the member does not match the type of the + initializer. + - Improved :doc:`readability-static-accessed-through-instance ` check to support calls to overloaded operators as base expression and provide fixes to diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-member-init.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-member-init.cpp index 17b2714abca0..6f18a6043be9 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-member-init.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-member-init.cpp @@ -302,3 +302,19 @@ struct D7 { D7 d7i; D7 d7s; + +struct SS { + SS() = default; + SS(S s) : s(s) {} + + S s; +}; + +struct D8 { + SS ss = S(); +}; + +struct D9 { + D9() : ss(S()) {} + SS ss; +};