@@ -712,6 +712,8 @@ class EffectsHandlingWalker : public ASTWalker {
712712 }
713713 } else if (auto TE = dyn_cast<MakeTemporarilyEscapableExpr>(E)) {
714714 recurse = asImpl ().checkTemporarilyEscapable (TE);
715+ } else if (auto OSE = dyn_cast<ObjCSelectorExpr>(E)) {
716+ recurse = asImpl ().checkObjCSelector (OSE);
715717 }
716718
717719 // Error handling validation (via checkTopLevelEffects) happens after
@@ -2268,6 +2270,10 @@ class ApplyClassifier {
22682270 return ShouldRecurse;
22692271 }
22702272
2273+ ShouldRecurse_t checkObjCSelector (ObjCSelectorExpr *E) {
2274+ return ShouldNotRecurse;
2275+ }
2276+
22712277 ConditionalEffectKind checkExhaustiveDoBody (DoCatchStmt *S) {
22722278 // All errors thrown by the do body are caught, but any errors thrown
22732279 // by the catch bodies are bounded by the throwing kind of the do body.
@@ -2417,6 +2423,10 @@ class ApplyClassifier {
24172423 return ShouldRecurse;
24182424 }
24192425
2426+ ShouldRecurse_t checkObjCSelector (ObjCSelectorExpr *E) {
2427+ return ShouldNotRecurse;
2428+ }
2429+
24202430 void visitExprPre (Expr *expr) { return ; }
24212431 };
24222432
@@ -2534,6 +2544,10 @@ class ApplyClassifier {
25342544 return ShouldRecurse;
25352545 }
25362546
2547+ ShouldRecurse_t checkObjCSelector (ObjCSelectorExpr *E) {
2548+ return ShouldNotRecurse;
2549+ }
2550+
25372551 void visitExprPre (Expr *expr) { return ; }
25382552 };
25392553
@@ -3715,6 +3729,12 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
37153729 Self.Flags .set (ContextFlags::InAsyncLet);
37163730 }
37173731
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+
37183738 void refineLocalContext (Context newContext) {
37193739 Self.CurContext = newContext;
37203740 }
@@ -3824,6 +3844,13 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
38243844 OldMaxThrowingKind = std::max (OldMaxThrowingKind, Self.MaxThrowingKind );
38253845 }
38263846
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+
38273854 void preserveCoverageFromOptionalOrForcedTryOperand () {
38283855 OldFlags.mergeFrom (ContextFlags::asyncAwaitFlags (), Self.Flags );
38293856 OldFlags.mergeFrom (ContextFlags::unsafeFlags (), Self.Flags );
@@ -4025,6 +4052,17 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
40254052 return ShouldRecurse;
40264053 }
40274054
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+
40284066 ConditionalEffectKind checkExhaustiveDoBody (DoCatchStmt *S) {
40294067 // This is a context where errors are handled.
40304068 ContextScope scope (*this , CurContext.withHandlesErrors ());
0 commit comments