@@ -2033,6 +2033,18 @@ namespace {
2033
2033
return semanticsKind == CxxRecordSemanticsKind::MoveOnly;
2034
2034
}
2035
2035
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
+
2036
2048
Decl *VisitRecordDecl (const clang::RecordDecl *decl) {
2037
2049
// Track whether this record contains fields we can't reference in Swift
2038
2050
// as stored properties.
@@ -2228,12 +2240,14 @@ namespace {
2228
2240
MoveOnlyAttr (/* Implicit=*/ true ));
2229
2241
}
2230
2242
2243
+ bool isNonEscapable = false ;
2231
2244
if (evaluateOrDefault (
2232
2245
Impl.SwiftContext .evaluator ,
2233
2246
ClangTypeEscapability ({decl->getTypeForDecl (), Impl}),
2234
2247
CxxEscapability::Unknown) == CxxEscapability::NonEscapable) {
2235
2248
result->getAttrs ().add (new (Impl.SwiftContext )
2236
2249
NonEscapableAttr (/* Implicit=*/ true ));
2250
+ isNonEscapable = true ;
2237
2251
}
2238
2252
2239
2253
// FIXME: Figure out what to do with superclasses in C++. One possible
@@ -2378,6 +2392,9 @@ namespace {
2378
2392
synthesizer.createValueConstructor (result, member,
2379
2393
/* want param names*/ true ,
2380
2394
/* wantBody=*/ true );
2395
+
2396
+ if (isNonEscapable)
2397
+ markReturnsUnsafeNonescapable (valueCtor);
2381
2398
ctors.push_back (valueCtor);
2382
2399
}
2383
2400
// TODO: we have a problem lazily looking up members of an unnamed
@@ -2402,7 +2419,13 @@ namespace {
2402
2419
(!cxxRecordDecl->hasDefaultConstructor () ||
2403
2420
cxxRecordDecl->ctors ().empty ());
2404
2421
}
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)) {
2406
2429
// Add default constructor for the struct if compiling in C mode.
2407
2430
// If we're compiling for C++:
2408
2431
// 1. If a default constructor is declared, don't synthesize one.
@@ -2415,7 +2438,6 @@ namespace {
2415
2438
// constructor available in Swift.
2416
2439
ConstructorDecl *defaultCtor =
2417
2440
synthesizer.createDefaultConstructor (result);
2418
- ctors.push_back (defaultCtor);
2419
2441
if (cxxRecordDecl) {
2420
2442
auto attr = AvailableAttr::createUniversallyDeprecated (
2421
2443
defaultCtor->getASTContext (),
@@ -2425,6 +2447,7 @@ namespace {
2425
2447
" " );
2426
2448
defaultCtor->getAttrs ().add (attr);
2427
2449
}
2450
+ ctors.push_back (defaultCtor);
2428
2451
}
2429
2452
2430
2453
bool forceMemberwiseInitializer = false ;
@@ -2454,6 +2477,9 @@ namespace {
2454
2477
if (!hasUnreferenceableStorage)
2455
2478
valueCtor->setIsMemberwiseInitializer ();
2456
2479
2480
+ if (isNonEscapable)
2481
+ markReturnsUnsafeNonescapable (valueCtor);
2482
+
2457
2483
ctors.push_back (valueCtor);
2458
2484
}
2459
2485
0 commit comments