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