@@ -713,6 +713,8 @@ class EffectsHandlingWalker : public ASTWalker {
713
713
}
714
714
} else if (auto TE = dyn_cast<MakeTemporarilyEscapableExpr>(E)) {
715
715
recurse = asImpl ().checkTemporarilyEscapable (TE);
716
+ } else if (auto OSE = dyn_cast<ObjCSelectorExpr>(E)) {
717
+ recurse = asImpl ().checkObjCSelector (OSE);
716
718
}
717
719
718
720
// Error handling validation (via checkTopLevelEffects) happens after
@@ -2269,6 +2271,10 @@ class ApplyClassifier {
2269
2271
return ShouldRecurse;
2270
2272
}
2271
2273
2274
+ ShouldRecurse_t checkObjCSelector (ObjCSelectorExpr *E) {
2275
+ return ShouldNotRecurse;
2276
+ }
2277
+
2272
2278
ConditionalEffectKind checkExhaustiveDoBody (DoCatchStmt *S) {
2273
2279
// All errors thrown by the do body are caught, but any errors thrown
2274
2280
// by the catch bodies are bounded by the throwing kind of the do body.
@@ -2418,6 +2424,10 @@ class ApplyClassifier {
2418
2424
return ShouldRecurse;
2419
2425
}
2420
2426
2427
+ ShouldRecurse_t checkObjCSelector (ObjCSelectorExpr *E) {
2428
+ return ShouldNotRecurse;
2429
+ }
2430
+
2421
2431
void visitExprPre (Expr *expr) { return ; }
2422
2432
};
2423
2433
@@ -2535,6 +2545,10 @@ class ApplyClassifier {
2535
2545
return ShouldRecurse;
2536
2546
}
2537
2547
2548
+ ShouldRecurse_t checkObjCSelector (ObjCSelectorExpr *E) {
2549
+ return ShouldNotRecurse;
2550
+ }
2551
+
2538
2552
void visitExprPre (Expr *expr) { return ; }
2539
2553
};
2540
2554
@@ -3716,6 +3730,12 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
3716
3730
Self.Flags .set (ContextFlags::InAsyncLet);
3717
3731
}
3718
3732
3733
+ // / Enter a subexpression that's never exected.
3734
+ void enterNonExecuting () {
3735
+ Self.Flags .set (ContextFlags::IsTryCovered);
3736
+ Self.Flags .set (ContextFlags::IsAsyncCovered);
3737
+ }
3738
+
3719
3739
void refineLocalContext (Context newContext) {
3720
3740
Self.CurContext = newContext;
3721
3741
}
@@ -3825,6 +3845,13 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
3825
3845
OldMaxThrowingKind = std::max (OldMaxThrowingKind, Self.MaxThrowingKind );
3826
3846
}
3827
3847
3848
+ void preserveCoverageFromNonExecutingOperand () {
3849
+ OldFlags.mergeFrom (ContextFlags::asyncAwaitFlags (), Self.Flags );
3850
+ OldFlags.mergeFrom (ContextFlags::throwFlags (), Self.Flags );
3851
+ OldFlags.mergeFrom (ContextFlags::unsafeFlags (), Self.Flags );
3852
+ OldMaxThrowingKind = std::max (OldMaxThrowingKind, Self.MaxThrowingKind );
3853
+ }
3854
+
3828
3855
void preserveCoverageFromOptionalOrForcedTryOperand () {
3829
3856
OldFlags.mergeFrom (ContextFlags::asyncAwaitFlags (), Self.Flags );
3830
3857
OldFlags.mergeFrom (ContextFlags::unsafeFlags (), Self.Flags );
@@ -4026,6 +4053,17 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
4026
4053
return ShouldRecurse;
4027
4054
}
4028
4055
4056
+ ShouldRecurse_t checkObjCSelector (ObjCSelectorExpr *E) {
4057
+ // Walk the operand.
4058
+ ContextScope scope (*this , std::nullopt);
4059
+ scope.enterNonExecuting ();
4060
+
4061
+ E->getSubExpr ()->walk (*this );
4062
+
4063
+ scope.preserveCoverageFromNonExecutingOperand ();
4064
+ return ShouldNotRecurse;
4065
+ }
4066
+
4029
4067
ConditionalEffectKind checkExhaustiveDoBody (DoCatchStmt *S) {
4030
4068
// This is a context where errors are handled.
4031
4069
ContextScope scope (*this , CurContext.withHandlesErrors ());
0 commit comments