Skip to content

Commit b9a8339

Browse files
committed
[NFC] Add implicit cast kinds for function pointer conversions
The new cast kinds are needed to distinguish between no-op conversions and conversions from pointers to noexcept functions to pointers to functions without noexcept as the latter can cause function pointers to be re-signed on arm64e. See #109056 for background.
1 parent 4db0cc4 commit b9a8339

40 files changed

+193
-36
lines changed

clang-tools-extra/clang-tidy/bugprone/SwappedArgumentsCheck.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ void SwappedArgumentsCheck::registerMatchers(MatchFinder *Finder) {
2727
static const Expr *ignoreNoOpCasts(const Expr *E) {
2828
if (auto *Cast = dyn_cast<CastExpr>(E))
2929
if (Cast->getCastKind() == CK_LValueToRValue ||
30+
Cast->getCastKind() == CK_FunctionPointerConversion ||
31+
Cast->getCastKind() == CK_MemberFunctionPointerConversion ||
3032
Cast->getCastKind() == CK_NoOp)
3133
return ignoreNoOpCasts(Cast->getSubExpr());
3234
return E;

clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@ void ProTypeCstyleCastCheck::check(const MatchFinder::MatchResult &Result) {
9090
return;
9191
}
9292

93-
if (MatchedCast->getCastKind() == CK_NoOp &&
93+
if ((MatchedCast->getCastKind() == CK_NoOp ||
94+
MatchedCast->getCastKind() == CK_FunctionPointerConversion ||
95+
MatchedCast->getCastKind() == CK_MemberFunctionPointerConversion) &&
9496
needsConstCast(SourceType, MatchedCast->getType())) {
9597
diag(MatchedCast->getBeginLoc(),
9698
"do not use C-style cast to cast away constness");

clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,10 @@ void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) {
123123
DestTypeAsWritten->isRecordType() &&
124124
!DestTypeAsWritten->isElaboratedTypeSpecifier();
125125

126-
if (CastExpr->getCastKind() == CK_NoOp && !FnToFnCast) {
126+
if ((CastExpr->getCastKind() == CK_NoOp ||
127+
CastExpr->getCastKind() == CK_FunctionPointerConversion ||
128+
CastExpr->getCastKind() == CK_MemberFunctionPointerConversion) &&
129+
!FnToFnCast) {
127130
// Function pointer/reference casts may be needed to resolve ambiguities in
128131
// case of overloaded functions, so detection of redundant casts is trickier
129132
// in this case. Don't emit "redundant cast" warnings for function
@@ -201,6 +204,8 @@ void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) {
201204
}
202205
return;
203206
case CK_NoOp:
207+
case CK_FunctionPointerConversion:
208+
case CK_MemberFunctionPointerConversion:
204209
if (FnToFnCast) {
205210
ReplaceWithNamedCast("static_cast");
206211
return;

clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,9 @@ static bool canBeModified(ASTContext *Context, const Expr *E) {
500500
if (Parents.size() != 1)
501501
return true;
502502
if (const auto *Cast = Parents[0].get<ImplicitCastExpr>()) {
503-
if ((Cast->getCastKind() == CK_NoOp &&
503+
if (((Cast->getCastKind() == CK_NoOp ||
504+
Cast->getCastKind() == CK_FunctionPointerConversion ||
505+
Cast->getCastKind() == CK_MemberFunctionPointerConversion) &&
504506
Context->hasSameType(Cast->getType(), E->getType().withConst())) ||
505507
(Cast->getCastKind() == CK_LValueToRValue &&
506508
!Cast->getType().isNull() && Cast->getType()->isFundamentalType()))

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ namespace clang::tidy::performance {
2424
// case we skip the first cast expr.
2525
static bool isNonTrivialImplicitCast(const Stmt *ST) {
2626
if (const auto *ICE = dyn_cast<ImplicitCastExpr>(ST)) {
27-
return (ICE->getCastKind() != CK_NoOp) ||
27+
return (ICE->getCastKind() != CK_NoOp &&
28+
ICE->getCastKind() != CK_FunctionPointerConversion &&
29+
ICE->getCastKind() != CK_MemberFunctionPointerConversion) ||
2830
isNonTrivialImplicitCast(ICE->getSubExpr());
2931
}
3032
return false;

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ class FindUsageOfThis : public RecursiveASTVisitor<FindUsageOfThis> {
9797
// (possibly `-UnaryOperator Deref)
9898
// `-CXXThisExpr 'S *' this
9999
bool visitUser(const ImplicitCastExpr *Cast) {
100-
if (Cast->getCastKind() != CK_NoOp)
100+
if (Cast->getCastKind() != CK_NoOp &&
101+
Cast->getCastKind() != CK_FunctionPointerConversion &&
102+
Cast->getCastKind() != CK_MemberFunctionPointerConversion)
101103
return false; // Stop traversal.
102104

103105
// Only allow NoOp cast to 'const S' or 'const S *'.
@@ -159,7 +161,10 @@ class FindUsageOfThis : public RecursiveASTVisitor<FindUsageOfThis> {
159161
if (Cast->getCastKind() == CK_LValueToRValue)
160162
return true;
161163

162-
if (Cast->getCastKind() == CK_NoOp && Cast->getType().isConstQualified())
164+
if ((Cast->getCastKind() == CK_NoOp ||
165+
Cast->getCastKind() == CK_FunctionPointerConversion ||
166+
Cast->getCastKind() == CK_MemberFunctionPointerConversion) &&
167+
Cast->getType().isConstQualified())
163168
return true;
164169
}
165170

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@ AST_MATCHER_P(DeclRefExpr, doesNotMutateObject, int, Indirections) {
240240
case CK_BaseToDerived:
241241
case CK_DerivedToBase:
242242
case CK_UncheckedDerivedToBase:
243+
case CK_FunctionPointerConversion:
244+
case CK_MemberFunctionPointerConversion:
243245
case CK_Dynamic:
244246
case CK_BaseToDerivedMemberPointer:
245247
case CK_DerivedToBaseMemberPointer:

clang-tools-extra/clangd/Hover.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,8 @@ void maybeAddCalleeArgInfo(const SelectionTree::Node *N, HoverInfo &HI,
11181118
if (const auto *ImplicitCast = CastNode->ASTNode.get<ImplicitCastExpr>()) {
11191119
switch (ImplicitCast->getCastKind()) {
11201120
case CK_NoOp:
1121+
case CK_FunctionPointerConversion:
1122+
case CK_MemberFunctionPointerConversion:
11211123
case CK_DerivedToBase:
11221124
case CK_UncheckedDerivedToBase:
11231125
// If it was a reference before, it's still a reference.

clang/include/clang/AST/IgnoreExpr.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ inline Expr *IgnoreBaseCastsSingleStep(Expr *E) {
102102
if (auto *CE = dyn_cast<CastExpr>(E))
103103
if (CE->getCastKind() == CK_DerivedToBase ||
104104
CE->getCastKind() == CK_UncheckedDerivedToBase ||
105-
CE->getCastKind() == CK_NoOp)
105+
CE->getCastKind() == CK_NoOp ||
106+
CE->getCastKind() == CK_FunctionPointerConversion ||
107+
CE->getCastKind() == CK_MemberFunctionPointerConversion)
106108
return CE->getSubExpr();
107109

108110
return E;

clang/include/clang/AST/OperationKinds.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ CAST_OPERATION(LValueToRValue)
8484
/// void () noexcept -> void ()
8585
CAST_OPERATION(NoOp)
8686

87+
/// CK_FunctionPointerConversion - A conversion from pointer/reference to
88+
/// noexcept function to pointer/reference to function.
89+
CAST_OPERATION(FunctionPointerConversion)
90+
91+
/// CK_MemberFunctionPointerConversion - A conversion from pointer to noexcept
92+
/// member function to pointer to member function.
93+
CAST_OPERATION(MemberFunctionPointerConversion)
94+
8795
/// CK_BaseToDerived - A conversion from a C++ class pointer/reference
8896
/// to a derived class pointer/reference.
8997
/// B *b = static_cast<B*>(a);

0 commit comments

Comments
 (0)