Skip to content

Commit f75922c

Browse files
committed
Merge "merge main into amd-staging" into amd-staging
2 parents 1b64a30 + 5f8f6f6 commit f75922c

File tree

79 files changed

+2959
-729
lines changed

Some content is hidden

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

79 files changed

+2959
-729
lines changed

clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,10 @@ void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
117117
/*SkipTrailingWhitespaceAndNewLine=*/true));
118118
for (const auto *UsingShadow : Using->shadows()) {
119119
const auto *TargetDecl = UsingShadow->getTargetDecl()->getCanonicalDecl();
120-
if (shouldCheckDecl(TargetDecl))
120+
if (shouldCheckDecl(TargetDecl)) {
121121
Context.UsingTargetDecls.insert(TargetDecl);
122+
UsingTargetDeclsCache.insert(TargetDecl);
123+
}
122124
}
123125
if (!Context.UsingTargetDecls.empty())
124126
Contexts.push_back(Context);
@@ -201,13 +203,16 @@ void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
201203
void UnusedUsingDeclsCheck::removeFromFoundDecls(const Decl *D) {
202204
if (!D)
203205
return;
206+
const Decl *CanonicalDecl = D->getCanonicalDecl();
207+
if (!UsingTargetDeclsCache.contains(CanonicalDecl))
208+
return;
204209
// FIXME: Currently, we don't handle the using-decls being used in different
205210
// scopes (such as different namespaces, different functions). Instead of
206211
// giving an incorrect message, we mark all of them as used.
207-
//
208-
// FIXME: Use a more efficient way to find a matching context.
209212
for (auto &Context : Contexts) {
210-
if (Context.UsingTargetDecls.contains(D->getCanonicalDecl()))
213+
if (Context.IsUsed)
214+
continue;
215+
if (Context.UsingTargetDecls.contains(CanonicalDecl))
211216
Context.IsUsed = true;
212217
}
213218
}
@@ -224,6 +229,7 @@ void UnusedUsingDeclsCheck::onEndOfTranslationUnit() {
224229
}
225230
}
226231
Contexts.clear();
232+
UsingTargetDeclsCache.clear();
227233
}
228234

229235
} // namespace clang::tidy::misc

clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class UnusedUsingDeclsCheck : public ClangTidyCheck {
4949
};
5050

5151
std::vector<UsingDeclContext> Contexts;
52+
llvm::SmallPtrSet<const Decl *, 32> UsingTargetDeclsCache;
5253

5354
StringRef RawStringHeaderFileExtensions;
5455
FileExtensionsSet HeaderFileExtensions;

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,15 @@ bool ForRangeCopyCheck::handleConstValueCopy(const VarDecl &LoopVar,
9797
return true;
9898
}
9999

