Skip to content

Commit 56746e3

Browse files
authored
[cxx-interop] Relax error when using SWIFT_RETURNS_(UN)RETAINED on templated return types resolving to non-frts (#78968)
We should not complain about usage of SWIFT_RETURNS_(UN)RETAINED for templated C++ APIs when instantiated with a non SWIFT_SHARED_REFERENCE types rdar://143732201
1 parent 52ebd4a commit 56746e3

File tree

4 files changed

+29
-43
lines changed

4 files changed

+29
-43
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3656,6 +3656,11 @@ namespace {
36563656
}
36573657
} else {
36583658
if (returnsRetainedAttrIsPresent || returnsUnretainedAttrIsPresent) {
3659+
if (const auto *functionDecl = dyn_cast<clang::FunctionDecl>(decl)) {
3660+
if (functionDecl->isTemplateInstantiation()) {
3661+
return;
3662+
}
3663+
}
36593664
Impl.diagnose(
36603665
loc,
36613666
diag::

test/Interop/Cxx/foreign-reference/Inputs/cxx-functions-and-methods-returning-frt.h

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
// FRT or SWIFT_SHARED_REFERENCE type
55
struct FRTStruct {
66
// Friend function declarations
7-
friend FRTStruct *returnInstanceOfFRTStruct(int v);
8-
friend FRTStruct *returnInstanceOfFRTStructWithAttrReturnsRetained(int v);
9-
friend FRTStruct *returnInstanceOfFRTStructWithAttrReturnsUnretained(int v);
7+
friend FRTStruct *returnInstanceOfFRTStruct(int v); // expected-warning {{'returnInstanceOfFRTStruct' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
8+
friend FRTStruct *returnInstanceOfFRTStructWithAttrReturnsRetained(int v); // expected-warning {{'returnInstanceOfFRTStructWithAttrReturnsRetained' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
9+
friend FRTStruct *returnInstanceOfFRTStructWithAttrReturnsUnretained(int v); // expected-warning {{'returnInstanceOfFRTStructWithAttrReturnsUnretained' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
1010
} __attribute__((swift_attr("import_reference")))
1111
__attribute__((swift_attr("retain:retainFRTStruct")))
1212
__attribute__((swift_attr("release:releaseFRTStruct")));
@@ -146,15 +146,15 @@ struct StructWithStaticMethodsReturningFRTWithAttributeReturnsUnretained {
146146
// Global/free C++ functions returning FRT with both attributes
147147
// swift_attr("returns_unretained") and swift_attr("returns_retained")
148148
FRTStruct
149-
*_Nonnull global_function_returning_FRT_with_both_attrs_returns_retained_returns_unretained()
149+
*_Nonnull global_function_returning_FRT_with_both_attrs_returns_retained_returns_unretained() // expected-error {{'global_function_returning_FRT_with_both_attrs_returns_retained_returns_unretained' cannot be annotated with both SWIFT_RETURNS_RETAINED and SWIFT_RETURNS_UNRETAINED}}
150150
__attribute__((swift_attr("returns_retained")))
151151
__attribute__((swift_attr("returns_unretained")));
152152

153153
// Struct having static method returning FRT with both attributes
154154
// swift_attr("returns_unretained") and swift_attr("returns_retained")
155155
struct
156156
StructWithStaticMethodsReturningFRTWithBothAttributesReturnsRetainedAndReturnsUnretained {
157-
static FRTStruct *_Nonnull StaticMethodReturningFRT()
157+
static FRTStruct *_Nonnull StaticMethodReturningFRT() // expected-error {{'StaticMethodReturningFRT' cannot be annotated with both SWIFT_RETURNS_RETAINED and SWIFT_RETURNS_UNRETAINED}}
158158
__attribute__((swift_attr("returns_retained")))
159159
__attribute__((swift_attr("returns_unretained")));
160160
};
@@ -178,50 +178,50 @@ __attribute__((swift_attr("unsafe")));
178178

179179
// C++ APIs returning cxx frts (for testing diagnostics)
180180
struct StructWithAPIsReturningCxxFrt {
181-
static FRTStruct *_Nonnull StaticMethodReturningCxxFrt();
181+
static FRTStruct *_Nonnull StaticMethodReturningCxxFrt(); // expected-warning {{'StaticMethodReturningCxxFrt' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
182182
static FRTStruct *_Nonnull StaticMethodReturningCxxFrtWithAnnotation()
183183
__attribute__((swift_attr("returns_retained")));
184184
};
185185

186-
FRTStruct *_Nonnull global_function_returning_cxx_frt();
186+
FRTStruct *_Nonnull global_function_returning_cxx_frt(); // expected-warning {{'global_function_returning_cxx_frt' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
187187
FRTStruct *_Nonnull global_function_returning_cxx_frt_with_annotations()
188188
__attribute__((swift_attr("returns_retained")));
189189

190190
// C++ APIs returning non-cxx-frts (for testing diagnostics)
191191
struct StructWithAPIsReturningNonCxxFrt {
192192
static NonFRTStruct *_Nonnull StaticMethodReturningNonCxxFrt();
193-
static NonFRTStruct *_Nonnull StaticMethodReturningNonCxxFrtWithAnnotation()
193+
static NonFRTStruct *_Nonnull StaticMethodReturningNonCxxFrtWithAnnotation() // expected-error {{'StaticMethodReturningNonCxxFrtWithAnnotation' cannot be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED because it is not returning a SWIFT_SHARED_REFERENCE type}}
194194
__attribute__((swift_attr("returns_retained")));
195195
};
196196

197197
NonFRTStruct *_Nonnull global_function_returning_non_cxx_frt();
198-
NonFRTStruct *_Nonnull global_function_returning_non_cxx_frt_with_annotations()
198+
NonFRTStruct *_Nonnull global_function_returning_non_cxx_frt_with_annotations() // expected-error {{'global_function_returning_non_cxx_frt_with_annotations' cannot be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED because it is not returning a SWIFT_SHARED_REFERENCE type}}
199199
__attribute__((swift_attr("returns_retained")));
200200

201201
// C++ APIs returning SWIFT_IMMORTAL_REFERENCE types (for testing diagnostics)
202202
struct StructWithAPIsReturningImmortalReference {
203203
static ImmortalRefStruct *_Nonnull StaticMethodReturningImmortalReference();
204204
static ImmortalRefStruct
205-
*_Nonnull StaticMethodReturningImmortalReferenceWithAnnotation()
205+
*_Nonnull StaticMethodReturningImmortalReferenceWithAnnotation() // expected-error {{'StaticMethodReturningImmortalReferenceWithAnnotation' cannot be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED because it is not returning a SWIFT_SHARED_REFERENCE type}}
206206
__attribute__((swift_attr("returns_retained")));
207207
};
208208

209209
ImmortalRefStruct *_Nonnull global_function_returning_immortal_reference();
210210
ImmortalRefStruct
211-
*_Nonnull global_function_returning_immortal_reference_with_annotations()
211+
*_Nonnull global_function_returning_immortal_reference_with_annotations() // expected-error {{'global_function_returning_immortal_reference_with_annotations' cannot be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED because it is not returning a SWIFT_SHARED_REFERENCE type}}
212212
__attribute__((swift_attr("returns_retained")));
213213

214214
// C++ APIs returning SWIFT_UNSAFE_REFERENCE types (for testing diagnostics)
215215
struct StructWithAPIsReturningUnsafeReference {
216216
static UnsafeRefStruct *_Nonnull StaticMethodReturningUnsafeReference();
217217
static UnsafeRefStruct
218-
*_Nonnull StaticMethodReturningUnsafeReferenceWithAnnotation()
218+
*_Nonnull StaticMethodReturningUnsafeReferenceWithAnnotation() // expected-error {{'StaticMethodReturningUnsafeReferenceWithAnnotation' cannot be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED because it is not returning a SWIFT_SHARED_REFERENCE type}}
219219
__attribute__((swift_attr("returns_retained")));
220220
};
221221

222222
UnsafeRefStruct *_Nonnull global_function_returning_unsafe_reference();
223223
UnsafeRefStruct
224-
*_Nonnull global_function_returning_unsafe_reference_with_annotations()
224+
*_Nonnull global_function_returning_unsafe_reference_with_annotations() // expected-error {{'global_function_returning_unsafe_reference_with_annotations' cannot be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED because it is not returning a SWIFT_SHARED_REFERENCE type}}
225225
__attribute__((swift_attr("returns_retained")));
226226

227227
// Global/free C++ functions returning non-FRT
@@ -296,13 +296,13 @@ __attribute__((swift_attr(
296296

297297
public:
298298
FRTOverloadedOperators *_Nonnull
299-
operator+(const FRTOverloadedOperators &other)
299+
operator+(const FRTOverloadedOperators &other) // expected-warning {{SWIFT_RETURNS_RETAINED and SWIFT_RETURNS_UNRETAINED is not supported yet for overloaded C++ 'operator+'. Overloaded C++ operators always return SWIFT_SHARED_REFERENCE types as owned}}
300300
__attribute__((swift_attr("returns_unretained")));
301301
FRTOverloadedOperators *_Nonnull
302302
operator-(const FRTOverloadedOperators &other);
303303
};
304304

305-
FRTOverloadedOperators *_Nonnull returnFRTOverloadedOperators();
305+
FRTOverloadedOperators *_Nonnull returnFRTOverloadedOperators(); // expected-warning {{'returnFRTOverloadedOperators' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
306306

307307
void retain_FRTOverloadedOperators(FRTOverloadedOperators *_Nonnull v);
308308
void release_FRTOverloadedOperators(FRTOverloadedOperators *_Nonnull v);
Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,34 @@
11
// RUN: rm -rf %t
2-
// RUN: not %target-swift-frontend -typecheck -I %S/Inputs %s -cxx-interoperability-mode=upcoming-swift 2>&1 | %FileCheck %s
2+
// RUN: %target-swift-frontend -typecheck -verify -I %S/Inputs %s -cxx-interoperability-mode=upcoming-swift -verify-additional-file %S/Inputs/cxx-functions-and-methods-returning-frt.h -Xcc -Wno-return-type -Xcc -Wno-nullability-completeness
3+
4+
// XFAIL: OS=windows-msvc
5+
// TODO: Enable this on windows when -verify-additional-file issue on Windows Swift CI is resolved
36

47
import FunctionsAndMethodsReturningFRT
58
import CxxStdlib
69

710
let frtLocalVar1 = global_function_returning_FRT_with_both_attrs_returns_retained_returns_unretained()
8-
// CHECK: error: 'global_function_returning_FRT_with_both_attrs_returns_retained_returns_unretained' cannot be annotated with both SWIFT_RETURNS_RETAINED and SWIFT_RETURNS_UNRETAINED
9-
1011
let frtLocalVar2 = StructWithStaticMethodsReturningFRTWithBothAttributesReturnsRetainedAndReturnsUnretained.StaticMethodReturningFRT()
11-
// CHECK: error: 'StaticMethodReturningFRT' cannot be annotated with both SWIFT_RETURNS_RETAINED and SWIFT_RETURNS_UNRETAINED
1212
let frtLocalVar3 = StructWithAPIsReturningCxxFrt.StaticMethodReturningCxxFrt()
13-
// CHECK: warning: 'StaticMethodReturningCxxFrt' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE
1413
let frtLocalVar4 = StructWithAPIsReturningCxxFrt.StaticMethodReturningCxxFrtWithAnnotation()
15-
1614
let frtLocalVar5 = global_function_returning_cxx_frt()
17-
// CHECK: warning: 'global_function_returning_cxx_frt' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE
1815
let frtLocalVar6 = global_function_returning_cxx_frt_with_annotations()
19-
2016
let frtLocalVar7 = StructWithAPIsReturningNonCxxFrt.StaticMethodReturningNonCxxFrt()
2117
let frtLocalVar8 = StructWithAPIsReturningNonCxxFrt.StaticMethodReturningNonCxxFrtWithAnnotation()
22-
// CHECK: error: 'StaticMethodReturningNonCxxFrtWithAnnotation' cannot be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED because it is not returning a SWIFT_SHARED_REFERENCE type
23-
2418
let frtLocalVar9 = global_function_returning_non_cxx_frt()
2519
let frtLocalVar10 = global_function_returning_non_cxx_frt_with_annotations()
26-
// CHECK: error: 'global_function_returning_non_cxx_frt_with_annotations' cannot be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED because it is not returning a SWIFT_SHARED_REFERENCE type
27-
2820
let frtLocalVar11 = StructWithAPIsReturningImmortalReference.StaticMethodReturningImmortalReference()
2921
let frtLocalVar12 = StructWithAPIsReturningImmortalReference.StaticMethodReturningImmortalReferenceWithAnnotation()
30-
// CHECK: error: 'StaticMethodReturningImmortalReferenceWithAnnotation' cannot be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED because it is not returning a SWIFT_SHARED_REFERENCE type
31-
3222
let frtLocalVar13 = global_function_returning_immortal_reference()
3323
let frtLocalVar14 = global_function_returning_immortal_reference_with_annotations()
34-
// CHECK: error: 'global_function_returning_immortal_reference_with_annotations' cannot be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED because it is not returning a SWIFT_SHARED_REFERENCE type
35-
36-
let frtLocalVar15 = StructWithAPIsReturningUnsafeReference.StaticMethodReturningUnsafeReference()
3724
let frtLocalVar16 = StructWithAPIsReturningUnsafeReference.StaticMethodReturningUnsafeReferenceWithAnnotation()
38-
// CHECK: error: 'StaticMethodReturningUnsafeReferenceWithAnnotation' cannot be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED because it is not returning a SWIFT_SHARED_REFERENCE type
39-
4025
let frtLocalVar17 = global_function_returning_unsafe_reference()
4126
let frtLocalVar18 = global_function_returning_unsafe_reference_with_annotations()
42-
// CHECK: error: 'global_function_returning_unsafe_reference_with_annotations' cannot be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED because it is not returning a SWIFT_SHARED_REFERENCE type
43-
4427
let x = returnFRTOverloadedOperators()
45-
// CHECK: warning: 'returnFRTOverloadedOperators' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE
4628
let y = returnFRTOverloadedOperators()
47-
// CHECK: warning: 'returnFRTOverloadedOperators' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE
4829
let z = x + y
49-
// CHECK: warning: SWIFT_RETURNS_RETAINED and SWIFT_RETURNS_UNRETAINED is not supported yet for overloaded C++ 'operator+'. Overloaded C++ operators always return SWIFT_SHARED_REFERENCE types as owned
5030
let w = x - y
51-
// CHECK-NOT: warning: 'operator-' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE
52-
5331
let f = FunctionVoidToFRTStruct()
5432
let frt = f()
55-
// CHECK-NOT: warning: 'operator()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE
33+
let nonFrt = NonFRTStruct()
34+
let nonFrtLocalVar1 = global_function_returning_templated_retrun_frt_owned(nonFrt)

test/Interop/Cxx/foreign-reference/frt-retained-unretained-attributes.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ func testStaticMethodsReturningNonFRT() {
185185
// CHECK: function_ref @{{.*}}StaticMethodReturningNonFRT_copy{{.*}} : $@convention(c) () -> UnsafeMutablePointer<NonFRTStruct>
186186
}
187187

188-
func testtFreeFunctionsTemplated(frt : FRTStruct) {
188+
func testtFreeFunctionsTemplated(frt : FRTStruct, nonFrt: NonFRTStruct) {
189189
let frtLocalVar1 : Int = 1;
190190

191191
let frtLocalVar2 = global_templated_function_returning_FRT(frtLocalVar1)
@@ -227,6 +227,8 @@ func testtFreeFunctionsTemplated(frt : FRTStruct) {
227227
let frtLocalVar14 = global_function_returning_templated_retrun_frt_owned(frt)
228228
// CHECK: function_ref @{{.*}}global_function_returning_templated_retrun_frt_owned{{.*}} : $@convention(c) (FRTStruct) -> @owned FRTStruct
229229

230+
let nonFrtLocalVar1 = global_function_returning_templated_retrun_frt_owned(nonFrt)
231+
// CHECK: function_ref @{{.*}}global_function_returning_templated_retrun_frt_owned{{.*}} : $@convention(c) (NonFRTStruct) -> NonFRTStruct
230232
}
231233

232234
func testVirtualMethods(base: Base, derived: Derived) {

0 commit comments

Comments
 (0)