Skip to content

Commit 5ac1e63

Browse files
authored
[6.2] [cxx-interop] Disabling should be annotated with SWIFT_RETURNS_(UN)RETAINED warning (#81390)
**Explanation**: In Swift 6.1, we introduced warnings for C++ APIs returning `SWIFT_SHARED_REFERENCE` types that lack the `SWIFT_RETURNS_(UN)RETAINED` annotations. These warnings serve as a reminder to annotate APIs, as the absence of these annotations can lead to arbitrary assumptions about the ownership of returned `SWIFT_SHARED_REFERENCE` values. This could result in both use-after-free (memory safety) bugs and memory leaks. We have received feedback from a few adopters indicating potential false positive cases where these warnings are triggered. Consequently, we have decided to disable these warnings in Swift 6.2 and re-qualify the warnings on larger projects to ensure their effectiveness and eliminate false positives. - **Scope**: Disabling a previously shipped warning. There is no likelihood of any source breakage or semantic alterations. - **Issues**: rdar://150937617 , rdar://150800115 - **Original PRs**: N/A - **Risk**: Low - **Testing**: Lit test and adopted manually on a demo Xcode project - **Reviewers**: N/A Our intention is to re-enable the warnings in later beta releases of Swift 6.2 once we have stronger evidence of their effectiveness on large codebases and proof that there are no false positives.
1 parent d3248fc commit 5ac1e63

File tree

4 files changed

+26
-25
lines changed

4 files changed

+26
-25
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3650,6 +3650,7 @@ namespace {
36503650
unannotatedAPIWarningNeeded = true;
36513651
}
36523652

3653+
unannotatedAPIWarningNeeded = false;
36533654
if (unannotatedAPIWarningNeeded) {
36543655
HeaderLoc loc(decl->getLocation());
36553656
Impl.diagnose(loc, diag::no_returns_retained_returns_unretained,

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

Lines changed: 6 additions & 6 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); // 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}}
7+
friend FRTStruct *returnInstanceOfFRTStruct(int v);
8+
friend FRTStruct *returnInstanceOfFRTStructWithAttrReturnsRetained(int v);
9+
friend FRTStruct *returnInstanceOfFRTStructWithAttrReturnsUnretained(int v);
1010
} __attribute__((swift_attr("import_reference")))
1111
__attribute__((swift_attr("retain:retainFRTStruct")))
1212
__attribute__((swift_attr("release:releaseFRTStruct")));
@@ -178,12 +178,12 @@ __attribute__((swift_attr("unsafe")));
178178

179179
// C++ APIs returning cxx frts (for testing diagnostics)
180180
struct StructWithAPIsReturningCxxFrt {
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}}
181+
static FRTStruct *_Nonnull StaticMethodReturningCxxFrt();
182182
static FRTStruct *_Nonnull StaticMethodReturningCxxFrtWithAnnotation()
183183
__attribute__((swift_attr("returns_retained")));
184184
};
185185

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}}
186+
FRTStruct *_Nonnull global_function_returning_cxx_frt();
187187
FRTStruct *_Nonnull global_function_returning_cxx_frt_with_annotations()
188188
__attribute__((swift_attr("returns_retained")));
189189

@@ -302,7 +302,7 @@ __attribute__((swift_attr(
302302
operator-(const FRTOverloadedOperators &other);
303303
};
304304

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}}
305+
FRTOverloadedOperators *_Nonnull returnFRTOverloadedOperators();
306306

307307
void retain_FRTOverloadedOperators(FRTOverloadedOperators *_Nonnull v);
308308
void release_FRTOverloadedOperators(FRTOverloadedOperators *_Nonnull v);

test/Interop/Cxx/foreign-reference/Inputs/inheritance.h

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ __attribute__((swift_attr("release:immortal"))) ImmortalRefType {};
109109
ImmortalRefType *returnImmortalRefType() { return new ImmortalRefType(); };
110110

