@@ -2041,6 +2041,18 @@ namespace {
2041
2041
return semanticsKind == CxxRecordSemanticsKind::MoveOnly;
2042
2042
}
2043
2043
2044
+ void markReturnsUnsafeNonescapable (AbstractFunctionDecl *fd) {
2045
+ if (Impl.SwiftContext .LangOpts .hasFeature (Feature::LifetimeDependence)) {
2046
+ fd->getAttrs ().add (new (Impl.SwiftContext )
2047
+ UnsafeNonEscapableResultAttr (/* Implicit=*/ true ));
2048
+ if (Impl.SwiftContext .LangOpts .hasFeature (Feature::SafeInterop) &&
2049
+ Impl.SwiftContext .LangOpts .hasFeature (
2050
+ Feature::AllowUnsafeAttribute))
2051
+ fd->getAttrs ().add (new (Impl.SwiftContext )
2052
+ UnsafeAttr (/* Implicit=*/ true ));
2053
+ }
2054
+ }
2055
+
2044
2056
Decl *VisitRecordDecl (const clang::RecordDecl *decl) {
2045
2057
// Track whether this record contains fields we can't reference in Swift
2046
2058
// as stored properties.
@@ -2236,12 +2248,14 @@ namespace {
2236
2248
MoveOnlyAttr (/* Implicit=*/ true ));
2237
2249
}
2238
2250
2251
+ bool isNonEscapable = false ;
2239
2252
if (evaluateOrDefault (
2240
2253
Impl.SwiftContext .evaluator ,
2241
2254
ClangTypeEscapability ({decl->getTypeForDecl (), Impl}),
2242
2255
CxxEscapability::Unknown) == CxxEscapability::NonEscapable) {
2243
2256
result->getAttrs ().add (new (Impl.SwiftContext )
2244
2257
NonEscapableAttr (/* Implicit=*/ true ));
2258
+ isNonEscapable = true ;
2245
2259
}
2246
2260
2247
2261
// FIXME: Figure out what to do with superclasses in C++. One possible
@@ -2386,6 +2400,9 @@ namespace {
2386
2400
synthesizer.createValueConstructor (result, member,
2387
2401
/* want param names*/ true ,
2388
2402
/* wantBody=*/ true );
2403
+
2404
+ if (isNonEscapable)
2405
+ markReturnsUnsafeNonescapable (valueCtor);
2389
2406
ctors.push_back (valueCtor);
2390
2407
}
2391
2408
// TODO: we have a problem lazily looking up members of an unnamed
@@ -2410,7 +2427,13 @@ namespace {
2410
2427
(!cxxRecordDecl->hasDefaultConstructor () ||
2411
2428
cxxRecordDecl->ctors ().empty ());
2412
2429
}
2413
- if (hasZeroInitializableStorage && needsEmptyInitializer) {
2430
+
2431
+ // TODO: builtin "zeroInitializer" does not work with non-escapable
2432
+ // types yet. Don't generate an initializer.
2433
+ if (hasZeroInitializableStorage && needsEmptyInitializer &&
2434
+ (!Impl.SwiftContext .LangOpts .hasFeature (
2435
+ Feature::LifetimeDependence) ||
2436
+ !isNonEscapable)) {
2414
2437
// Add default constructor for the struct if compiling in C mode.
2415
2438
// If we're compiling for C++:
2416
2439
// 1. If a default constructor is declared, don't synthesize one.
@@ -2423,7 +2446,6 @@ namespace {
2423
2446
// constructor available in Swift.
2424
2447
ConstructorDecl *defaultCtor =
2425
2448
synthesizer.createDefaultConstructor (result);
2426
- ctors.push_back (defaultCtor);
2427
2449
if (cxxRecordDecl) {
2428
2450
auto attr = AvailableAttr::createUniversallyDeprecated (
2429
2451
defaultCtor->getASTContext (),
@@ -2433,6 +2455,7 @@ namespace {
2433
2455
" " );
2434
2456
defaultCtor->getAttrs ().add (attr);
2435
2457
}
2458
+ ctors.push_back (defaultCtor);
2436
2459
}
2437
2460
2438
2461
bool forceMemberwiseInitializer = false ;
@@ -2462,6 +2485,9 @@ namespace {
2462
2485
if (!hasUnreferenceableStorage)
2463
2486
valueCtor->setIsMemberwiseInitializer ();
2464
2487
2488
+ if (isNonEscapable)
2489
+ markReturnsUnsafeNonescapable (valueCtor);
2490
+
2465
2491
ctors.push_back (valueCtor);
2466
2492
}
2467
2493
0 commit comments