Skip to content

Commit 94ca6fa

Browse files
authored
Merge pull request #79793 from swiftlang/gaborh/remove-feature-flag
2 parents a866f5d + 6b24af6 commit 94ca6fa

File tree

3 files changed

+38
-49
lines changed

3 files changed

+38
-49
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2036,12 +2036,9 @@ namespace {
20362036
}
20372037

20382038
void markReturnsUnsafeNonescapable(AbstractFunctionDecl *fd) {
2039-
if (Impl.SwiftContext.LangOpts.hasFeature(Feature::LifetimeDependence)) {
2040-
fd->getAttrs().add(new (Impl.SwiftContext)
2041-
UnsafeNonEscapableResultAttr(/*Implicit=*/true));
2042-
fd->getAttrs().add(new (Impl.SwiftContext)
2043-
UnsafeAttr(/*Implicit=*/true));
2044-
}
2039+
fd->getAttrs().add(new (Impl.SwiftContext)
2040+
UnsafeNonEscapableResultAttr(/*Implicit=*/true));
2041+
fd->getAttrs().add(new (Impl.SwiftContext) UnsafeAttr(/*Implicit=*/true));
20452042
}
20462043

20472044
Decl *VisitRecordDecl(const clang::RecordDecl *decl) {
@@ -2417,9 +2414,7 @@ namespace {
24172414
// TODO: builtin "zeroInitializer" does not work with non-escapable
24182415
// types yet. Don't generate an initializer.
24192416
if (hasZeroInitializableStorage && needsEmptyInitializer &&
2420-
(!Impl.SwiftContext.LangOpts.hasFeature(
2421-
Feature::LifetimeDependence) ||
2422-
!isNonEscapable)) {
2417+
!isNonEscapable) {
24232418
// Add default constructor for the struct if compiling in C mode.
24242419
// If we're compiling for C++:
24252420
// 1. If a default constructor is declared, don't synthesize one.
@@ -4053,21 +4048,29 @@ namespace {
40534048
if (decl->getTemplatedKind() == clang::FunctionDecl::TK_FunctionTemplate)
40544049
return;
40554050

4056-
auto &ASTContext = result->getASTContext();
4057-
if (!ASTContext.LangOpts.hasFeature(Feature::LifetimeDependence))
4051+
// FIXME: support C functions imported as members.
4052+
if (result->getImportAsMemberStatus().isImportAsMember() &&
4053+
!isa<clang::CXXMethodDecl, clang::ObjCMethodDecl>(decl))
40584054
return;
40594055

4056+
auto isEscapable = [this](clang::QualType ty) {
4057+
return evaluateOrDefault(
4058+
Impl.SwiftContext.evaluator,
4059+
ClangTypeEscapability({ty.getTypePtr(), &Impl}),
4060+
CxxEscapability::Unknown) != CxxEscapability::NonEscapable;
4061+
};
4062+
4063+
auto &ASTContext = result->getASTContext();
40604064
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
40614065
LifetimeDependenceInfo immortalLifetime(nullptr, nullptr, 0,
40624066
/*isImmortal*/ true);
4063-
if (const auto *funDecl = dyn_cast<FuncDecl>(result))
4064-
if (hasUnsafeAPIAttr(decl) && !funDecl->getResultInterfaceType()->isEscapable()) {
4065-
lifetimeDependencies.push_back(immortalLifetime);
4066-
Impl.SwiftContext.evaluator.cacheOutput(
4067-
LifetimeDependenceInfoRequest{result},
4068-
Impl.SwiftContext.AllocateCopy(lifetimeDependencies));
4069-
return;
4070-
}
4067+
if (hasUnsafeAPIAttr(decl) && !isEscapable(decl->getReturnType())) {
4068+
lifetimeDependencies.push_back(immortalLifetime);
4069+
Impl.SwiftContext.evaluator.cacheOutput(
4070+
LifetimeDependenceInfoRequest{result},
4071+
Impl.SwiftContext.AllocateCopy(lifetimeDependencies));
4072+
return;
4073+
}
40714074

40724075
auto retType = decl->getReturnType();
40734076
auto warnForEscapableReturnType = [&] {
@@ -4088,23 +4091,24 @@ namespace {
40884091
SmallBitVector scopedLifetimeParamIndicesForReturn(dependencyVecSize);
40894092
SmallBitVector paramHasAnnotation(dependencyVecSize);
40904093
std::map<unsigned, SmallBitVector> inheritedArgDependences;
4091-
auto processLifetimeBound = [&](unsigned idx, Type ty) {
4094+
auto processLifetimeBound = [&](unsigned idx, clang::QualType ty) {
40924095
warnForEscapableReturnType();
40934096
paramHasAnnotation[idx] = true;
4094-
if (ty->isEscapable())
4097+
if (isEscapable(ty))
40954098
scopedLifetimeParamIndicesForReturn[idx] = true;
40964099
else
40974100
inheritLifetimeParamIndicesForReturn[idx] = true;
40984101
};
40994102
auto processLifetimeCaptureBy =
4100-
[&](const clang::LifetimeCaptureByAttr *attr, unsigned idx, Type ty) {
4103+
[&](const clang::LifetimeCaptureByAttr *attr, unsigned idx,
4104+
clang::QualType ty) {
41014105
// FIXME: support scoped lifetimes. This is not straightforward as
41024106
// const T& is imported as taking a value
41034107
// and we assume the address of T would not escape. An
41044108
// annotation in this case contradicts our assumptions. We
41054109
// should diagnose that, and support this for the non-const
41064110
// case.
4107-
if (ty->isEscapable())
4111+
if (isEscapable(ty))
41084112
return;
41094113
for (auto param : attr->params()) {
41104114
// FIXME: Swift assumes no escaping to globals. We should diagnose
@@ -4130,20 +4134,20 @@ namespace {
41304134
};
41314135
for (auto [idx, param] : llvm::enumerate(decl->parameters())) {
41324136
if (param->hasAttr<clang::LifetimeBoundAttr>())
4133-
processLifetimeBound(idx, swiftParams->get(idx)->getInterfaceType());
4137+
processLifetimeBound(idx, param->getType());
41344138
if (const auto *attr = param->getAttr<clang::LifetimeCaptureByAttr>())
4135-
processLifetimeCaptureBy(attr, idx,
4136-
swiftParams->get(idx)->getInterfaceType());
4139+
processLifetimeCaptureBy(attr, idx, param->getType());
41374140
}
41384141
if (getImplicitObjectParamAnnotation<clang::LifetimeBoundAttr>(decl))
4139-
processLifetimeBound(result->getSelfIndex(),
4140-
result->getImplicitSelfDecl()->getInterfaceType());
4142+
processLifetimeBound(
4143+
result->getSelfIndex(),
4144+
cast<clang::CXXMethodDecl>(decl)->getThisType()->getPointeeType());
41414145
if (auto attr =
41424146
getImplicitObjectParamAnnotation<clang::LifetimeCaptureByAttr>(
41434147
decl))
41444148
processLifetimeCaptureBy(
41454149
attr, result->getSelfIndex(),
4146-
result->getImplicitSelfDecl()->getInterfaceType());
4150+
cast<clang::CXXMethodDecl>(decl)->getThisType()->getPointeeType());
41474151

41484152
for (auto& [idx, inheritedDepVec]: inheritedArgDependences) {
41494153
lifetimeDependencies.push_back(LifetimeDependenceInfo(inheritedDepVec.any() ? IndexSubset::get(Impl.SwiftContext,
@@ -4188,7 +4192,7 @@ namespace {
41884192
}
41894193

41904194
for (auto [idx, param] : llvm::enumerate(decl->parameters())) {
4191-
if (swiftParams->get(idx)->getInterfaceType()->isEscapable())
4195+
if (isEscapable(param->getType()))
41924196
continue;
41934197
if (param->hasAttr<clang::NoEscapeAttr>() || paramHasAnnotation[idx])
41944198
continue;

test/Interop/Cxx/class/nonescapable-errors.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,16 @@ import CxxStdlib
103103
// CHECK-NO-LIFETIMES: test.swift:6:32: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
104104
public func noAnnotations() -> View {
105105
// CHECK: nonescapable.h:16:7: warning: the returned type 'Owner' is annotated as escapable; it cannot have lifetime dependencies
106+
// CHECK-NO-LIFETIMES: nonescapable.h:16:7: warning: the returned type 'Owner' is annotated as escapable; it cannot have lifetime dependencies
106107
f(nil)
107108
// CHECK: nonescapable.h:20:7: warning: the returned type 'Owner' is annotated as escapable; it cannot have lifetime dependencies
109+
// CHECK-NO-LIFETIMES: nonescapable.h:20:7: warning: the returned type 'Owner' is annotated as escapable; it cannot have lifetime dependencies
108110
// No duplicate warning for f2:
109111
// CHECK-NOT: nonescapable.h:20
110112
f2(nil, nil)
111113
// CHECK: nonescapable.h:24:6: warning: the returned type 'View' is annotated as non-escapable; its lifetime dependencies must be annotated
112114
// CHECK: nonescapable.h:24:6: error: cannot infer lifetime dependence, no parameters found that are either ~Escapable or Escapable with a borrowing ownership
115+
// CHECK-NO-LIFETIMES: nonescapable.h:24:6: warning: the returned type 'View' is annotated as non-escapable; its lifetime dependencies must be annotated
113116
// CHECK-NO-LIFETIMES: nonescapable.h:24:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
114117
g(nil)
115118
h1(nil)
@@ -144,8 +147,6 @@ public func noAnnotations() -> View {
144147
// CHECK-NO-LIFETIMES: nonescapable.h:77:12: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
145148
l2();
146149
return View()
147-
// CHECK-NO-LIFETIMES: nonescapable.h:5:5: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
148-
// CHECK-NO-LIFETIMES: nonescapable.h:6:5: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
149150
}
150151

151152
public func test3(_ x: inout View) {

test/Interop/Cxx/class/nonescapable-lifetimebound.swift

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: rm -rf %t
22
// RUN: split-file %s %t
33
// RUN: %target-swift-frontend -I %swift_src_root/lib/ClangImporter/SwiftBridging -I %t/Inputs -emit-sil %t/test.swift -enable-experimental-feature LifetimeDependence -cxx-interoperability-mode=default -diagnostic-style llvm 2>&1 | %FileCheck %s
4-
// RUN: not %target-swift-frontend -I %swift_src_root/lib/ClangImporter/SwiftBridging -I %t/Inputs -emit-sil %t/test.swift -cxx-interoperability-mode=default -diagnostic-style llvm 2>&1 | %FileCheck %s -check-prefix=CHECK-NO-LIFETIMES
4+
// RUN: %target-swift-frontend -I %swift_src_root/lib/ClangImporter/SwiftBridging -I %t/Inputs -emit-sil %t/test.swift -cxx-interoperability-mode=default -diagnostic-style llvm 2>&1 | %FileCheck %s
55

66
// REQUIRES: swift_feature_LifetimeDependence
77

@@ -124,22 +124,6 @@ struct SWIFT_NONESCAPABLE AggregateView {
124124
// CHECK: sil [clang CaptureView.captureView] {{.*}} : $@convention(cxx_method) (View, @lifetime(copy 0) @inout CaptureView) -> ()
125125
// CHECK: sil [clang CaptureView.handOut] {{.*}} : $@convention(cxx_method) (@lifetime(copy 1) @inout View, @in_guaranteed CaptureView) -> ()
126126

127-
// CHECK-NO-LIFETIMES: nonescapable.h:35:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
128-
// CHECK-NO-LIFETIMES: nonescapable.h:39:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
129-
// CHECK-NO-LIFETIMES: nonescapable.h:45:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
130-
// CHECK-NO-LIFETIMES: nonescapable.h:52:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
131-
// CHECK-NO-LIFETIMES: nonescapable.h:22:10: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
132-
// CHECK-NO-LIFETIMES: nonescapable.h:26:10: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
133-
// CHECK-NO-LIFETIMES: nonescapable.h:4:5: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
134-
// CHECK-NO-LIFETIMES: nonescapable.h:5:5: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
135-
// CHECK-NO-LIFETIMES: nonescapable.h:13:5: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
136-
// CHECK-NO-LIFETIMES: nonescapable.h:12:27: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
137-
// CHECK-NO-LIFETIMES: nonescapable.h:67:6: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
138-
// CHECK-NO-LIFETIMES: nonescapable.h:90:13: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
139-
// CHECK-NO-LIFETIMES: nonescapable.h:94:27: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
140-
// CHECK-NO-LIFETIMES: nonescapable.h:94:27: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
141-
// CHECK-NO-LIFETIMES-NOT: error
142-
143127
//--- test.swift
144128

145129
import Test

0 commit comments

Comments
 (0)