111111
struct DerivedFromImmortalRefType : ImmortalRefType {};
112-
DerivedFromImmortalRefType *returnDerivedFromImmortalRefType() { // expected-warning {{'returnDerivedFromImmortalRefType' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
113-
return new DerivedFromImmortalRefType();
112+
DerivedFromImmortalRefType *returnDerivedFromImmortalRefType() {
113+
return new DerivedFromImmortalRefType();
114114
};
115115

116116
} // namespace ImmortalRefereceExample
@@ -122,7 +122,7 @@ ValueType *returnValueType() { return new ValueType(); }
122122
struct __attribute__((swift_attr("import_reference")))
123123
__attribute__((swift_attr("retain:ret1")))
124124
__attribute__((swift_attr("release:rel1"))) RefType {};
125-
RefType *returnRefType() { return new RefType(); } // expected-warning {{'returnRefType' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
125+
RefType *returnRefType() { return new RefType(); }
126126

127127
struct DerivedFromValueType : ValueType {};
128128
DerivedFromValueType *returnDerivedFromValueType() {
@@ -133,21 +133,21 @@ struct __attribute__((swift_attr("import_reference")))
133133
__attribute__((swift_attr("retain:ret2")))
134134
__attribute__((swift_attr("release:rel2"))) DerivedFromValueTypeAndAnnotated
135135
: ValueType {};
136-
DerivedFromValueTypeAndAnnotated *returnDerivedFromValueTypeAndAnnotated() { // expected-warning {{'returnDerivedFromValueTypeAndAnnotated' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
137-
return new DerivedFromValueTypeAndAnnotated();
136+
DerivedFromValueTypeAndAnnotated *returnDerivedFromValueTypeAndAnnotated() {
137+
return new DerivedFromValueTypeAndAnnotated();
138138
}
139139

140140
struct DerivedFromRefType final : RefType {};
141-
DerivedFromRefType *returnDerivedFromRefType() { // expected-warning {{'returnDerivedFromRefType' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
142-
return new DerivedFromRefType();
141+
DerivedFromRefType *returnDerivedFromRefType() {
142+
return new DerivedFromRefType();
143143
}
144144

145145
struct __attribute__((swift_attr("import_reference")))
146146
__attribute__((swift_attr("retain:ret3")))
147147
__attribute__((swift_attr("release:rel3"))) DerivedFromRefTypeAndAnnotated
148148
: RefType {};
149-
DerivedFromRefTypeAndAnnotated *returnDerivedFromRefTypeAndAnnotated() { // expected-warning {{'returnDerivedFromRefTypeAndAnnotated' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
150-
return new DerivedFromRefTypeAndAnnotated();
149+
DerivedFromRefTypeAndAnnotated *returnDerivedFromRefTypeAndAnnotated() {
150+
return new DerivedFromRefTypeAndAnnotated();
151151
}
152152
} // namespace ExplicitAnnotationHasPrecedence1
153153

@@ -184,8 +184,8 @@ __attribute__((swift_attr("retain:retain_C")))
184184
__attribute__((swift_attr("release:release_C"))) DerivedFromRefTypeAAndBAnnotated
185185
: RefTypeA,
186186
RefTypeB {};
187-
DerivedFromRefTypeAAndBAnnotated *returnDerivedFromRefTypeAAndBAnnotated() { // expected-warning {{'returnDerivedFromRefTypeAAndBAnnotated' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
188-
return new DerivedFromRefTypeAAndBAnnotated();
187+
DerivedFromRefTypeAAndBAnnotated *returnDerivedFromRefTypeAAndBAnnotated() {
188+
return new DerivedFromRefTypeAAndBAnnotated();
189189
}
190190
} // namespace ExplicitAnnotationHasPrecedence2
191191

@@ -206,10 +206,10 @@ struct __attribute__((swift_attr("import_reference")))
206206
__attribute__((swift_attr("retain:RCRetain")))
207207
__attribute__((swift_attr("release:RCRelease"))) RefType {};
208208

209-
RefType *returnRefType() { return new RefType(); }; // expected-warning {{'returnRefType' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENC}}
209+
RefType *returnRefType() { return new RefType(); };
210210

211211
struct DerivedFromRefType final : RefType {};
212-
DerivedFromRefType *returnDerivedFromRefType() { // expected-warning {{'returnDerivedFromRefType' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
212+
DerivedFromRefType *returnDerivedFromRefType() {
213213
return new DerivedFromRefType();
214214
};
215215
} // namespace BasicInheritanceExample
@@ -236,7 +236,7 @@ DerivedFromBaseRef1AndBaseRef2 *returnDerivedFromBaseRef1AndBaseRef2() {
236236
};
237237

238238
struct DerivedFromBaseRef3 : BaseRef3 {};
239-
DerivedFromBaseRef3 *returnDerivedFromBaseRef3() { // expected-warning {{'returnDerivedFromBaseRef3' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
239+
DerivedFromBaseRef3 *returnDerivedFromBaseRef3() {
240240
return new DerivedFromBaseRef3();
241241
};
242242
} // namespace MultipleInheritanceExample1
@@ -312,7 +312,7 @@ __attribute__((swift_attr("release:samerelease"))) B2 {}; // expected-error {{m
312312

313313
struct D : B1, B2 {}; // expected-error {{multiple functions 'sameretain' found; there must be exactly one retain function for reference type 'D'}}
314314
// expected-error@-1 {{multiple functions 'samerelease' found; there must be exactly one release function for reference type 'D'}}
315-
D *returnD() { return new D(); }; // expected-warning {{'returnD' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
315+
D *returnD() { return new D(); };
316316
} // namespace OverloadedRetainRelease
317317

318318
void sameretain(OverloadedRetainRelease::B1 *v) {}
@@ -339,7 +339,7 @@ struct BVirtual : virtual A {};
339339
struct CVirtual : virtual A {};
340340

341341
struct VirtualDiamond : BVirtual, CVirtual {};
342-
VirtualDiamond *returnVirtualDiamond() { return new VirtualDiamond(); }; // expected-warning {{'returnVirtualDiamond' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
342+
VirtualDiamond *returnVirtualDiamond() { return new VirtualDiamond(); };
343343
} // namespace RefTypeDiamondInheritance
344344

345345
void retainA(RefTypeDiamondInheritance::A *a) {};
@@ -355,7 +355,7 @@ __attribute__((swift_attr("release:releaseB"))) B : A {};
355355
struct C : A {};
356356

357357
struct Diamond : B, C {};
358-
Diamond *returnDiamond() { return new Diamond(); }; // expected-warning {{'returnDiamond' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
358+
Diamond *returnDiamond() { return new Diamond(); };
359359

360360
} // namespace NonRefTypeDiamondInheritance
361361

@@ -384,7 +384,7 @@ __attribute__((swift_attr("retain:forestRetain"))) __attribute__((
384384
};
385385

386386
class Forest : public IntrusiveRefCountedTemplate<Forest> {};
387-
Forest *returnForest() { return new Forest(); }; // expected-warning {{'returnForest' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
387+
Forest *returnForest() { return new Forest(); };
388388
} // namespace InheritingTemplatedRefType
389389

390390
void forestRetain(InheritingTemplatedRefType::IntrusiveRefCountedTemplate<

test/Interop/Cxx/objc-correctness/Inputs/cxx-frt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ void releaseCxxRefType(CxxRefType *_Nonnull b) {}
1616

1717
@interface Bridge : NSObject
1818

19-
+ (struct CxxRefType *)objCMethodReturningFRTUnannotated; // expected-warning {{'objCMethodReturningFRTUnannotated' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENCE}}
19+
+ (struct CxxRefType *)objCMethodReturningFRTUnannotated;
2020
+ (struct CxxRefType *)objCMethodReturningFRTUnowned
2121
__attribute__((swift_attr("returns_unretained")));
2222
+ (struct CxxRefType *)objCMethodReturningFRTOwned

0 commit comments

Comments
 (0)