@@ -713,6 +713,8 @@ class EffectsHandlingWalker : public ASTWalker {
713713 }
714714 } else if (auto TE = dyn_cast<MakeTemporarilyEscapableExpr>(E)) {
715715 recurse = asImpl ().checkTemporarilyEscapable (TE);
716+ } else if (auto OSE = dyn_cast<ObjCSelectorExpr>(E)) {
717+ recurse = asImpl ().checkObjCSelector (OSE);
716718 }
717719
718720 // Error handling validation (via checkTopLevelEffects) happens after
@@ -2269,6 +2271,10 @@ class ApplyClassifier {
22692271 return ShouldRecurse;
22702272 }
22712273
2274+ ShouldRecurse_t checkObjCSelector (ObjCSelectorExpr *E) {
2275+ return ShouldNotRecurse;
2276+ }
2277+
22722278 ConditionalEffectKind checkExhaustiveDoBody (DoCatchStmt *S) {
22732279 // All errors thrown by the do body are caught, but any errors thrown
22742280 // by the catch bodies are bounded by the throwing kind of the do body.
@@ -2418,6 +2424,10 @@ class ApplyClassifier {
24182424 return ShouldRecurse;
24192425 }
24202426
2427+ ShouldRecurse_t checkObjCSelector (ObjCSelectorExpr *E) {
2428+ return ShouldNotRecurse;
2429+ }
2430+
24212431 void visitExprPre (Expr *expr) { return ; }
24222432 };
24232433
@@ -2535,6 +2545,10 @@ class ApplyClassifier {
25352545 return ShouldRecurse;
25362546 }
25372547
2548+ ShouldRecurse_t checkObjCSelector (ObjCSelectorExpr *E) {
2549+ return ShouldNotRecurse;
2550+ }
2551+
25382552 void visitExprPre (Expr *expr) { return ; }
25392553 };
25402554
@@ -3716,6 +3730,12 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
37163730 Self.Flags .set (ContextFlags::InAsyncLet);
37173731 }
37183732
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+
37193739 void refineLocalContext (Context newContext) {
37203740 Self.CurContext = newContext;
37213741 }
@@ -3825,6 +3845,13 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
38253845 OldMaxThrowingKind = std::max (OldMaxThrowingKind, Self.MaxThrowingKind );
38263846 }
38273847
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+
38283855 void preserveCoverageFromOptionalOrForcedTryOperand () {
38293856 OldFlags.mergeFrom (ContextFlags::asyncAwaitFlags (), Self.Flags );
38303857 OldFlags.mergeFrom (ContextFlags::unsafeFlags (), Self.Flags );
@@ -4026,6 +4053,17 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
40264053 return ShouldRecurse;
40274054 }
40284055
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+
40294067 ConditionalEffectKind checkExhaustiveDoBody (DoCatchStmt *S) {
40304068 // This is a context where errors are handled.
40314069 ContextScope scope (*this , CurContext.withHandlesErrors ());
0 commit comments