@@ -644,7 +644,10 @@ class EffectsHandlingWalker : public ASTWalker {
644644 break ;
645645 }
646646 }
647+ } else if (auto TE = dyn_cast<MakeTemporarilyEscapableExpr>(E)) {
648+ recurse = asImpl ().checkTemporarilyEscapable (TE);
647649 }
650+
648651 // Error handling validation (via checkTopLevelEffects) happens after
649652 // type checking. If an unchecked expression is still around, the code was
650653 // invalid.
@@ -1090,6 +1093,15 @@ class Classification {
10901093 return result;
10911094 }
10921095
1096+ // / Return a potentially-unsafe classification by recording all of the
1097+ // / provided unsafe uses.
1098+ static Classification forUnsafe (ArrayRef<UnsafeUse> unsafeUses) {
1099+ Classification result;
1100+ for (const auto &unsafeUse : unsafeUses)
1101+ result.recordUnsafeUse (unsafeUse);
1102+ return result;
1103+ }
1104+
10931105 // / Return a classification for a given declaration reference.
10941106 static Classification
10951107 forDeclRef (ConcreteDeclRef declRef, ConditionalEffectKind conditionalKind,
@@ -1856,6 +1868,38 @@ class ApplyClassifier {
18561868 return result;
18571869 }
18581870
1871+ Classification classifyTemporarilyEscapable (MakeTemporarilyEscapableExpr *E) {
1872+ auto opaqueValue = E->getOpaqueValue ();
1873+ if (!opaqueValue)
1874+ return Classification ();
1875+
1876+ auto type = opaqueValue->getType ();
1877+ if (!type)
1878+ return Classification ();
1879+
1880+ auto fnType = type->getAs <AnyFunctionType>();
1881+ if (!fnType)
1882+ return Classification ();
1883+
1884+ // Runtime safety checks for temporarily-escapable functions aren't
1885+ // always available.
1886+ switch (fnType->getRepresentation ()) {
1887+ case FunctionTypeRepresentation::Swift:
1888+ // Swift performs runtime checking to ensure that the function did not
1889+ // escape.
1890+ return Classification ();
1891+
1892+ case FunctionTypeRepresentation::Block:
1893+ return Classification::forUnsafe ({UnsafeUse::forTemporarilyEscaping (E)});
1894+
1895+ case FunctionTypeRepresentation::Thin:
1896+ case FunctionTypeRepresentation::CFunctionPointer:
1897+ // Thin and C functions cannot carry any state with them, so escaping
1898+ // the pointers does not introduce a memory-safety issue.
1899+ return Classification ();
1900+ }
1901+ }
1902+
18591903private:
18601904 // / Classify a throwing or async function according to our local
18611905 // / knowledge of its implementation.
@@ -2073,6 +2117,10 @@ class ApplyClassifier {
20732117 return ShouldRecurse;
20742118 }
20752119
2120+ ShouldRecurse_t checkTemporarilyEscapable (MakeTemporarilyEscapableExpr *E) {
2121+ return ShouldRecurse;
2122+ }
2123+
20762124 ConditionalEffectKind checkExhaustiveDoBody (DoCatchStmt *S) {
20772125 // All errors thrown by the do body are caught, but any errors thrown
20782126 // by the catch bodies are bounded by the throwing kind of the do body.
@@ -2214,6 +2262,10 @@ class ApplyClassifier {
22142262 return ShouldRecurse;
22152263 }
22162264
2265+ ShouldRecurse_t checkTemporarilyEscapable (MakeTemporarilyEscapableExpr *E) {
2266+ return ShouldRecurse;
2267+ }
2268+
22172269 void visitExprPre (Expr *expr) { return ; }
22182270 };
22192271
@@ -2327,6 +2379,11 @@ class ApplyClassifier {
23272379 return ShouldRecurse;
23282380 }
23292381
2382+ ShouldRecurse_t checkTemporarilyEscapable (MakeTemporarilyEscapableExpr *E) {
2383+ classification.merge (Self.classifyTemporarilyEscapable (E));
2384+ return ShouldRecurse;
2385+ }
2386+
23302387 void visitExprPre (Expr *expr) { return ; }
23312388 };
23322389
@@ -3774,6 +3831,13 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
37743831 return ShouldRecurse;
37753832 }
37763833
3834+ ShouldRecurse_t checkTemporarilyEscapable (MakeTemporarilyEscapableExpr *E) {
3835+ auto classification = getApplyClassifier ().
3836+ classifyTemporarilyEscapable (E);
3837+ checkEffectSite (E, /* requiresTry=*/ false , classification);
3838+ return ShouldRecurse;
3839+ }
3840+
37773841 ConditionalEffectKind checkExhaustiveDoBody (DoCatchStmt *S) {
37783842 // This is a context where errors are handled.
37793843 ContextScope scope (*this , CurContext.withHandlesErrors ());
0 commit comments