57
57
#include " clang/AST/Decl.h"
58
58
#include " clang/AST/DeclCXX.h"
59
59
#include " clang/AST/DeclObjCCommon.h"
60
+ #include " clang/AST/Type.h"
60
61
#include " clang/Basic/Specifiers.h"
61
62
#include " clang/Basic/TargetInfo.h"
62
63
#include " clang/Lex/Preprocessor.h"
@@ -3852,11 +3853,36 @@ namespace {
3852
3853
return result;
3853
3854
}
3854
3855
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
+
3855
3870
void addLifetimeDependencies (const clang::FunctionDecl *decl,
3856
3871
AbstractFunctionDecl *result) {
3857
3872
if (decl->getTemplatedKind () == clang::FunctionDecl::TK_FunctionTemplate)
3858
3873
return ;
3859
3874
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
+
3860
3886
auto swiftParams = result->getParameters ();
3861
3887
bool hasSelf = result->hasImplicitSelfDecl () && !isa<ConstructorDecl>(result);
3862
3888
SmallVector<LifetimeDependenceInfo, 1 > lifetimeDependencies;
@@ -3866,13 +3892,15 @@ namespace {
3866
3892
hasSelf);
3867
3893
for (auto [idx, param] : llvm::enumerate (decl->parameters ())) {
3868
3894
if (param->hasAttr <clang::LifetimeBoundAttr>()) {
3895
+ warnForEscapableReturnType ();
3869
3896
if (swiftParams->get (idx)->getInterfaceType ()->isEscapable ())
3870
3897
scopedLifetimeParamIndicesForReturn[idx] = true ;
3871
3898
else
3872
3899
inheritLifetimeParamIndicesForReturn[idx] = true ;
3873
3900
}
3874
3901
}
3875
3902
if (implicitObjectParamIsLifetimeBound (decl)) {
3903
+ warnForEscapableReturnType ();
3876
3904
auto idx = result->getSelfIndex ();
3877
3905
if (result->getImplicitSelfDecl ()->getInterfaceType ()->isEscapable ())
3878
3906
scopedLifetimeParamIndicesForReturn[idx] = true ;
@@ -3900,11 +3928,20 @@ namespace {
3900
3928
lifetimeDependencies.push_back (
3901
3929
LifetimeDependenceInfo (nullptr , nullptr , 0 , /* isImmortal*/ true ));
3902
3930
}
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 {
3904
3940
Impl.SwiftContext .evaluator .cacheOutput (
3905
3941
LifetimeDependenceInfoRequest{result},
3906
3942
Impl.SwiftContext .AllocateCopy (lifetimeDependencies));
3907
3943
}
3944
+ Impl.diagnoseTargetDirectly (decl);
3908
3945
}
3909
3946
3910
3947
void finishFuncDecl (const clang::FunctionDecl *decl,
0 commit comments