@@ -4097,7 +4097,8 @@ namespace {
40974097 func->setSelfIndex (selfIdx.value ());
40984098 if (Impl.SwiftContext .LangOpts .hasFeature (
40994099 Feature::AddressableParameters))
4100- func->getImplicitSelfDecl ()->setAddressable ();
4100+ func->getAttrs ().add (new (Impl.SwiftContext )
4101+ AddressableSelfAttr (true ));
41014102 } else {
41024103 func->setStatic ();
41034104 func->setImportAsStaticMember ();
@@ -4145,6 +4146,34 @@ namespace {
41454146 return false ;
41464147 }
41474148
4149+ // Inject lifetime annotations selectively for some STL types so we can use
4150+ // unsafeAddress to avoid copies.
4151+ bool inferSelfDependence (const clang::FunctionDecl *decl,
4152+ AbstractFunctionDecl *result, size_t returnIdx) {
4153+ const auto *method = dyn_cast<clang::CXXMethodDecl>(decl);
4154+ if (!method)
4155+ return false ;
4156+ const auto *enclosing = method->getParent ();
4157+ if (enclosing->isInStdNamespace () &&
4158+ (enclosing->getName () == " unique_ptr" ||
4159+ enclosing->getName () == " shared_ptr" ) &&
4160+ method->isOverloadedOperator () &&
4161+ method->getOverloadedOperator () == clang::OO_Star) {
4162+ SmallVector<LifetimeDependenceInfo, 1 > lifetimeDependencies;
4163+ SmallBitVector dependenciesOfRet (returnIdx);
4164+ dependenciesOfRet[result->getSelfIndex ()] = true ;
4165+ lifetimeDependencies.push_back (LifetimeDependenceInfo (
4166+ nullptr , IndexSubset::get (Impl.SwiftContext , dependenciesOfRet),
4167+ returnIdx,
4168+ /* isImmortal*/ false ));
4169+ Impl.SwiftContext .evaluator .cacheOutput (
4170+ LifetimeDependenceInfoRequest{result},
4171+ Impl.SwiftContext .AllocateCopy (lifetimeDependencies));
4172+ return true ;
4173+ }
4174+ return false ;
4175+ }
4176+
41484177 void addLifetimeDependencies (const clang::FunctionDecl *decl,
41494178 AbstractFunctionDecl *result) {
41504179 if (decl->getTemplatedKind () == clang::FunctionDecl::TK_FunctionTemplate)
@@ -4163,10 +4192,19 @@ namespace {
41634192 CxxEscapability::Unknown) != CxxEscapability::NonEscapable;
41644193 };
41654194
4195+ auto swiftParams = result->getParameters ();
4196+ bool hasSelf =
4197+ result->hasImplicitSelfDecl () && !isa<ConstructorDecl>(result);
4198+ auto returnIdx = swiftParams->size () + hasSelf;
4199+
4200+ if (inferSelfDependence (decl, result, returnIdx))
4201+ return ;
4202+
41664203 // FIXME: this uses '0' as the result index. That only works for
41674204 // standalone functions with no parameters.
41684205 // See markReturnsUnsafeNonescapable() for a general approach.
41694206 auto &ASTContext = result->getASTContext ();
4207+
41704208 SmallVector<LifetimeDependenceInfo, 1 > lifetimeDependencies;
41714209 LifetimeDependenceInfo immortalLifetime (nullptr , nullptr , 0 ,
41724210 /* isImmortal*/ true );
@@ -4189,10 +4227,7 @@ namespace {
41894227 }
41904228 };
41914229
4192- auto swiftParams = result->getParameters ();
4193- bool hasSelf =
4194- result->hasImplicitSelfDecl () && !isa<ConstructorDecl>(result);
4195- const auto dependencyVecSize = swiftParams->size () + hasSelf;
4230+ const auto dependencyVecSize = returnIdx;
41964231 SmallBitVector inheritLifetimeParamIndicesForReturn (dependencyVecSize);
41974232 SmallBitVector scopedLifetimeParamIndicesForReturn (dependencyVecSize);
41984233 SmallBitVector paramHasAnnotation (dependencyVecSize);
@@ -4271,7 +4306,7 @@ namespace {
42714306 ? IndexSubset::get (Impl.SwiftContext ,
42724307 scopedLifetimeParamIndicesForReturn)
42734308 : nullptr ,
4274- swiftParams-> size () + hasSelf ,
4309+ returnIdx ,
42754310 /* isImmortal*/ false ));
42764311 else if (auto *ctordecl = dyn_cast<clang::CXXConstructorDecl>(decl)) {
42774312 // Assume default constructed view types have no dependencies.
0 commit comments