Skip to content

[clang-tidy] Fix false positives in readability-redundant-inline-specifier #135391

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

bjosv
Copy link
Contributor

@bjosv bjosv commented Apr 11, 2025

The out-of-line explicitly-defaulted definition is not the first declaration, so it is not implicitly inline.

Alt. reference:
9.5.2 (3) Explicitly-defaulted functions in N4950.
or https://timsong-cpp.github.io/cppwp/n4861/dcl.fct.def.default#3

Fixes #130745

bjosv added 2 commits April 11, 2025 17:09
…cifier

Signed-off-by: Björn Svensson <bjorn.a.svensson@est.tech>
…ifier

Only warn on explicitly defaulted functions which are inlined by default,
i.e. dont warn on out-of-line explicitly defaulted functions.

Signed-off-by: Björn Svensson <bjorn.a.svensson@est.tech>
@llvmbot
Copy link
Member

llvmbot commented Apr 11, 2025

@llvm/pr-subscribers-clang-tools-extra

Author: Björn Svensson (bjosv)

Changes

The out-of-line explicitly-defaulted definition is not the first declaration, so it is not implicitly inline.

Alt. reference:
9.5.2 (3) Explicitly-defaulted functions in N4950.
or https://timsong-cpp.github.io/cppwp/n4861/dcl.fct.def.default#3

Fixes #130745


Full diff: https://github.com/llvm/llvm-project/pull/135391.diff

3 Files Affected:

  • (modified) clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp (+4-3)
  • (modified) clang-tools-extra/docs/ReleaseNotes.rst (+4)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/readability/redundant-inline-specifier.cpp (+10)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp
index 1693e5c5e9cd4..33effb3dab977 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp
@@ -72,11 +72,13 @@ static SourceLocation getInlineTokenLocation(SourceRange RangeLocation,
 }
 
 void RedundantInlineSpecifierCheck::registerMatchers(MatchFinder *Finder) {
+  const auto IsPartOfRecordDecl = hasAncestor(recordDecl());
   Finder->addMatcher(
       functionDecl(isInlineSpecified(),
-                   anyOf(isConstexpr(), isDeleted(), isDefaulted(),
+                   anyOf(isConstexpr(), isDeleted(),
+                         allOf(isDefaulted(), IsPartOfRecordDecl),
                          isInternalLinkage(StrictMode),
-                         allOf(isDefinition(), hasAncestor(recordDecl()))))
+                         allOf(isDefinition(), IsPartOfRecordDecl)))
           .bind("fun_decl"),
       this);
 
@@ -88,7 +90,6 @@ void RedundantInlineSpecifierCheck::registerMatchers(MatchFinder *Finder) {
         this);
 
   if (getLangOpts().CPlusPlus17) {
-    const auto IsPartOfRecordDecl = hasAncestor(recordDecl());
     Finder->addMatcher(
         varDecl(
             isInlineSpecified(),
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 761c1d3a80359..8fed96ceef647 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -204,6 +204,10 @@ Changes in existing checks
   tolerating fix-it breaking compilation when functions is used as pointers
   to avoid matching usage of functions within the current compilation unit.
 
+- Improved :doc:`readability-redundant-inline-specifier
+  <clang-tidy/checks/readability/redundant-inline-specifier>` check by fixing
+  false positives on out-of-line explicitly defaulted functions.
+
 Removed checks
 ^^^^^^^^^^^^^^
 
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-inline-specifier.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-inline-specifier.cpp
index 14f9e88f7e721..882ce640b13c1 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-inline-specifier.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-inline-specifier.cpp
@@ -149,3 +149,13 @@ class A
   // CHECK-FIXES-STRICT: static float test4;
 };
 }
+
+namespace ns {
+class B
+{
+public:
+  ~B();
+};
+
+inline B::~B() = default;
+}

@llvmbot
Copy link
Member

llvmbot commented Apr 11, 2025

@llvm/pr-subscribers-clang-tidy

Author: Björn Svensson (bjosv)

Changes

The out-of-line explicitly-defaulted definition is not the first declaration, so it is not implicitly inline.

Alt. reference:
9.5.2 (3) Explicitly-defaulted functions in N4950.
or https://timsong-cpp.github.io/cppwp/n4861/dcl.fct.def.default#3

Fixes #130745


Full diff: https://github.com/llvm/llvm-project/pull/135391.diff

3 Files Affected:

  • (modified) clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp (+4-3)
  • (modified) clang-tools-extra/docs/ReleaseNotes.rst (+4)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/readability/redundant-inline-specifier.cpp (+10)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp
index 1693e5c5e9cd4..33effb3dab977 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp
@@ -72,11 +72,13 @@ static SourceLocation getInlineTokenLocation(SourceRange RangeLocation,
 }
 
 void RedundantInlineSpecifierCheck::registerMatchers(MatchFinder *Finder) {
+  const auto IsPartOfRecordDecl = hasAncestor(recordDecl());
   Finder->addMatcher(
       functionDecl(isInlineSpecified(),
-                   anyOf(isConstexpr(), isDeleted(), isDefaulted(),
+                   anyOf(isConstexpr(), isDeleted(),
+                         allOf(isDefaulted(), IsPartOfRecordDecl),
                          isInternalLinkage(StrictMode),
-                         allOf(isDefinition(), hasAncestor(recordDecl()))))
+                         allOf(isDefinition(), IsPartOfRecordDecl)))
           .bind("fun_decl"),
       this);
 
@@ -88,7 +90,6 @@ void RedundantInlineSpecifierCheck::registerMatchers(MatchFinder *Finder) {
         this);
 
   if (getLangOpts().CPlusPlus17) {
-    const auto IsPartOfRecordDecl = hasAncestor(recordDecl());
     Finder->addMatcher(
         varDecl(
             isInlineSpecified(),
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 761c1d3a80359..8fed96ceef647 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -204,6 +204,10 @@ Changes in existing checks
   tolerating fix-it breaking compilation when functions is used as pointers
   to avoid matching usage of functions within the current compilation unit.
 
+- Improved :doc:`readability-redundant-inline-specifier
+  <clang-tidy/checks/readability/redundant-inline-specifier>` check by fixing
+  false positives on out-of-line explicitly defaulted functions.
+
 Removed checks
 ^^^^^^^^^^^^^^
 
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-inline-specifier.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-inline-specifier.cpp
index 14f9e88f7e721..882ce640b13c1 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-inline-specifier.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-inline-specifier.cpp
@@ -149,3 +149,13 @@ class A
   // CHECK-FIXES-STRICT: static float test4;
 };
 }
+
+namespace ns {
+class B
+{
+public:
+  ~B();
+};
+
+inline B::~B() = default;
+}

Copy link
Member

@PiotrZSL PiotrZSL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -72,11 +72,13 @@ static SourceLocation getInlineTokenLocation(SourceRange RangeLocation,
}

void RedundantInlineSpecifierCheck::registerMatchers(MatchFinder *Finder) {
const auto IsPartOfRecordDecl = hasAncestor(recordDecl());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I wonder, maybe hasDeclContext should be used here instead of hasAncestor or just match cxxMethodDecl directly instead of functionDecl.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants