@@ -448,6 +448,8 @@ class EffectsHandlingWalker : public ASTWalker {
448448 recurse = asImpl ().checkInterpolatedStringLiteral (interpolated);
449449 } else if (auto macroExpansionExpr = dyn_cast<MacroExpansionExpr>(E)) {
450450 recurse = ShouldRecurse;
451+ } else if (auto *SVE = dyn_cast<SingleValueStmtExpr>(E)) {
452+ recurse = asImpl ().checkSingleValueStmtExpr (SVE);
451453 }
452454 // Error handling validation (via checkTopLevelEffects) happens after
453455 // type checking. If an unchecked expression is still around, the code was
@@ -1076,6 +1078,10 @@ class ApplyClassifier {
10761078 return ShouldRecurse;
10771079 }
10781080
1081+ ShouldRecurse_t checkSingleValueStmtExpr (SingleValueStmtExpr *SVE) {
1082+ return ShouldRecurse;
1083+ }
1084+
10791085 ConditionalEffectKind checkExhaustiveDoBody (DoCatchStmt *S) {
10801086 // All errors thrown by the do body are caught, but any errors thrown
10811087 // by the catch bodies are bounded by the throwing kind of the do body.
@@ -1196,6 +1202,10 @@ class ApplyClassifier {
11961202 return ShouldRecurse;
11971203 }
11981204
1205+ ShouldRecurse_t checkSingleValueStmtExpr (SingleValueStmtExpr *SVE) {
1206+ return ShouldRecurse;
1207+ }
1208+
11991209 void visitExprPre (Expr *expr) { return ; }
12001210 };
12011211
@@ -2211,6 +2221,15 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
22112221 // 'async'.
22122222 }
22132223
2224+ void preserveCoverageFromSingleValueStmtExpr () {
2225+ // We need to preserve whether we saw any throwing sites, to avoid warning
2226+ // on 'do { let x = if .random() { try ... } else { ... } } catch { ... }'
2227+ OldFlags.mergeFrom (ContextFlags::HasAnyThrowSite, Self.Flags );
2228+
2229+ // We need to preserve the throwing kind to correctly handle rethrows.
2230+ OldMaxThrowingKind = std::max (OldMaxThrowingKind, Self.MaxThrowingKind );
2231+ }
2232+
22142233 void preserveCoverageFromNonExhaustiveCatch () {
22152234 OldFlags.mergeFrom (ContextFlags::HasAnyThrowSite, Self.Flags );
22162235 OldMaxThrowingKind = std::max (OldMaxThrowingKind, Self.MaxThrowingKind );
@@ -2354,6 +2373,17 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
23542373 return ShouldNotRecurse;
23552374 }
23562375
2376+ ShouldRecurse_t
2377+ checkSingleValueStmtExpr (SingleValueStmtExpr *SVE) {
2378+ // For an if/switch expression, we reset coverage such that a 'try'/'await'
2379+ // does not cover the branches.
2380+ ContextScope scope (*this , /* newContext*/ llvm::None);
2381+ scope.resetCoverage ();
2382+ SVE->getStmt ()->walk (*this );
2383+ scope.preserveCoverageFromSingleValueStmtExpr ();
2384+ return ShouldNotRecurse;
2385+ }
2386+
23572387 ConditionalEffectKind checkExhaustiveDoBody (DoCatchStmt *S) {
23582388 // This is a context where errors are handled.
23592389 ContextScope scope (*this , CurContext.withHandlesErrors ());
0 commit comments