@@ -448,6 +448,8 @@ class EffectsHandlingWalker : public ASTWalker {
448
448
recurse = asImpl ().checkInterpolatedStringLiteral (interpolated);
449
449
} else if (auto macroExpansionExpr = dyn_cast<MacroExpansionExpr>(E)) {
450
450
recurse = ShouldRecurse;
451
+ } else if (auto *SVE = dyn_cast<SingleValueStmtExpr>(E)) {
452
+ recurse = asImpl ().checkSingleValueStmtExpr (SVE);
451
453
}
452
454
// Error handling validation (via checkTopLevelEffects) happens after
453
455
// type checking. If an unchecked expression is still around, the code was
@@ -1076,6 +1078,10 @@ class ApplyClassifier {
1076
1078
return ShouldRecurse;
1077
1079
}
1078
1080
1081
+ ShouldRecurse_t checkSingleValueStmtExpr (SingleValueStmtExpr *SVE) {
1082
+ return ShouldRecurse;
1083
+ }
1084
+
1079
1085
ConditionalEffectKind checkExhaustiveDoBody (DoCatchStmt *S) {
1080
1086
// All errors thrown by the do body are caught, but any errors thrown
1081
1087
// by the catch bodies are bounded by the throwing kind of the do body.
@@ -1196,6 +1202,10 @@ class ApplyClassifier {
1196
1202
return ShouldRecurse;
1197
1203
}
1198
1204
1205
+ ShouldRecurse_t checkSingleValueStmtExpr (SingleValueStmtExpr *SVE) {
1206
+ return ShouldRecurse;
1207
+ }
1208
+
1199
1209
void visitExprPre (Expr *expr) { return ; }
1200
1210
};
1201
1211
@@ -2211,6 +2221,15 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
2211
2221
// 'async'.
2212
2222
}
2213
2223
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
+
2214
2233
void preserveCoverageFromNonExhaustiveCatch () {
2215
2234
OldFlags.mergeFrom (ContextFlags::HasAnyThrowSite, Self.Flags );
2216
2235
OldMaxThrowingKind = std::max (OldMaxThrowingKind, Self.MaxThrowingKind );
@@ -2354,6 +2373,17 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
2354
2373
return ShouldNotRecurse;
2355
2374
}
2356
2375
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
+
2357
2387
ConditionalEffectKind checkExhaustiveDoBody (DoCatchStmt *S) {
2358
2388
// This is a context where errors are handled.
2359
2389
ContextScope scope (*this , CurContext.withHandlesErrors ());
0 commit comments