diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp @@ -41,12 +41,21 @@ void recordRemoval(const DeclStmt &Stmt, ASTContext &Context, DiagnosticBuilder &Diagnostic) { - // Attempt to remove the whole line until the next non-comment token. + // Attempt to remove trailing comments as well. auto Tok = utils::lexer::findNextTokenSkippingComments( Stmt.getEndLoc(), Context.getSourceManager(), Context.getLangOpts()); - if (Tok) { - Diagnostic << FixItHint::CreateRemoval(SourceRange( - Stmt.getBeginLoc(), Tok->getLocation().getLocWithOffset(-1))); + bool Invalid; + const char *TextAfter = + Context.getSourceManager().getCharacterData(Stmt.getEndLoc(), &Invalid); + if (Tok && !Invalid) { + size_t Offset = std::strcspn(TextAfter, "\n"); + auto PastNewLine = Stmt.getEndLoc().getLocWithOffset(Offset + 1); + auto BeforeFirstTokenAfterComment = Tok->getLocation().getLocWithOffset(-1); + // Remove until the end of the line or the end of a trailing comment which + // ever comes first. + auto End = std::min(PastNewLine, BeforeFirstTokenAfterComment); + Diagnostic << FixItHint::CreateRemoval( + SourceRange(Stmt.getBeginLoc(), End)); } else { Diagnostic << FixItHint::CreateRemoval(Stmt.getSourceRange()); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp @@ -596,8 +596,15 @@ // CHECK-FIXES: int i = 0; // Foo bar. auto TrailingCommentRemoved = ExpensiveTypeReference(); // Trailing comment. // CHECK-MESSAGES: [[@LINE-1]]:8: warning: the variable 'TrailingCommentRemoved' is copy-constructed from a const reference but is never used; - // CHECK-FIXES-NOT: auto TrailingCommentRemoved = ExpensiveTypeReference(); // Trailing comment. + // CHECK-FIXES-NOT: auto TrailingCommentRemoved = ExpensiveTypeReference(); + // CHECK-FIXES-NOT: // Trailing comment. // clang-format on + + auto UnusedAndUnnecessary = ExpensiveTypeReference(); + // Comments on a new line should not be deleted. + // CHECK-MESSAGES: [[@LINE-2]]:8: warning: the variable 'UnusedAndUnnecessary' is copy-constructed + // CHECK-FIXES-NOT: auto UnusedAndUnnecessary = ExpensiveTypeReference(); + // CHECK-FIXES: // Comments on a new line should not be deleted. } void negativeloopedOverObjectIsModified() {