[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