Skip to content

Commit d24e228

Browse files
committed
Merge from 'main' to 'sycl-web' (#2)
CONFLICT (content): Merge conflict in llvm/test/Transforms/OpenMP/hide_mem_transfer_latency.ll
2 parents 64095f6 + c70c30d commit d24e228

File tree

327 files changed

+4999
-2648
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

327 files changed

+4999
-2648
lines changed

clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "UnnecessaryCopyInitialization.h"
10-
1110
#include "../utils/DeclRefExprUtils.h"
1211
#include "../utils/FixItHintUtils.h"
12+
#include "../utils/LexerUtils.h"
1313
#include "../utils/Matchers.h"
1414
#include "../utils/OptionsUtils.h"
1515
#include "clang/Basic/Diagnostic.h"
@@ -21,6 +21,7 @@ namespace {
2121

2222
using namespace ::clang::ast_matchers;
2323
using llvm::StringRef;
24+
using utils::decl_ref_expr::allDeclRefExprs;
2425
using utils::decl_ref_expr::isOnlyUsedAsConst;
2526

2627
static constexpr StringRef ObjectArgId = "objectArg";
@@ -37,6 +38,19 @@ void recordFixes(const VarDecl &Var, ASTContext &Context,
3738
}
3839
}
3940

41+
void recordRemoval(const DeclStmt &Stmt, ASTContext &Context,
42+
DiagnosticBuilder &Diagnostic) {
43+
// Attempt to remove the whole line until the next non-comment token.
44+
auto Tok = utils::lexer::findNextTokenSkippingComments(
45+
Stmt.getEndLoc(), Context.getSourceManager(), Context.getLangOpts());
46+
if (Tok) {
47+
Diagnostic << FixItHint::CreateRemoval(SourceRange(
48+
Stmt.getBeginLoc(), Tok->getLocation().getLocWithOffset(-1)));
49+
} else {
50+
Diagnostic << FixItHint::CreateRemoval(Stmt.getSourceRange());
51+
}
52+
}
53+
4054
AST_MATCHER_FUNCTION(StatementMatcher, isConstRefReturningMethodCall) {
4155
// Match method call expressions where the `this` argument is only used as
4256
// const, this will be checked in `check()` part. This returned const
@@ -118,6 +132,11 @@ static bool isInitializingVariableImmutable(const VarDecl &InitializingVar,
118132
return false;
119133
}
120134

135+
bool isVariableUnused(const VarDecl &Var, const Stmt &BlockStmt,
136+
ASTContext &Context) {
137+
return allDeclRefExprs(Var, BlockStmt, Context).empty();
138+
}
139+
121140
} // namespace
122141

123142
UnnecessaryCopyInitialization::UnnecessaryCopyInitialization(
@@ -169,14 +188,13 @@ void UnnecessaryCopyInitialization::check(
169188
const auto *ObjectArg = Result.Nodes.getNodeAs<VarDecl>(ObjectArgId);
170189
const auto *BlockStmt = Result.Nodes.getNodeAs<Stmt>("blockStmt");
171190
const auto *CtorCall = Result.Nodes.getNodeAs<CXXConstructExpr>("ctorCall");
191+
const auto *Stmt = Result.Nodes.getNodeAs<DeclStmt>("declStmt");
172192

173193
TraversalKindScope RAII(*Result.Context, TK_AsIs);
174194

175195
// Do not propose fixes if the DeclStmt has multiple VarDecls or in macros
176196
// since we cannot place them correctly.
177-
bool IssueFix =
178-
Result.Nodes.getNodeAs<DeclStmt>("declStmt")->isSingleDecl() &&
179-
!NewVar->getLocation().isMacroID();
197+
bool IssueFix = Stmt->isSingleDecl() && !NewVar->getLocation().isMacroID();
180198

181199
// A constructor that looks like T(const T& t, bool arg = false) counts as a
182200
// copy only when it is called with default arguments for the arguments after
@@ -186,47 +204,68 @@ void UnnecessaryCopyInitialization::check(
186204
return;
187205

188206
if (OldVar == nullptr) {
189-
handleCopyFromMethodReturn(*NewVar, *BlockStmt, IssueFix, ObjectArg,
207+
handleCopyFromMethodReturn(*NewVar, *BlockStmt, *Stmt, IssueFix, ObjectArg,
190208
*Result.Context);
191209
} else {
192-
handleCopyFromLocalVar(*NewVar, *OldVar, *BlockStmt, IssueFix,
210+
handleCopyFromLocalVar(*NewVar, *OldVar, *BlockStmt, *Stmt, IssueFix,
193211
*Result.Context);
194212
}
195213
}
196214

197215
void UnnecessaryCopyInitialization::handleCopyFromMethodReturn(
198-
const VarDecl &Var, const Stmt &BlockStmt, bool IssueFix,
199-
const VarDecl *ObjectArg, ASTContext &Context) {
216+
const VarDecl &Var, const Stmt &BlockStmt, const DeclStmt &Stmt,
217+
bool IssueFix, const VarDecl *ObjectArg, ASTContext &Context) {
200218
bool IsConstQualified = Var.getType().isConstQualified();
201219
if (!IsConstQualified && !isOnlyUsedAsConst(Var, BlockStmt, Context))
202220
return;
203221
if (ObjectArg != nullptr &&
204222
!isInitializingVariableImmutable(*ObjectArg, BlockStmt, Context))
205223
return;
206-
207-
auto Diagnostic =
208-
diag(Var.getLocation(),
209-
"the %select{|const qualified }0variable %1 is copy-constructed "
210-
"from a const reference%select{ but is only used as const "
211-
"reference|}0; consider making it a const reference")
212-
<< IsConstQualified << &Var;
213-
if (IssueFix)
214-
recordFixes(Var, Context, Diagnostic);
224+
if (isVariableUnused(Var, BlockStmt, Context)) {
225+
auto Diagnostic =
226+
diag(Var.getLocation(),
227+
"the %select{|const qualified }0variable %1 is copy-constructed "
228+
"from a const reference but is never used; consider "
229+
"removing the statement")
230+
<< IsConstQualified << &Var;
231+
if (IssueFix)
232+
recordRemoval(Stmt, Context, Diagnostic);
233+
} else {
234+
auto Diagnostic =
235+
diag(Var.getLocation(),
236+
"the %select{|const qualified }0variable %1 is copy-constructed "
237+
"from a const reference%select{ but is only used as const "
238+
"reference|}0; consider making it a const reference")
239+
<< IsConstQualified << &Var;
240+
if (IssueFix)
241+
recordFixes(Var, Context, Diagnostic);
242+
}
215243
}
216244

217245
void UnnecessaryCopyInitialization::handleCopyFromLocalVar(
218246
const VarDecl &NewVar, const VarDecl &OldVar, const Stmt &BlockStmt,
219-
bool IssueFix, ASTContext &Context) {
247+
const DeclStmt &Stmt, bool IssueFix, ASTContext &Context) {
220248
if (!isOnlyUsedAsConst(NewVar, BlockStmt, Context) ||
221249
!isInitializingVariableImmutable(OldVar, BlockStmt, Context))
222250
return;
223251

224-
auto Diagnostic = diag(NewVar.getLocation(),
225-
"local copy %0 of the variable %1 is never modified; "
226-
"consider avoiding the copy")
227-
<< &NewVar << &OldVar;
228-
if (IssueFix)
229-
recordFixes(NewVar, Context, Diagnostic);
252+
if (isVariableUnused(NewVar, BlockStmt, Context)) {
253+
auto Diagnostic = diag(NewVar.getLocation(),
254+
"local copy %0 of the variable %1 is never modified "
255+
"and never used; "
256+
"consider removing the statement")
257+
<< &NewVar << &OldVar;
258+
if (IssueFix)
259+
recordRemoval(Stmt, Context, Diagnostic);
260+
} else {
261+
auto Diagnostic =
262+
diag(NewVar.getLocation(),
263+
"local copy %0 of the variable %1 is never modified; "
264+
"consider avoiding the copy")
265+
<< &NewVar << &OldVar;
266+
if (IssueFix)
267+
recordFixes(NewVar, Context, Diagnostic);
268+
}
230269
}
231270

232271
void UnnecessaryCopyInitialization::storeOptions(

clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,12 @@ class UnnecessaryCopyInitialization : public ClangTidyCheck {
3535

3636
private:
3737
void handleCopyFromMethodReturn(const VarDecl &Var, const Stmt &BlockStmt,
38-
bool IssueFix, const VarDecl *ObjectArg,
38+
const DeclStmt &Stmt, bool IssueFix,
39+
const VarDecl *ObjectArg,
3940
ASTContext &Context);
4041
void handleCopyFromLocalVar(const VarDecl &NewVar, const VarDecl &OldVar,
41-
const Stmt &BlockStmt, bool IssueFix,
42-
ASTContext &Context);
42+
const Stmt &BlockStmt, const DeclStmt &Stmt,
43+
bool IssueFix, ASTContext &Context);
4344
const std::vector<std::string> AllowedTypes;
4445
};
4546

clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization-allowed-types.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct smart_ref {
3434

3535
struct OtherType {
3636
~OtherType();
37+
void constMethod() const;
3738
};
3839

3940
template <typename T> struct SomeComplexTemplate {
@@ -89,6 +90,7 @@ void positiveOtherType() {
8990
const auto O = getOtherType();
9091
// 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]
9192
// CHECK-FIXES: const auto& O = getOtherType();
93+
O.constMethod();
9294
}
9395

9496
void negativeNotTooComplexRef() {

0 commit comments

Comments
 (0)