Skip to content

Commit 1113c14

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 llvm#109056 for background.
1 parent c8fcfe1 commit 1113c14

Some content is hidden

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

57 files changed

+506
-428
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
@@ -1122,6 +1122,8 @@ void maybeAddCalleeArgInfo(const SelectionTree::Node *N, HoverInfo &HI,
11221122
if (const auto *ImplicitCast = CastNode->ASTNode.get<ImplicitCastExpr>()) {
11231123
switch (ImplicitCast->getCastKind()) {
11241124
case CK_NoOp:
1125+
case CK_FunctionPointerConversion:
1126+
case CK_MemberFunctionPointerConversion:
11251127
case CK_DerivedToBase:
11261128
case CK_UncheckedDerivedToBase:
11271129
// 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);

clang/lib/ARCMigrate/TransBlockObjCVariable.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@ class RootBlockObjCVarRewriter :
5353
if (ref->getDecl() == Var) {
5454
if (castE->getCastKind() == CK_LValueToRValue)
5555
return true; // Using the value of the variable.
56-
if (castE->getCastKind() == CK_NoOp && castE->isLValue() &&
57-
Var->getASTContext().getLangOpts().CPlusPlus)
56+
if ((castE->getCastKind() == CK_NoOp ||
57+
castE->getCastKind() == CK_FunctionPointerConversion ||
58+
castE->getCastKind() == CK_MemberFunctionPointerConversion) &&
59+
castE->isLValue() && Var->getASTContext().getLangOpts().CPlusPlus)
5860
return true; // Binding to const C++ reference.
5961
}
6062
}

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
429429
case CK_FunctionToPointerDecay:
430430
case CK_NonAtomicToAtomic:
431431
case CK_NoOp:
432+
case CK_FunctionPointerConversion:
433+
case CK_MemberFunctionPointerConversion:
432434
case CK_UserDefinedConversion:
433435
case CK_AddressSpaceConversion:
434436
return this->delegate(SubExpr);
@@ -3067,6 +3069,8 @@ bool Compiler<Emitter>::VisitCXXNewExpr(const CXXNewExpr *E) {
30673069
for (; auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
30683070
Stripped = ICE->getSubExpr())
30693071
if (ICE->getCastKind() != CK_NoOp &&
3072+
ICE->getCastKind() != CK_FunctionPointerConversion &&
3073+
ICE->getCastKind() != CK_MemberFunctionPointerConversion &&
30703074
ICE->getCastKind() != CK_IntegralCast)
30713075
break;
30723076

clang/lib/AST/Expr.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ const Expr *Expr::skipRValueSubobjectAdjustments(
9898
continue;
9999
}
100100

101-
if (CE->getCastKind() == CK_NoOp) {
101+
if (CE->getCastKind() == CK_NoOp ||
102+
CE->getCastKind() == CK_FunctionPointerConversion ||
103+
CE->getCastKind() == CK_MemberFunctionPointerConversion) {
102104
E = CE->getSubExpr();
103105
continue;
104106
}
@@ -1926,6 +1928,8 @@ bool CastExpr::CastConsistency() const {
19261928
case CK_Dependent:
19271929
case CK_LValueToRValue:
19281930
case CK_NoOp:
1931+
case CK_FunctionPointerConversion:
1932+
case CK_MemberFunctionPointerConversion:
19291933
case CK_AtomicToNonAtomic:
19301934
case CK_NonAtomicToAtomic:
19311935
case CK_PointerToBoolean:
@@ -3188,7 +3192,9 @@ static const Expr *skipTemporaryBindingsNoOpCastsAndParens(const Expr *E) {
31883192
E = M->getSubExpr();
31893193

31903194
while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
3191-
if (ICE->getCastKind() == CK_NoOp)
3195+
if (ICE->getCastKind() == CK_NoOp ||
3196+
ICE->getCastKind() == CK_FunctionPointerConversion ||
3197+
ICE->getCastKind() == CK_MemberFunctionPointerConversion)
31923198
E = ICE->getSubExpr();
31933199
else
31943200
break;
@@ -3198,7 +3204,9 @@ static const Expr *skipTemporaryBindingsNoOpCastsAndParens(const Expr *E) {
31983204
E = BE->getSubExpr();
31993205

32003206
while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
3201-
if (ICE->getCastKind() == CK_NoOp)
3207+
if (ICE->getCastKind() == CK_NoOp ||
3208+
ICE->getCastKind() == CK_FunctionPointerConversion ||
3209+
ICE->getCastKind() == CK_MemberFunctionPointerConversion)
32023210
E = ICE->getSubExpr();
32033211
else
32043212
break;
@@ -3263,6 +3271,8 @@ bool Expr::isImplicitCXXThis() const {
32633271

32643272
if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
32653273
if (ICE->getCastKind() == CK_NoOp ||
3274+
ICE->getCastKind() == CK_FunctionPointerConversion ||
3275+
ICE->getCastKind() == CK_MemberFunctionPointerConversion ||
32663276
ICE->getCastKind() == CK_LValueToRValue ||
32673277
ICE->getCastKind() == CK_DerivedToBase ||
32683278
ICE->getCastKind() == CK_UncheckedDerivedToBase) {
@@ -3478,6 +3488,8 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
34783488

34793489
// Handle misc casts we want to ignore.
34803490
if (CE->getCastKind() == CK_NoOp ||
3491+
CE->getCastKind() == CK_FunctionPointerConversion ||
3492+
CE->getCastKind() == CK_MemberFunctionPointerConversion ||
34813493
CE->getCastKind() == CK_LValueToRValue ||
34823494
CE->getCastKind() == CK_ToUnion ||
34833495
CE->getCastKind() == CK_ConstructorConversion ||
@@ -4113,7 +4125,10 @@ FieldDecl *Expr::getSourceBitField() {
41134125

41144126
while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
41154127
if (ICE->getCastKind() == CK_LValueToRValue ||
4116-
(ICE->isGLValue() && ICE->getCastKind() == CK_NoOp))
4128+
(ICE->isGLValue() &&
4129+
(ICE->getCastKind() == CK_NoOp ||
4130+
ICE->getCastKind() == CK_FunctionPointerConversion ||
4131+
ICE->getCastKind() == CK_MemberFunctionPointerConversion)))
41174132
E = ICE->getSubExpr()->IgnoreParens();
41184133
else
41194134
break;
@@ -4167,7 +4182,10 @@ bool Expr::refersToVectorElement() const {
41674182
const Expr *E = this->IgnoreParens();
41684183

41694184
while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
4170-
if (ICE->isGLValue() && ICE->getCastKind() == CK_NoOp)
4185+
if (ICE->isGLValue() &&
4186+
(ICE->getCastKind() == CK_NoOp ||
4187+
ICE->getCastKind() == CK_FunctionPointerConversion ||
4188+
ICE->getCastKind() == CK_MemberFunctionPointerConversion))
41714189
E = ICE->getSubExpr()->IgnoreParens();
41724190
else
41734191
break;

clang/lib/AST/ExprCXX.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,12 @@ QualType CXXDeleteExpr::getDestroyedType() const {
344344
while (const auto *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
345345
if (ICE->getCastKind() == CK_DerivedToBase ||
346346
ICE->getCastKind() == CK_UncheckedDerivedToBase ||
347-
ICE->getCastKind() == CK_NoOp) {
347+
ICE->getCastKind() == CK_NoOp ||
348+
ICE->getCastKind() == CK_FunctionPointerConversion ||
349+
ICE->getCastKind() == CK_MemberFunctionPointerConversion) {
348350
assert((ICE->getCastKind() == CK_NoOp ||
351+
ICE->getCastKind() == CK_FunctionPointerConversion ||
352+
ICE->getCastKind() == CK_MemberFunctionPointerConversion ||
349353
getOperatorDelete()->isDestroyingOperatorDelete()) &&
350354
"only a destroying operator delete can have a converted arg");
351355
Arg = ICE->getSubExpr();

clang/lib/AST/ExprConstant.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6247,7 +6247,9 @@ static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info,
62476247
} else if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
62486248
// Step over a derived-to-base conversion.
62496249
E = ICE->getSubExpr();
6250-
if (ICE->getCastKind() == CK_NoOp)
6250+
if (ICE->getCastKind() == CK_NoOp ||
6251+
ICE->getCastKind() == CK_FunctionPointerConversion ||
6252+
ICE->getCastKind() == CK_MemberFunctionPointerConversion)
62516253
continue;
62526254
if (ICE->getCastKind() != CK_DerivedToBase &&
62536255
ICE->getCastKind() != CK_UncheckedDerivedToBase)
@@ -8301,6 +8303,8 @@ class ExprEvaluatorBase
83018303
}
83028304

83038305
case CK_NoOp:
8306+
case CK_FunctionPointerConversion:
8307+
case CK_MemberFunctionPointerConversion:
83048308
case CK_UserDefinedConversion:
83058309
return StmtVisitorTy::Visit(E->getSubExpr());
83068310

@@ -10074,6 +10078,8 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
1007410078
for (; auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
1007510079
Stripped = ICE->getSubExpr())
1007610080
if (ICE->getCastKind() != CK_NoOp &&
10081+
ICE->getCastKind() != CK_FunctionPointerConversion &&
10082+
ICE->getCastKind() != CK_MemberFunctionPointerConversion &&
1007710083
ICE->getCastKind() != CK_IntegralCast)
1007810084
break;
1007910085

@@ -12210,8 +12216,9 @@ static const Expr *ignorePointerCastsAndParens(const Expr *E) {
1221012216
// We only conservatively allow a few kinds of casts, because this code is
1221112217
// inherently a simple solution that seeks to support the common case.
1221212218
auto CastKind = Cast->getCastKind();
12213-
if (CastKind != CK_NoOp && CastKind != CK_BitCast &&
12214-
CastKind != CK_AddressSpaceConversion)
12219+
if (CastKind != CK_NoOp && CastKind != CK_FunctionPointerConversion &&
12220+
CastKind != CK_MemberFunctionPointerConversion &&
12221+
CastKind != CK_BitCast && CastKind != CK_AddressSpaceConversion)
1221512222
return NoParens;
1221612223

1221712224
const auto *SubExpr = Cast->getSubExpr();
@@ -14448,6 +14455,8 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
1444814455
QualType SrcType = SubExpr->getType();
1444914456

1445014457
switch (E->getCastKind()) {
14458+
case CK_FunctionPointerConversion:
14459+
case CK_MemberFunctionPointerConversion:
1445114460
case CK_BaseToDerived:
1445214461
case CK_DerivedToBase:
1445314462
case CK_UncheckedDerivedToBase:
@@ -15288,6 +15297,8 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
1528815297
case CK_BaseToDerived:
1528915298
case CK_DerivedToBase:
1529015299
case CK_UncheckedDerivedToBase:
15300+
case CK_FunctionPointerConversion:
15301+
case CK_MemberFunctionPointerConversion:
1529115302
case CK_Dynamic:
1529215303
case CK_ToUnion:
1529315304
case CK_ArrayToPointerDecay:

clang/lib/Analysis/CFG.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,6 +1491,8 @@ void CFGBuilder::findConstructionContexts(
14911491
// Should we support other implicit cast kinds?
14921492
switch (Cast->getCastKind()) {
14931493
case CK_NoOp:
1494+
case CK_FunctionPointerConversion:
1495+
case CK_MemberFunctionPointerConversion:
14941496
case CK_ConstructorConversion:
14951497
findConstructionContexts(Layer, Cast->getSubExpr());
14961498
break;

clang/lib/Analysis/ExprMutationAnalyzer.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -377,11 +377,13 @@ ExprMutationAnalyzer::Analyzer::findDirectMutation(const Expr *Exp) {
377377
// We're assuming 'Exp' is mutated as soon as its address is taken, though in
378378
// theory we can follow the pointer and see whether it escaped `Stm` or is
379379
// dereferenced and then mutated. This is left for future improvements.
380-
const auto AsAmpersandOperand =
381-
unaryOperator(hasOperatorName("&"),
382-
// A NoOp implicit cast is adding const.
383-
unless(hasParent(implicitCastExpr(hasCastKind(CK_NoOp)))),
384-
hasUnaryOperand(canResolveToExpr(Exp)));
380+
const auto AsAmpersandOperand = unaryOperator(
381+
hasOperatorName("&"),
382+
// A NoOp implicit cast is adding const.
383+
unless(hasParent(implicitCastExpr(
384+
anyOf(hasCastKind(CK_NoOp), hasCastKind(CK_FunctionPointerConversion),
385+
hasCastKind(CK_MemberFunctionPointerConversion))))),
386+
hasUnaryOperand(canResolveToExpr(Exp)));
385387
const auto AsPointerFromArrayDecay = castExpr(
386388
hasCastKind(CK_ArrayToPointerDecay),
387389
unless(hasParent(arraySubscriptExpr())), has(canResolveToExpr(Exp)));

clang/lib/Analysis/FlowSensitive/Transfer.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,9 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
322322
case CK_UserDefinedConversion:
323323
// FIXME: Add tests that excercise CK_UncheckedDerivedToBase,
324324
// CK_ConstructorConversion, and CK_UserDefinedConversion.
325-
case CK_NoOp: {
325+
case CK_NoOp:
326+
case CK_FunctionPointerConversion:
327+
case CK_MemberFunctionPointerConversion: {
326328
// FIXME: Consider making `Environment::getStorageLocation` skip noop
327329
// expressions (this and other similar expressions in the file) instead
328330
// of assigning them storage locations.
@@ -679,7 +681,9 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
679681
}
680682

681683
void VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) {
682-
if (S->getCastKind() == CK_NoOp) {
684+
if (S->getCastKind() == CK_NoOp ||
685+
S->getCastKind() == CK_FunctionPointerConversion ||
686+
S->getCastKind() == CK_MemberFunctionPointerConversion) {
683687
const Expr *SubExpr = S->getSubExpr();
684688
assert(SubExpr != nullptr);
685689

clang/lib/Analysis/ThreadSafety.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2103,8 +2103,10 @@ void BuildLockset::VisitCXXConstructExpr(const CXXConstructExpr *Exp) {
21032103

21042104
static const Expr *UnpackConstruction(const Expr *E) {
21052105
if (auto *CE = dyn_cast<CastExpr>(E))
2106-
if (CE->getCastKind() == CK_NoOp)
2107-
E = CE->getSubExpr()->IgnoreParens();
2106+
if (CE->getCastKind() == CK_NoOp ||
2107+
CE->getCastKind() == CK_FunctionPointerConversion ||
2108+
CE->getCastKind() == CK_MemberFunctionPointerConversion)
2109+
E = CE->getSubExpr()->IgnoreParens();
21082110
if (auto *CE = dyn_cast<CastExpr>(E))
21092111
if (CE->getCastKind() == CK_ConstructorConversion ||
21102112
CE->getCastKind() == CK_UserDefinedConversion)

clang/lib/Analysis/ThreadSafetyCommon.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,8 @@ til::SExpr *SExprBuilder::translateCastExpr(const CastExpr *CE,
620620
// return new (Arena) til::Load(E0);
621621
}
622622
case CK_NoOp:
623+
case CK_FunctionPointerConversion:
624+
case CK_MemberFunctionPointerConversion:
623625
case CK_DerivedToBase:
624626
case CK_UncheckedDerivedToBase:
625627
case CK_ArrayToPointerDecay:

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,8 @@ static bool tryEmitARCCopyWeakInit(CodeGenFunction &CGF,
697697
switch (castExpr->getCastKind()) {
698698
// Look through casts that don't require representation changes.
699699
case CK_NoOp:
700+
case CK_FunctionPointerConversion:
701+
case CK_MemberFunctionPointerConversion:
700702
case CK_BitCast:
701703
case CK_BlockPointerToObjCPointerCast:
702704
needsCast = true;

0 commit comments

Comments
 (0)