[clang-tools-extra] [clang-tidy] Improve modernize-use-equals-default check to handle explicit parent constructor calls (PR #226456)

via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 25 06:30:10 PDT 2026


https://github.com/serge-sans-paille updated https://github.com/llvm/llvm-project/pull/226456

>From a542ebb957d23dadee87351e472e75edc7f84982 Mon Sep 17 00:00:00 2001
From: serge-sans-paille <sguelton at mozilla.com>
Date: Fri, 25 Sep 2026 13:44:35 +0200
Subject: [PATCH 1/2] [clang-tidy] Improve modernize-use-equals-default check
 to handle explicit parent constructor calls

Now capture this pattern:

struct Base {};
struct C : Base {
    C() : Base() {}
};

And turn it into

struct Base {};
struct C : Base {
    C() = default;
};
---
 .../modernize/UseEqualsDefaultCheck.cpp          | 16 ++++++++++------
 clang-tools-extra/docs/ReleaseNotes.md           |  3 +++
 .../checkers/modernize/use-equals-default.cpp    | 16 ++++++++++++++++
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
index 1535fa79676abf..af8774dc09f359 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -247,7 +247,9 @@ void UseEqualsDefaultCheck::registerMatchers(MatchFinder *Finder) {
           anyOf(
               // Default constructor.
               allOf(parameterCountIs(0),
-                    unless(hasAnyConstructorInitializer(isWritten())),
+                    unless(hasAnyConstructorInitializer(allOf(
+                        isWritten(), unless(withInitializer(cxxConstructExpr(
+                                         argumentCountIs(0))))))),
                     unless(isVariadic()), IsPublicOrOutOfLineUntilCPP20),
               // Copy constructor.
               allOf(isCopyConstructor(),
@@ -319,11 +321,13 @@ void UseEqualsDefaultCheck::check(const MatchFinder::MatchResult &Result) {
       if (!isCopyConstructorAndCanBeDefaulted(Result.Context, Ctor))
         return;
       MemberType = 1;
-      // If there are constructor initializers, they must be removed.
-      for (const auto *Init : Ctor->inits()) {
-        RemoveInitializers.emplace_back(
-            FixItHint::CreateRemoval(Init->getSourceRange()));
-      }
+    }
+    // If there are constructor initializers, they must be removed.
+    for (const auto *Init : Ctor->inits()) {
+      if (!Init->isWritten())
+        continue;
+      RemoveInitializers.emplace_back(
+          FixItHint::CreateRemoval(Init->getSourceRange()));
     }
   } else if (isa<CXXDestructorDecl>(SpecialFunctionDecl)) {
     MemberType = 2;
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index 833638a47abc63..400b067b19bae4 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -236,6 +236,9 @@ infrastructure are described first, followed by tool-specific sections.
   <clang-tidy/checks/modernize/use-designated-initializers>` when analyzing
   malformed code with nested classes and ambiguous initializer.
 
+- Improved {doc}`modernize-use-equals-default` check to also capture default
+  constructor with explicit default-initialization of parents.
+
 - Fixed a crash in {doc}`modernize-use-noexcept
   <clang-tidy/checks/modernize/use-noexcept>` when analyzing malformed template
   code with an unparsed exception specification.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
index 2eefdf9d6460ca..34e37f5a7f5db5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -236,11 +236,27 @@ ODef::~ODef() = default;
 // Delegating constructor and overriden destructor.
 struct DC : KW {
   DC() : KW() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: DC() = default;
   ~DC() override {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~DC() override = default;
 };
 
+// Delegating constructor with multiple initializers.
+struct DCM : KW, N {
+  DCM() : KW(), N() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: DCM() = default;
+};
+
+// Delegating constructor with noexcept.
+struct DCNE : KW {
+  DCNE() noexcept : KW() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: DCNE() noexcept = default;
+};
+
 struct OverrideWithSemiColon : KW {
   ~OverrideWithSemiColon() override {};
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'

>From 644361eded6eeed288e52f35059cfdfe990956dd Mon Sep 17 00:00:00 2001
From: serge-sans-paille <sguelton at mozilla.com>
Date: Fri, 25 Sep 2026 15:29:43 +0200
Subject: [PATCH 2/2] fixup! [clang-tidy] Improve modernize-use-equals-default
 check to handle explicit parent constructor calls

---
 clang-tools-extra/docs/ReleaseNotes.md | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index 400b067b19bae4..3157be71e5f024 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -236,8 +236,9 @@ infrastructure are described first, followed by tool-specific sections.
   <clang-tidy/checks/modernize/use-designated-initializers>` when analyzing
   malformed code with nested classes and ambiguous initializer.
 
-- Improved {doc}`modernize-use-equals-default` check to also capture default
-  constructor with explicit default-initialization of parents.
+- Improved {doc}`modernize-use-equals-default
+  <clang-tidy/checks/modernize/use-equals-default>` check to also capture
+  default constructor with explicit default-initialization of parents.
 
 - Fixed a crash in {doc}`modernize-use-noexcept
   <clang-tidy/checks/modernize/use-noexcept>` when analyzing malformed template



More information about the cfe-commits mailing list