@@ -2033,6 +2033,18 @@ namespace {
20332033 return semanticsKind == CxxRecordSemanticsKind::MoveOnly;
20342034 }
20352035
2036+ void markReturnsUnsafeNonescapable (AbstractFunctionDecl *fd) {
2037+ if (Impl.SwiftContext .LangOpts .hasFeature (Feature::LifetimeDependence)) {
2038+ fd->getAttrs ().add (new (Impl.SwiftContext )
2039+ UnsafeNonEscapableResultAttr (/* Implicit=*/ true ));
2040+ if (Impl.SwiftContext .LangOpts .hasFeature (Feature::SafeInterop) &&
2041+ Impl.SwiftContext .LangOpts .hasFeature (
2042+ Feature::AllowUnsafeAttribute))
2043+ fd->getAttrs ().add (new (Impl.SwiftContext )
2044+ UnsafeAttr (/* Implicit=*/ true ));
2045+ }
2046+ }
2047+
20362048 Decl *VisitRecordDecl (const clang::RecordDecl *decl) {
20372049 // Track whether this record contains fields we can't reference in Swift
20382050 // as stored properties.
@@ -2228,12 +2240,14 @@ namespace {
22282240 MoveOnlyAttr (/* Implicit=*/ true ));
22292241 }
22302242
2243+ bool isNonEscapable = false ;
22312244 if (evaluateOrDefault (
22322245 Impl.SwiftContext .evaluator ,
22332246 ClangTypeEscapability ({decl->getTypeForDecl (), Impl}),
22342247 CxxEscapability::Unknown) == CxxEscapability::NonEscapable) {
22352248 result->getAttrs ().add (new (Impl.SwiftContext )
22362249 NonEscapableAttr (/* Implicit=*/ true ));
2250+ isNonEscapable = true ;
22372251 }
22382252
22392253 // FIXME: Figure out what to do with superclasses in C++. One possible
@@ -2378,6 +2392,9 @@ namespace {
23782392 synthesizer.createValueConstructor (result, member,
23792393 /* want param names*/ true ,
23802394 /* wantBody=*/ true );
2395+
2396+ if (isNonEscapable)
2397+ markReturnsUnsafeNonescapable (valueCtor);
23812398 ctors.push_back (valueCtor);
23822399 }
23832400 // TODO: we have a problem lazily looking up members of an unnamed
@@ -2402,7 +2419,13 @@ namespace {
24022419 (!cxxRecordDecl->hasDefaultConstructor () ||
24032420 cxxRecordDecl->ctors ().empty ());
24042421 }
2405- if (hasZeroInitializableStorage && needsEmptyInitializer) {
2422+
2423+ // TODO: builtin "zeroInitializer" does not work with non-escapable
2424+ // types yet. Don't generate an initializer.
2425+ if (hasZeroInitializableStorage && needsEmptyInitializer &&
2426+ (!Impl.SwiftContext .LangOpts .hasFeature (
2427+ Feature::LifetimeDependence) ||
2428+ !isNonEscapable)) {
24062429 // Add default constructor for the struct if compiling in C mode.
24072430 // If we're compiling for C++:
24082431 // 1. If a default constructor is declared, don't synthesize one.
@@ -2415,7 +2438,6 @@ namespace {
24152438 // constructor available in Swift.
24162439 ConstructorDecl *defaultCtor =
24172440 synthesizer.createDefaultConstructor (result);
2418- ctors.push_back (defaultCtor);
24192441 if (cxxRecordDecl) {
24202442 auto attr = AvailableAttr::createUniversallyDeprecated (
24212443 defaultCtor->getASTContext (),
@@ -2425,6 +2447,7 @@ namespace {
24252447 " " );
24262448 defaultCtor->getAttrs ().add (attr);
24272449 }
2450+ ctors.push_back (defaultCtor);
24282451 }
24292452
24302453 bool forceMemberwiseInitializer = false ;
@@ -2454,6 +2477,9 @@ namespace {
24542477 if (!hasUnreferenceableStorage)
24552478 valueCtor->setIsMemberwiseInitializer ();
24562479
2480+ if (isNonEscapable)
2481+ markReturnsUnsafeNonescapable (valueCtor);
2482+
24572483 ctors.push_back (valueCtor);
24582484 }
24592485
0 commit comments