5757#include " clang/AST/Decl.h"
5858#include " clang/AST/DeclCXX.h"
5959#include " clang/AST/DeclObjCCommon.h"
60+ #include " clang/AST/Type.h"
6061#include " clang/Basic/Specifiers.h"
6162#include " clang/Basic/TargetInfo.h"
6263#include " clang/Lex/Preprocessor.h"
@@ -3852,11 +3853,36 @@ namespace {
38523853 return result;
38533854 }
38543855
3856+ static bool isNonEscapableAnnotatedType (const clang::Type *t) {
3857+ if (const auto *rd = t->getAsRecordDecl ()) {
3858+ return hasNonEscapableAttr (rd);
3859+ }
3860+ return false ;
3861+ }
3862+
3863+ static bool isEscapableAnnotatedType (const clang::Type *t) {
3864+ if (const auto *rd = t->getAsRecordDecl ()) {
3865+ return hasEscapableAttr (rd);
3866+ }
3867+ return false ;
3868+ }
3869+
38553870 void addLifetimeDependencies (const clang::FunctionDecl *decl,
38563871 AbstractFunctionDecl *result) {
38573872 if (decl->getTemplatedKind () == clang::FunctionDecl::TK_FunctionTemplate)
38583873 return ;
38593874
3875+ auto retType = decl->getReturnType ();
3876+ auto warnForEscapableReturnType = [&] {
3877+ if (isEscapableAnnotatedType (retType.getTypePtr ())) {
3878+ Impl.addImportDiagnostic (
3879+ decl,
3880+ Diagnostic (diag::return_escapable_with_lifetimebound,
3881+ Impl.SwiftContext .AllocateCopy (retType.getAsString ())),
3882+ decl->getLocation ());
3883+ }
3884+ };
3885+
38603886 auto swiftParams = result->getParameters ();
38613887 bool hasSelf = result->hasImplicitSelfDecl () && !isa<ConstructorDecl>(result);
38623888 SmallVector<LifetimeDependenceInfo, 1 > lifetimeDependencies;
@@ -3866,13 +3892,15 @@ namespace {
38663892 hasSelf);
38673893 for (auto [idx, param] : llvm::enumerate (decl->parameters ())) {
38683894 if (param->hasAttr <clang::LifetimeBoundAttr>()) {
3895+ warnForEscapableReturnType ();
38693896 if (swiftParams->get (idx)->getInterfaceType ()->isEscapable ())
38703897 scopedLifetimeParamIndicesForReturn[idx] = true ;
38713898 else
38723899 inheritLifetimeParamIndicesForReturn[idx] = true ;
38733900 }
38743901 }
38753902 if (implicitObjectParamIsLifetimeBound (decl)) {
3903+ warnForEscapableReturnType ();
38763904 auto idx = result->getSelfIndex ();
38773905 if (result->getImplicitSelfDecl ()->getInterfaceType ()->isEscapable ())
38783906 scopedLifetimeParamIndicesForReturn[idx] = true ;
@@ -3900,11 +3928,20 @@ namespace {
39003928 lifetimeDependencies.push_back (
39013929 LifetimeDependenceInfo (nullptr , nullptr , 0 , /* isImmortal*/ true ));
39023930 }
3903- if (!lifetimeDependencies.empty ()) {
3931+ if (lifetimeDependencies.empty ()) {
3932+ if (isNonEscapableAnnotatedType (retType.getTypePtr ())) {
3933+ Impl.addImportDiagnostic (
3934+ decl,
3935+ Diagnostic (diag::return_nonescapable_without_lifetimebound,
3936+ Impl.SwiftContext .AllocateCopy (retType.getAsString ())),
3937+ decl->getLocation ());
3938+ }
3939+ } else {
39043940 Impl.SwiftContext .evaluator .cacheOutput (
39053941 LifetimeDependenceInfoRequest{result},
39063942 Impl.SwiftContext .AllocateCopy (lifetimeDependencies));
39073943 }
3944+ Impl.diagnoseTargetDirectly (decl);
39083945 }
39093946
39103947 void finishFuncDecl (const clang::FunctionDecl *decl,
0 commit comments