[clang-tidy] Avoid adding unnecessary semicolon in modernize-use-equals-default
authorAlexander Shaposhnikov <ashaposhnikov@google.com>
Sat, 22 Oct 2022 00:42:50 +0000 (00:42 +0000)
committerAlexander Shaposhnikov <ashaposhnikov@google.com>
Sat, 22 Oct 2022 00:42:50 +0000 (00:42 +0000)
Adjust the automatic fixit to avoid adding superfluous semicolon.

Test plan: ninja check-all

Differential revision: https://reviews.llvm.org/D136399

clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp

index e72ea76..60e0f80 100644 (file)
@@ -337,10 +337,13 @@ void UseEqualsDefaultCheck::check(const MatchFinder::MatchResult &Result) {
   Diag << MemberType;
 
   if (ApplyFix) {
+    SourceLocation UnifiedEnd = utils::lexer::getUnifiedEndLoc(
+        *Body, Result.Context->getSourceManager(),
+        Result.Context->getLangOpts());
     // Skipping comments, check for a semicolon after Body->getSourceRange()
     Optional<Token> Token = utils::lexer::findNextTokenSkippingComments(
-        Body->getSourceRange().getEnd().getLocWithOffset(1),
-        Result.Context->getSourceManager(), Result.Context->getLangOpts());
+        UnifiedEnd, Result.Context->getSourceManager(),
+        Result.Context->getLangOpts());
     StringRef Replacement =
         Token && Token->is(tok::semi) ? "= default" : "= default;";
     Diag << FixItHint::CreateReplacement(Body->getSourceRange(), Replacement)
index 68995a9..d7ae8df 100644 (file)
@@ -159,6 +159,7 @@ Changes in existing checks
   with empty body is not equivalent to the explicitly defaulted one, variadic constructors
   since they cannot be explicitly defaulted. The check also skips copy assignment operators
   with nonstandard return types, private/protected default constructors for C++17 or earlier.
+  The automatic fixit has been adjusted to avoid adding superfluous semicolon.
   The check is restricted to C++11 or later.
 
 - Change the default behavior of :doc:`readability-avoid-const-params-in-decls
index 6482c3a..7a21ebe 100644 (file)
@@ -91,7 +91,7 @@ public:
 // Private constructor/destructor.
 class Priv {
   Priv();
-  ~Priv() {};
+  ~Priv() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~Priv() = default;
 };
@@ -100,14 +100,28 @@ Priv::Priv() {}
 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use '= default'
 // CHECK-FIXES: Priv::Priv() = default;
 
+struct SemiColon {
+  SemiColon() {};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: SemiColon() = default;{{$}}
+};
+
+struct SemiColonOutOfLine {
+  SemiColonOutOfLine();
+};
+
+SemiColonOutOfLine::SemiColonOutOfLine() {};
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use '= default'
+// CHECK-FIXES: SemiColonOutOfLine::SemiColonOutOfLine() = default;{{$}}
+
 // struct.
 struct ST {
   ST() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ST() = default;
+  // CHECK-FIXES: ST() = default;{{$}}
   ~ST() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ST() = default;
+  // CHECK-FIXES: ST() = default;{{$}}
 };
 
 // Deleted constructor/destructor.
@@ -200,7 +214,13 @@ struct DC : KW {
   DC() : KW() {}
   ~DC() override {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ~DC() override = default;
+  // CHECK-FIXES: ~DC() override = default;{{$}}
+};
+
+struct OverrideWithSemiColon : KW {
+  ~OverrideWithSemiColon() override {};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~OverrideWithSemiColon() override = default;{{$}}
 };
 
 struct Comments {