[clang-tools-extra] 5dbe3bf - [clang-tidy] performance-unnecessary-copy-initialization: Remove the complete statement when the copied variable is unused.
Felix Berger via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 9 12:54:08 PDT 2021
Author: Felix Berger
Date: 2021-06-09T15:52:48-04:00
New Revision: 5dbe3bf4b8dbb7e67d41c7c1360f15d512dd72a0
URL: https://github.com/llvm/llvm-project/commit/5dbe3bf4b8dbb7e67d41c7c1360f15d512dd72a0
DIFF: https://github.com/llvm/llvm-project/commit/5dbe3bf4b8dbb7e67d41c7c1360f15d512dd72a0.diff
LOG: [clang-tidy] performance-unnecessary-copy-initialization: Remove the complete statement when the copied variable is unused.
It is not useful to keep the statement around and can lead to compiler
warnings when -Wall (-Wunused-variable specifically) turned on.
Differential Revision: https://reviews.llvm.org/D102175
Reviewed-by: ymandel
Added:
Modified:
clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.h
clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization-allowed-types.cpp
clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
index 0cc9a44263021..57a2310e779fb 100644
--- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
+++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
@@ -7,9 +7,9 @@
//===----------------------------------------------------------------------===//
#include "UnnecessaryCopyInitialization.h"
-
#include "../utils/DeclRefExprUtils.h"
#include "../utils/FixItHintUtils.h"
+#include "../utils/LexerUtils.h"
#include "../utils/Matchers.h"
#include "../utils/OptionsUtils.h"
#include "clang/Basic/Diagnostic.h"
@@ -21,6 +21,7 @@ namespace {
using namespace ::clang::ast_matchers;
using llvm::StringRef;
+using utils::decl_ref_expr::allDeclRefExprs;
using utils::decl_ref_expr::isOnlyUsedAsConst;
static constexpr StringRef ObjectArgId = "objectArg";
@@ -37,6 +38,19 @@ void recordFixes(const VarDecl &Var, ASTContext &Context,
}
}
+void recordRemoval(const DeclStmt &Stmt, ASTContext &Context,
+ DiagnosticBuilder &Diagnostic) {
+ // Attempt to remove the whole line until the next non-comment token.
+ auto Tok = utils::lexer::findNextTokenSkippingComments(
+ Stmt.getEndLoc(), Context.getSourceManager(), Context.getLangOpts());
+ if (Tok) {
+ Diagnostic << FixItHint::CreateRemoval(SourceRange(
+ Stmt.getBeginLoc(), Tok->getLocation().getLocWithOffset(-1)));
+ } else {
+ Diagnostic << FixItHint::CreateRemoval(Stmt.getSourceRange());
+ }
+}
+
AST_MATCHER_FUNCTION(StatementMatcher, isConstRefReturningMethodCall) {
// Match method call expressions where the `this` argument is only used as
// const, this will be checked in `check()` part. This returned const
@@ -118,6 +132,11 @@ static bool isInitializingVariableImmutable(const VarDecl &InitializingVar,
return false;
}
+bool isVariableUnused(const VarDecl &Var, const Stmt &BlockStmt,
+ ASTContext &Context) {
+ return allDeclRefExprs(Var, BlockStmt, Context).empty();
+}
+
} // namespace
UnnecessaryCopyInitialization::UnnecessaryCopyInitialization(
@@ -169,14 +188,13 @@ void UnnecessaryCopyInitialization::check(
const auto *ObjectArg = Result.Nodes.getNodeAs<VarDecl>(ObjectArgId);
const auto *BlockStmt = Result.Nodes.getNodeAs<Stmt>("blockStmt");
const auto *CtorCall = Result.Nodes.getNodeAs<CXXConstructExpr>("ctorCall");
+ const auto *Stmt = Result.Nodes.getNodeAs<DeclStmt>("declStmt");
TraversalKindScope RAII(*Result.Context, TK_AsIs);
// Do not propose fixes if the DeclStmt has multiple VarDecls or in macros
// since we cannot place them correctly.
- bool IssueFix =
- Result.Nodes.getNodeAs<DeclStmt>("declStmt")->isSingleDecl() &&
- !NewVar->getLocation().isMacroID();
+ bool IssueFix = Stmt->isSingleDecl() && !NewVar->getLocation().isMacroID();
// A constructor that looks like T(const T& t, bool arg = false) counts as a
// copy only when it is called with default arguments for the arguments after
@@ -186,47 +204,68 @@ void UnnecessaryCopyInitialization::check(
return;
if (OldVar == nullptr) {
- handleCopyFromMethodReturn(*NewVar, *BlockStmt, IssueFix, ObjectArg,
+ handleCopyFromMethodReturn(*NewVar, *BlockStmt, *Stmt, IssueFix, ObjectArg,
*Result.Context);
} else {
- handleCopyFromLocalVar(*NewVar, *OldVar, *BlockStmt, IssueFix,
+ handleCopyFromLocalVar(*NewVar, *OldVar, *BlockStmt, *Stmt, IssueFix,
*Result.Context);
}
}
void UnnecessaryCopyInitialization::handleCopyFromMethodReturn(
- const VarDecl &Var, const Stmt &BlockStmt, bool IssueFix,
- const VarDecl *ObjectArg, ASTContext &Context) {
+ const VarDecl &Var, const Stmt &BlockStmt, const DeclStmt &Stmt,
+ bool IssueFix, const VarDecl *ObjectArg, ASTContext &Context) {
bool IsConstQualified = Var.getType().isConstQualified();
if (!IsConstQualified && !isOnlyUsedAsConst(Var, BlockStmt, Context))
return;
if (ObjectArg != nullptr &&
!isInitializingVariableImmutable(*ObjectArg, BlockStmt, Context))
return;
-
- auto Diagnostic =
- diag(Var.getLocation(),
- "the %select{|const qualified }0variable %1 is copy-constructed "
- "from a const reference%select{ but is only used as const "
- "reference|}0; consider making it a const reference")
- << IsConstQualified << &Var;
- if (IssueFix)
- recordFixes(Var, Context, Diagnostic);
+ if (isVariableUnused(Var, BlockStmt, Context)) {
+ auto Diagnostic =
+ diag(Var.getLocation(),
+ "the %select{|const qualified }0variable %1 is copy-constructed "
+ "from a const reference but is never used; consider "
+ "removing the statement")
+ << IsConstQualified << &Var;
+ if (IssueFix)
+ recordRemoval(Stmt, Context, Diagnostic);
+ } else {
+ auto Diagnostic =
+ diag(Var.getLocation(),
+ "the %select{|const qualified }0variable %1 is copy-constructed "
+ "from a const reference%select{ but is only used as const "
+ "reference|}0; consider making it a const reference")
+ << IsConstQualified << &Var;
+ if (IssueFix)
+ recordFixes(Var, Context, Diagnostic);
+ }
}
void UnnecessaryCopyInitialization::handleCopyFromLocalVar(
const VarDecl &NewVar, const VarDecl &OldVar, const Stmt &BlockStmt,
- bool IssueFix, ASTContext &Context) {
+ const DeclStmt &Stmt, bool IssueFix, ASTContext &Context) {
if (!isOnlyUsedAsConst(NewVar, BlockStmt, Context) ||
!isInitializingVariableImmutable(OldVar, BlockStmt, Context))
return;
- auto Diagnostic = diag(NewVar.getLocation(),
- "local copy %0 of the variable %1 is never modified; "
- "consider avoiding the copy")
- << &NewVar << &OldVar;
- if (IssueFix)
- recordFixes(NewVar, Context, Diagnostic);
+ if (isVariableUnused(NewVar, BlockStmt, Context)) {
+ auto Diagnostic = diag(NewVar.getLocation(),
+ "local copy %0 of the variable %1 is never modified "
+ "and never used; "
+ "consider removing the statement")
+ << &NewVar << &OldVar;
+ if (IssueFix)
+ recordRemoval(Stmt, Context, Diagnostic);
+ } else {
+ auto Diagnostic =
+ diag(NewVar.getLocation(),
+ "local copy %0 of the variable %1 is never modified; "
+ "consider avoiding the copy")
+ << &NewVar << &OldVar;
+ if (IssueFix)
+ recordFixes(NewVar, Context, Diagnostic);
+ }
}
void UnnecessaryCopyInitialization::storeOptions(
diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.h b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.h
index eeb9138d8532d..8193672218932 100644
--- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.h
+++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.h
@@ -35,11 +35,12 @@ class UnnecessaryCopyInitialization : public ClangTidyCheck {
private:
void handleCopyFromMethodReturn(const VarDecl &Var, const Stmt &BlockStmt,
- bool IssueFix, const VarDecl *ObjectArg,
+ const DeclStmt &Stmt, bool IssueFix,
+ const VarDecl *ObjectArg,
ASTContext &Context);
void handleCopyFromLocalVar(const VarDecl &NewVar, const VarDecl &OldVar,
- const Stmt &BlockStmt, bool IssueFix,
- ASTContext &Context);
+ const Stmt &BlockStmt, const DeclStmt &Stmt,
+ bool IssueFix, ASTContext &Context);
const std::vector<std::string> AllowedTypes;
};
diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization-allowed-types.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization-allowed-types.cpp
index 420efa8dbe3c6..52b14be1231f7 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization-allowed-types.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization-allowed-types.cpp
@@ -34,6 +34,7 @@ struct smart_ref {
struct OtherType {
~OtherType();
+ void constMethod() const;
};
template <typename T> struct SomeComplexTemplate {
@@ -89,6 +90,7 @@ void positiveOtherType() {
const auto O = getOtherType();
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'O' is copy-constructed from a const reference; consider making it a const reference [performance-unnecessary-copy-initialization]
// CHECK-FIXES: const auto& O = getOtherType();
+ O.constMethod();
}
void negativeNotTooComplexRef() {
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
index 8cc095e431fda..3a4c3ec869e1c 100644
--- 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
@@ -38,60 +38,88 @@ void PositiveFunctionCall() {
const auto AutoAssigned = ExpensiveTypeReference();
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned' is copy-constructed from a const reference; consider making it a const reference [performance-unnecessary-copy-initialization]
// CHECK-FIXES: const auto& AutoAssigned = ExpensiveTypeReference();
+ AutoAssigned.constMethod();
+
const auto AutoCopyConstructed(ExpensiveTypeReference());
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed'
// CHECK-FIXES: const auto& AutoCopyConstructed(ExpensiveTypeReference());
+ AutoCopyConstructed.constMethod();
+
const ExpensiveToCopyType VarAssigned = ExpensiveTypeReference();
// CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned'
// CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = ExpensiveTypeReference();
+ VarAssigned.constMethod();
+
const ExpensiveToCopyType VarCopyConstructed(ExpensiveTypeReference());
// CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed'
// CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(ExpensiveTypeReference());
+ VarCopyConstructed.constMethod();
}
void PositiveMethodCallConstReferenceParam(const ExpensiveToCopyType &Obj) {
const auto AutoAssigned = Obj.reference();
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
// CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
+ AutoAssigned.constMethod();
+
const auto AutoCopyConstructed(Obj.reference());
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed'
// CHECK-FIXES: const auto& AutoCopyConstructed(Obj.reference());
+ AutoCopyConstructed.constMethod();
+
const ExpensiveToCopyType VarAssigned = Obj.reference();
// CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned'
// CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = Obj.reference();
+ VarAssigned.constMethod();
+
const ExpensiveToCopyType VarCopyConstructed(Obj.reference());
// CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed'
// CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(Obj.reference());
+ VarCopyConstructed.constMethod();
}
void PositiveMethodCallConstParam(const ExpensiveToCopyType Obj) {
const auto AutoAssigned = Obj.reference();
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
// CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
+ AutoAssigned.constMethod();
+
const auto AutoCopyConstructed(Obj.reference());
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed'
// CHECK-FIXES: const auto& AutoCopyConstructed(Obj.reference());
+ AutoCopyConstructed.constMethod();
+
const ExpensiveToCopyType VarAssigned = Obj.reference();
// CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned'
// CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = Obj.reference();
+ VarAssigned.constMethod();
+
const ExpensiveToCopyType VarCopyConstructed(Obj.reference());
// CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed'
// CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(Obj.reference());
+ VarCopyConstructed.constMethod();
}
void PositiveMethodCallConstPointerParam(const ExpensiveToCopyType *const Obj) {
const auto AutoAssigned = Obj->reference();
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
// CHECK-FIXES: const auto& AutoAssigned = Obj->reference();
+ AutoAssigned.constMethod();
+
const auto AutoCopyConstructed(Obj->reference());
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed'
// CHECK-FIXES: const auto& AutoCopyConstructed(Obj->reference());
+ AutoCopyConstructed.constMethod();
+
const ExpensiveToCopyType VarAssigned = Obj->reference();
// CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned'
// CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = Obj->reference();
+ VarAssigned.constMethod();
+
const ExpensiveToCopyType VarCopyConstructed(Obj->reference());
// CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed'
// CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(Obj->reference());
+ VarCopyConstructed.constMethod();
}
void PositiveLocalConstValue() {
@@ -99,6 +127,7 @@ void PositiveLocalConstValue() {
const auto UnnecessaryCopy = Obj.reference();
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'UnnecessaryCopy'
// CHECK-FIXES: const auto& UnnecessaryCopy = Obj.reference();
+ UnnecessaryCopy.constMethod();
}
void PositiveLocalConstRef() {
@@ -107,6 +136,7 @@ void PositiveLocalConstRef() {
const auto UnnecessaryCopy = ConstReference.reference();
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'UnnecessaryCopy'
// CHECK-FIXES: const auto& UnnecessaryCopy = ConstReference.reference();
+ UnnecessaryCopy.constMethod();
}
void PositiveLocalConstPointer() {
@@ -115,6 +145,7 @@ void PositiveLocalConstPointer() {
const auto UnnecessaryCopy = ConstPointer->reference();
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'UnnecessaryCopy'
// CHECK-FIXES: const auto& UnnecessaryCopy = ConstPointer->reference();
+ UnnecessaryCopy.constMethod();
}
void NegativeFunctionCallTrivialType() {
@@ -132,15 +163,22 @@ void PositiveFunctionCallExpensiveTypeNonConstVariable() {
auto AutoAssigned = ExpensiveTypeReference();
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: the variable 'AutoAssigned' is copy-constructed from a const reference but is only used as const reference; consider making it a const reference [performance-unnecessary-copy-initialization]
// CHECK-FIXES: const auto& AutoAssigned = ExpensiveTypeReference();
+ AutoAssigned.constMethod();
+
auto AutoCopyConstructed(ExpensiveTypeReference());
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: the variable 'AutoCopyConstructed'
// CHECK-FIXES: const auto& AutoCopyConstructed(ExpensiveTypeReference());
+ AutoCopyConstructed.constMethod();
+
ExpensiveToCopyType VarAssigned = ExpensiveTypeReference();
// CHECK-MESSAGES: [[@LINE-1]]:23: warning: the variable 'VarAssigned'
// CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = ExpensiveTypeReference();
+ VarAssigned.constMethod();
+
ExpensiveToCopyType VarCopyConstructed(ExpensiveTypeReference());
// CHECK-MESSAGES: [[@LINE-1]]:23: warning: the variable 'VarCopyConstructed'
// CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(ExpensiveTypeReference());
+ VarCopyConstructed.constMethod();
}
void positiveNonConstVarInCodeBlock(const ExpensiveToCopyType &Obj) {
@@ -181,6 +219,7 @@ void PositiveMethodCallNonConstRefNotModified(ExpensiveToCopyType &Obj) {
const auto AutoAssigned = Obj.reference();
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
// CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
+ AutoAssigned.constMethod();
}
void NegativeMethodCallNonConstRefIsModified(ExpensiveToCopyType &Obj) {
@@ -195,6 +234,7 @@ void PositiveMethodCallNonConstNotModified(ExpensiveToCopyType Obj) {
const auto AutoAssigned = Obj.reference();
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
// CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
+ AutoAssigned.constMethod();
}
void NegativeMethodCallNonConstValueArgumentIsModified(ExpensiveToCopyType Obj) {
@@ -207,6 +247,7 @@ void PositiveMethodCallNonConstPointerNotModified(ExpensiveToCopyType *const Obj
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
// CHECK-FIXES: const auto& AutoAssigned = Obj->reference();
Obj->constMethod();
+ AutoAssigned.constMethod();
}
void NegativeMethodCallNonConstPointerIsModified(ExpensiveToCopyType *const Obj) {
@@ -222,6 +263,7 @@ void PositiveLocalVarIsNotModified() {
const auto AutoAssigned = LocalVar.reference();
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
// CHECK-FIXES: const auto& AutoAssigned = LocalVar.reference();
+ AutoAssigned.constMethod();
}
void NegativeLocalVarIsModified() {
@@ -252,6 +294,7 @@ void PositiveMacroArgument(const ExpensiveToCopyType &Obj) {
// CHECK-MESSAGES: [[@LINE-1]]:48: warning: the variable 'CopyInMacroArg' is copy-constructed
// Ensure fix is not applied.
// CHECK-FIXES: auto CopyInMacroArg = Obj.reference()
+ CopyInMacroArg.constMethod();
}
void PositiveLocalCopyConstMethodInvoked() {
@@ -285,6 +328,7 @@ void PositiveLocalCopyUsedAsConstRef() {
// CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy_4'
// CHECK-FIXES: const ExpensiveToCopyType& copy_4 = orig;
useAsConstReference(orig);
+ copy_4.constMethod();
}
void PositiveLocalCopyTwice() {
@@ -370,6 +414,7 @@ void WarningOnlyMultiDeclStmt() {
ExpensiveToCopyType copy = orig, copy2;
// CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy' of the variable 'orig' is never modified; consider avoiding the copy [performance-unnecessary-copy-initialization]
// CHECK-FIXES: ExpensiveToCopyType copy = orig, copy2;
+ copy.constMethod();
}
class Element {};
@@ -450,6 +495,7 @@ template <class R, class... Args>
struct function {
// Custom copy constructor makes it expensive to copy;
function(const function &);
+ void constMethod() const;
};
} // namespace std
@@ -457,6 +503,7 @@ void positiveFakeStdFunction(std::function<void(int)> F) {
auto Copy = F;
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: local copy 'Copy' of the variable 'F' is never modified;
// CHECK-FIXES: const auto& Copy = F;
+ Copy.constMethod();
}
} // namespace fake
@@ -491,6 +538,7 @@ void positiveCopiedFromReferenceToConstVar() {
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: local copy 'UnnecessaryCopy' of
// CHECK-FIXES: const auto& UnnecessaryCopy = Ref;
Orig.constMethod();
+ UnnecessaryCopy.constMethod();
}
void negativeCopiedFromGetterOfReferenceToModifiedVar() {
@@ -507,4 +555,17 @@ void positiveCopiedFromGetterOfReferenceToConstVar() {
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: the variable 'UnnecessaryCopy' is
// CHECK-FIXES: const auto& UnnecessaryCopy = Ref.reference();
Orig.constMethod();
+ UnnecessaryCopy.constMethod();
+}
+
+void positiveUnusedReferenceIsRemoved() {
+ // clang-format off
+ const auto AutoAssigned = ExpensiveTypeReference(); int i = 0; // Foo bar.
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned' is copy-constructed from a const reference but is never used; consider removing the statement [performance-unnecessary-copy-initialization]
+ // CHECK-FIXES-NOT: const auto AutoAssigned = ExpensiveTypeReference();
+ // 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.
+ // clang-format on
}
More information about the cfe-commits
mailing list