mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #78807 from swiftlang/gaborh/generated-ctors
[cxx-interop] Fix spurious lifetime dependence errors
This commit is contained in:
@@ -2033,6 +2033,18 @@ namespace {
|
||||
return semanticsKind == CxxRecordSemanticsKind::MoveOnly;
|
||||
}
|
||||
|
||||
void markReturnsUnsafeNonescapable(AbstractFunctionDecl *fd) {
|
||||
if (Impl.SwiftContext.LangOpts.hasFeature(Feature::LifetimeDependence)) {
|
||||
fd->getAttrs().add(new (Impl.SwiftContext)
|
||||
UnsafeNonEscapableResultAttr(/*Implicit=*/true));
|
||||
if (Impl.SwiftContext.LangOpts.hasFeature(Feature::SafeInterop) &&
|
||||
Impl.SwiftContext.LangOpts.hasFeature(
|
||||
Feature::AllowUnsafeAttribute))
|
||||
fd->getAttrs().add(new (Impl.SwiftContext)
|
||||
UnsafeAttr(/*Implicit=*/true));
|
||||
}
|
||||
}
|
||||
|
||||
Decl *VisitRecordDecl(const clang::RecordDecl *decl) {
|
||||
// Track whether this record contains fields we can't reference in Swift
|
||||
// as stored properties.
|
||||
@@ -2228,12 +2240,14 @@ namespace {
|
||||
MoveOnlyAttr(/*Implicit=*/true));
|
||||
}
|
||||
|
||||
bool isNonEscapable = false;
|
||||
if (evaluateOrDefault(
|
||||
Impl.SwiftContext.evaluator,
|
||||
ClangTypeEscapability({decl->getTypeForDecl(), Impl}),
|
||||
CxxEscapability::Unknown) == CxxEscapability::NonEscapable) {
|
||||
result->getAttrs().add(new (Impl.SwiftContext)
|
||||
NonEscapableAttr(/*Implicit=*/true));
|
||||
isNonEscapable = true;
|
||||
}
|
||||
|
||||
// FIXME: Figure out what to do with superclasses in C++. One possible
|
||||
@@ -2378,6 +2392,9 @@ namespace {
|
||||
synthesizer.createValueConstructor(result, member,
|
||||
/*want param names*/ true,
|
||||
/*wantBody=*/true);
|
||||
|
||||
if (isNonEscapable)
|
||||
markReturnsUnsafeNonescapable(valueCtor);
|
||||
ctors.push_back(valueCtor);
|
||||
}
|
||||
// TODO: we have a problem lazily looking up members of an unnamed
|
||||
@@ -2402,7 +2419,13 @@ namespace {
|
||||
(!cxxRecordDecl->hasDefaultConstructor() ||
|
||||
cxxRecordDecl->ctors().empty());
|
||||
}
|
||||
if (hasZeroInitializableStorage && needsEmptyInitializer) {
|
||||
|
||||
// TODO: builtin "zeroInitializer" does not work with non-escapable
|
||||
// types yet. Don't generate an initializer.
|
||||
if (hasZeroInitializableStorage && needsEmptyInitializer &&
|
||||
(!Impl.SwiftContext.LangOpts.hasFeature(
|
||||
Feature::LifetimeDependence) ||
|
||||
!isNonEscapable)) {
|
||||
// Add default constructor for the struct if compiling in C mode.
|
||||
// If we're compiling for C++:
|
||||
// 1. If a default constructor is declared, don't synthesize one.
|
||||
@@ -2415,7 +2438,6 @@ namespace {
|
||||
// constructor available in Swift.
|
||||
ConstructorDecl *defaultCtor =
|
||||
synthesizer.createDefaultConstructor(result);
|
||||
ctors.push_back(defaultCtor);
|
||||
if (cxxRecordDecl) {
|
||||
auto attr = AvailableAttr::createUniversallyDeprecated(
|
||||
defaultCtor->getASTContext(),
|
||||
@@ -2425,6 +2447,7 @@ namespace {
|
||||
"");
|
||||
defaultCtor->getAttrs().add(attr);
|
||||
}
|
||||
ctors.push_back(defaultCtor);
|
||||
}
|
||||
|
||||
bool forceMemberwiseInitializer = false;
|
||||
@@ -2454,6 +2477,9 @@ namespace {
|
||||
if (!hasUnreferenceableStorage)
|
||||
valueCtor->setIsMemberwiseInitializer();
|
||||
|
||||
if (isNonEscapable)
|
||||
markReturnsUnsafeNonescapable(valueCtor);
|
||||
|
||||
ctors.push_back(valueCtor);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ private:
|
||||
};
|
||||
|
||||
struct SWIFT_NONESCAPABLE OtherView {
|
||||
OtherView() : member(nullptr) {}
|
||||
OtherView(View v [[clang::lifetimebound]]) : member(v.member) {}
|
||||
OtherView(const OtherView&) = default;
|
||||
private:
|
||||
@@ -105,6 +104,10 @@ CaptureView getCaptureView(const Owner& owner [[clang::lifetimebound]]) {
|
||||
return CaptureView(View{&owner.data});
|
||||
}
|
||||
|
||||
struct SWIFT_NONESCAPABLE AggregateView {
|
||||
const int *member;
|
||||
};
|
||||
|
||||
// CHECK: sil [clang makeOwner] {{.*}}: $@convention(c) () -> Owner
|
||||
// CHECK: sil [clang getView] {{.*}} : $@convention(c) (@in_guaranteed Owner) -> @lifetime(borrow 0) @owned View
|
||||
// CHECK: sil [clang getViewFromFirst] {{.*}} : $@convention(c) (@in_guaranteed Owner, @in_guaranteed Owner) -> @lifetime(borrow 0) @owned View
|
||||
@@ -120,18 +123,20 @@ CaptureView getCaptureView(const Owner& owner [[clang::lifetimebound]]) {
|
||||
// CHECK: sil [clang CaptureView.captureView] {{.*}} : $@convention(cxx_method) (View, @lifetime(copy 0) @inout CaptureView) -> ()
|
||||
// CHECK: sil [clang CaptureView.handOut] {{.*}} : $@convention(cxx_method) (@lifetime(copy 1) @inout View, @in_guaranteed CaptureView) -> ()
|
||||
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:36:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:40:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:46:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:53:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:23:10: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:27:10: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:35:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:39:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:45:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:52:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:22:10: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:26:10: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:4:5: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:5:5: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:13:5: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:14:5: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:68:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:91:13: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:12:27: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:67:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:90:13: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:94:27: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES: nonescapable.h:94:27: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
|
||||
// CHECK-NO-LIFETIMES-NOT: error
|
||||
|
||||
//--- test.swift
|
||||
@@ -155,3 +160,7 @@ public func test() {
|
||||
cv.captureView(v1)
|
||||
cv.handOut(&v1)
|
||||
}
|
||||
|
||||
public func test2(_ x: AggregateView) {
|
||||
let _ = AggregateView(member: x.member)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user