100+
static bool isReferenced(const VarDecl &LoopVar, const Stmt &Stmt,
101+
ASTContext &Context) {
102+
const auto IsLoopVar = varDecl(equalsNode(&LoopVar));
103+
return !match(stmt(hasDescendant(declRefExpr(to(valueDecl(anyOf(
104+
IsLoopVar, bindingDecl(forDecomposition(IsLoopVar)))))))),
105+
Stmt, Context)
106+
.empty();
107+
}
108+
100109
bool ForRangeCopyCheck::handleCopyIsOnlyConstReferenced(
101110
const VarDecl &LoopVar, const CXXForRangeStmt &ForRange,
102111
ASTContext &Context) {
@@ -113,9 +122,7 @@ bool ForRangeCopyCheck::handleCopyIsOnlyConstReferenced(
113122
// compiler warning which can't be suppressed.
114123
// Since this case is very rare, it is safe to ignore it.
115124
if (!ExprMutationAnalyzer(*ForRange.getBody(), Context).isMutated(&LoopVar) &&
116-
!utils::decl_ref_expr::allDeclRefExprs(LoopVar, *ForRange.getBody(),
117-
Context)
118-
.empty()) {
125+
isReferenced(LoopVar, *ForRange.getBody(), Context)) {
119126
auto Diag = diag(
120127
LoopVar.getLocation(),
121128
"loop variable is copied but only used as const reference; consider "

clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp

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

99
#include "ImplicitBoolConversionCheck.h"
10+
#include "../utils/FixItHintUtils.h"
1011
#include "clang/AST/ASTContext.h"
1112
#include "clang/ASTMatchers/ASTMatchFinder.h"
1213
#include "clang/Lex/Lexer.h"
@@ -61,31 +62,6 @@ bool isUnaryLogicalNotOperator(const Stmt *Statement) {
6162
return UnaryOperatorExpr && UnaryOperatorExpr->getOpcode() == UO_LNot;
6263
}
6364

64-
bool areParensNeededForOverloadedOperator(OverloadedOperatorKind OperatorKind) {
65-
switch (OperatorKind) {
66-
case OO_New:
67-
case OO_Delete: // Fall-through on purpose.
68-
case OO_Array_New:
69-
case OO_Array_Delete:
70-
case OO_ArrowStar:
71-
case OO_Arrow:
72-
case OO_Call:
73-
case OO_Subscript:
74-
return false;
75-
76-
default:
77-
return true;
78-
}
79-
}
80-
81-
bool areParensNeededForStatement(const Stmt *Statement) {
82-
if (const auto *OperatorCall = dyn_cast<CXXOperatorCallExpr>(Statement)) {
83-
return areParensNeededForOverloadedOperator(OperatorCall->getOperator());
84-
}
85-
86-
return isa<BinaryOperator>(Statement) || isa<UnaryOperator>(Statement);
87-
}
88-
8965
void fixGenericExprCastToBool(DiagnosticBuilder &Diag,
9066
const ImplicitCastExpr *Cast, const Stmt *Parent,
9167
ASTContext &Context) {
@@ -105,9 +81,10 @@ void fixGenericExprCastToBool(DiagnosticBuilder &Diag,
10581

10682
const Expr *SubExpr = Cast->getSubExpr();
10783

108-
bool NeedInnerParens = areParensNeededForStatement(SubExpr);
84+
bool NeedInnerParens =
85+
SubExpr != nullptr && utils::fixit::areParensNeededForStatement(*SubExpr);
10986
bool NeedOuterParens =
110-
Parent != nullptr && areParensNeededForStatement(Parent);
87+
Parent != nullptr && utils::fixit::areParensNeededForStatement(*Parent);
11188

11289
std::string StartLocInsertion;
11390

@@ -364,7 +341,7 @@ void ImplicitBoolConversionCheck::handleCastToBool(const ImplicitCastExpr *Cast,
364341
return;
365342
}
366343

367-
auto Diag = diag(Cast->getBeginLoc(), "implicit conversion %0 -> bool")
344+
auto Diag = diag(Cast->getBeginLoc(), "implicit conversion %0 -> 'bool'")
368345
<< Cast->getSubExpr()->getType();
369346

370347
StringRef EquivalentLiteral =
@@ -381,7 +358,7 @@ void ImplicitBoolConversionCheck::handleCastFromBool(
381358
ASTContext &Context) {
382359
QualType DestType =
383360
NextImplicitCast ? NextImplicitCast->getType() : Cast->getType();
384-
auto Diag = diag(Cast->getBeginLoc(), "implicit conversion bool -> %0")
361+
auto Diag = diag(Cast->getBeginLoc(), "implicit conversion 'bool' -> %0")
385362
<< DestType;
386363

387364
if (const auto *BoolLiteral =

clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,40 @@ std::optional<FixItHint> addQualifierToVarDecl(const VarDecl &Var,
224224
return std::nullopt;
225225
}
226226

227+
bool areParensNeededForStatement(const Stmt &Node) {
228+
if (isa<ParenExpr>(&Node))
229+
return false;
230+
231+
if (isa<clang::BinaryOperator>(&Node) || isa<UnaryOperator>(&Node))
232+
return true;
233+
234+
if (isa<clang::ConditionalOperator>(&Node) ||
235+
isa<BinaryConditionalOperator>(&Node))
236+
return true;
237+
238+
if (const auto *Op = dyn_cast<CXXOperatorCallExpr>(&Node)) {
239+
switch (Op->getOperator()) {
240+
case OO_PlusPlus:
241+
[[fallthrough]];
242+
case OO_MinusMinus:
243+
return Op->getNumArgs() != 2;
244+
case OO_Call:
245+
[[fallthrough]];
246+
case OO_Subscript:
247+
[[fallthrough]];
248+
case OO_Arrow:
249+
return false;
250+
default:
251+
return true;
252+
};
253+
}
254+
255+
if (isa<CStyleCastExpr>(&Node))
256+
return true;
257+
258+
return false;
259+
}
260+
227261
// Return true if expr needs to be put in parens when it is an argument of a
228262
// prefix unary operator, e.g. when it is a binary or ternary operator
229263
// syntactically.

clang-tools-extra/clang-tidy/utils/FixItHintUtils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ addQualifierToVarDecl(const VarDecl &Var, const ASTContext &Context,
4747

4848
// \brief Format a pointer to an expression
4949
std::string formatDereference(const Expr &ExprNode, const ASTContext &Context);
50+
51+
// \brief Checks whatever a expression require extra () to be always used in
52+
// safe way in any other expression.
53+
bool areParensNeededForStatement(const Stmt &Node);
5054
} // namespace clang::tidy::utils::fixit
5155

5256
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_FIXITHINTUTILS_H

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,10 @@ Changes in existing checks
447447
<clang-tidy/checks/performance/faster-string-find>` check to properly escape
448448
single quotes.
449449

450+
- Improved :doc:`performance-for-range-copy
451+
<clang-tidy/checks/performance/for-range-copy>` check to handle cases where
452+
the loop variable is a structured binding.
453+
450454
- Improved :doc:`performance-noexcept-move-constructor
451455
<clang-tidy/checks/performance/noexcept-move-constructor>` to better handle
452456
conditional ``noexcept`` expressions, eliminating false-positives.
@@ -498,8 +502,8 @@ Changes in existing checks
498502
<clang-tidy/checks/readability/implicit-bool-conversion>` check to take
499503
do-while loops into account for the `AllowIntegerConditions` and
500504
`AllowPointerConditions` options. It also now provides more consistent
501-
suggestions when parentheses are added to the return value. It also ignores
502-
false-positives for comparison containing bool bitfield.
505+
suggestions when parentheses are added to the return value or expressions.
506+
It also ignores false-positives for comparison containing bool bitfield.
503507

504508
- Improved :doc:`readability-misleading-indentation
505509
<clang-tidy/checks/readability/misleading-indentation>` check to ignore

clang-tools-extra/test/clang-tidy/checkers/performance/for-range-copy.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ struct S {
4747
S &operator=(const S &);
4848
};
4949

50+
struct Point {
51+
~Point() {}
52+
int x, y;
53+
};
54+
5055
struct Convertible {
5156
operator S() const {
5257
return S();
@@ -87,6 +92,10 @@ void instantiated() {
8792
// CHECK-MESSAGES: [[@LINE-1]]:16: warning: the loop variable's type is {{.*}}
8893
// CHECK-FIXES: {{^}} for (const S& S2 : View<Iterator<S>>()) {}
8994

95+
for (const auto [X, Y] : View<Iterator<Point>>()) {}
96+
// CHECK-MESSAGES: [[@LINE-1]]:19: warning: the loop variable's type is
97+
// CHECK-FIXES: {{^}} for (const auto& [X, Y] : View<Iterator<Point>>()) {}
98+
9099
for (const T T2 : View<Iterator<T>>()) {}
91100
// CHECK-MESSAGES: [[@LINE-1]]:16: warning: the loop variable's type is {{.*}}
92101
// CHECK-FIXES: {{^}} for (const T& T2 : View<Iterator<T>>()) {}
@@ -123,11 +132,6 @@ struct Mutable {
123132
~Mutable() {}
124133
};
125134

126-
struct Point {
127-
~Point() {}
128-
int x, y;
129-
};
130-
131135
Mutable& operator<<(Mutable &Out, bool B) {
132136
Out.setBool(B);
133137
return Out;
@@ -144,6 +148,7 @@ void useByValue(Mutable M);
144148
void useByConstValue(const Mutable M);
145149
void mutate(Mutable *M);
146150
void mutate(Mutable &M);
151+
void mutate(int &);
147152
void onceConstOnceMutated(const Mutable &M1, Mutable &M2);
148153

149154
void negativeVariableIsMutated() {
@@ -234,6 +239,22 @@ void positiveOnlyAccessedFieldAsConst() {
234239
}
235240
}
236241

242+
void positiveOnlyUsedAsConstBinding() {
243+
for (auto [X, Y] : View<Iterator<Point>>()) {
244+
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but
245+
// CHECK-FIXES: for (const auto& [X, Y] : View<Iterator<Point>>()) {
246+
use(X);
247+
use(Y);
248+
}
249+
}
250+
251+
void negativeMutatedBinding() {
252+
for (auto [X, Y] : View<Iterator<Point>>()) {
253+
use(X);
254+
mutate(Y);
255+
}
256+
}
257+
237258
void positiveOnlyUsedInCopyConstructor() {
238259
for (auto A : View<Iterator<Mutable>>()) {
239260
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]

clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-allow-in-conditions.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct Struct {
1919
void regularImplicitConversionIntegerToBoolIsNotIgnored() {
2020
int integer = 0;
2121
functionTaking<bool>(integer);
22-
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool [readability-implicit-bool-conversion]
22+
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' [readability-implicit-bool-conversion]
2323
// CHECK-FIXES: functionTaking<bool>(integer != 0);
2424
}
2525

@@ -54,12 +54,12 @@ void implicitConversionIntegerToBoolInConditionalsIsAllowed() {
5454
void regularImplicitConversionPointerToBoolIsNotIgnored() {
5555
int* pointer = nullptr;
5656
functionTaking<bool>(pointer);
57-
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> bool
57+
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> 'bool'
5858
// CHECK-FIXES: functionTaking<bool>(pointer != nullptr);
5959

6060
int Struct::* memberPointer = &Struct::member;
6161
functionTaking<bool>(memberPointer);
62-
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int Struct::*' -> bool
62+
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int Struct::*' -> 'bool'
6363
// CHECK-FIXES: functionTaking<bool>(memberPointer != nullptr);
6464
}
6565

clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-cxx98.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,31 @@ struct Struct {
1515
void useOldNullMacroInReplacements() {
1616
int* pointer = NULL;
1717
functionTaking<bool>(pointer);
18-
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> bool [readability-implicit-bool-conversion]
18+
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> 'bool' [readability-implicit-bool-conversion]
1919
// CHECK-FIXES: functionTaking<bool>(pointer != 0);
2020

2121
int Struct::* memberPointer = NULL;
2222
functionTaking<bool>(!memberPointer);
23-
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion 'int Struct::*' -> bool
23+
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion 'int Struct::*' -> 'bool'
2424
// CHECK-FIXES: functionTaking<bool>(memberPointer == 0);
2525
}
2626

2727
void fixFalseLiteralConvertingToNullPointer() {
2828
functionTaking<int*>(false);
29-
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion bool -> 'int *'
29+
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'bool' -> 'int *'
3030
// CHECK-FIXES: functionTaking<int*>(0);
3131

3232
int* pointer = NULL;
3333
if (pointer == false) {}
34-
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: implicit conversion bool -> 'int *'
34+
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: implicit conversion 'bool' -> 'int *'
3535
// CHECK-FIXES: if (pointer == 0) {}
3636

3737
functionTaking<int Struct::*>(false);
38-
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion bool -> 'int Struct::*'
38+
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'bool' -> 'int Struct::*'
3939
// CHECK-FIXES: functionTaking<int Struct::*>(0);
4040

4141
int Struct::* memberPointer = NULL;
4242
if (memberPointer != false) {}
43-
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion bool -> 'int Struct::*'
43+
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'bool' -> 'int Struct::*'
4444
// CHECK-FIXES: if (memberPointer != 0) {}
4545
}

0 commit comments

Comments
 (0)