Skip to content

Commit 781489f

Browse files
authored
Merge pull request #85021 from j-hui/return-frt-diagnostics
[cxx-interop] Put RETURNS_RETAINED warnings in a diagnostic group rdar://161932849 rdar://144976203
2 parents 7fef148 + a622254 commit 781489f

20 files changed

+195
-92
lines changed

include/swift/AST/DiagnosticGroups.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ GROUP(AvailabilityUnrecognizedName, "availability-unrecognized-name")
4646
GROUP(ClangDeclarationImport, "clang-declaration-import")
4747
GROUP(CompilationCaching, "compilation-caching")
4848
GROUP(ConformanceIsolation, "conformance-isolation")
49+
GROUP(ForeignReferenceType, "foreign-reference-type")
4950
GROUP(DeprecatedDeclaration, "deprecated-declaration")
5051
GROUP(DynamicCallable, "dynamic-callable-requirements")
5152
GROUP(EmbeddedRestrictions, "embedded-restrictions")

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2211,12 +2211,12 @@ ERROR(expose_nested_type_to_cxx,none,
22112211
"nested %kind0 can not yet be represented in C++", (ValueDecl *))
22122212
ERROR(expose_macro_to_cxx,none,
22132213
"Swift macro can not yet be represented in C++", (ValueDecl *))
2214-
WARNING(warn_unannotated_cxx_func_returning_frt, none,
2215-
"cannot infer the ownership of the returned value, annotate %0 with "
2216-
"either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED",
2214+
GROUPED_WARNING(warn_unannotated_cxx_func_returning_frt, ForeignReferenceType, none,
2215+
"cannot infer ownership of foreign reference value returned by %0",
2216+
(const ValueDecl *))
2217+
NOTE(note_unannotated_cxx_func_returning_frt, none,
2218+
"annotate %0 with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED",
22172219
(const ValueDecl *))
2218-
NOTE(note_unannotated_cxx_func_returning_frt, none, "%0 is defined here",
2219-
(const ValueDecl *))
22202220
ERROR(unexposed_other_decl_in_cxx,none,
22212221
"%kind0 is not yet exposed to C++", (ValueDecl *))
22222222
ERROR(unsupported_other_decl_in_cxx,none,

include/swift/Basic/Features.def

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -498,10 +498,9 @@ EXPERIMENTAL_FEATURE(AssumeResilientCxxTypes, true)
498498
/// Import inherited non-public members when importing C++ classes.
499499
EXPERIMENTAL_FEATURE(ImportNonPublicCxxMembers, true)
500500

501-
/// Emit a warning when a C++ API returns a SWIFT_SHARED_REFERENCE type
502-
/// without being explicitly annotated with either SWIFT_RETURNS_RETAINED
503-
/// or SWIFT_RETURNS_UNRETAINED.
504-
EXPERIMENTAL_FEATURE(WarnUnannotatedReturnOfCxxFrt, true)
501+
/// Suppress the synthesis of static factory methods for C++ foreign reference
502+
/// types and importing them as Swift initializers.
503+
EXPERIMENTAL_FEATURE(SuppressCXXForeignReferenceTypeInitializers, true)
505504

506505
/// modify/read single-yield coroutines
507506
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(CoroutineAccessors, true)

lib/AST/FeatureSet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ UNINTERESTING_FEATURE(LibraryEvolution)
333333
UNINTERESTING_FEATURE(SafeInteropWrappers)
334334
UNINTERESTING_FEATURE(AssumeResilientCxxTypes)
335335
UNINTERESTING_FEATURE(ImportNonPublicCxxMembers)
336-
UNINTERESTING_FEATURE(WarnUnannotatedReturnOfCxxFrt)
336+
UNINTERESTING_FEATURE(SuppressCXXForeignReferenceTypeInitializers)
337337
UNINTERESTING_FEATURE(CoroutineAccessorsUnwindOnCallerError)
338338
UNINTERESTING_FEATURE(AllowRuntimeSymbolDeclarations)
339339

lib/Sema/MiscDiagnostics.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6375,8 +6375,6 @@ static bool isReturningFRT(const clang::NamedDecl *ND,
63756375
static bool shouldDiagnoseMissingReturnsRetained(const clang::NamedDecl *ND,
63766376
clang::QualType retType,
63776377
ASTContext &Ctx) {
6378-
if (!Ctx.LangOpts.hasFeature(Feature::WarnUnannotatedReturnOfCxxFrt))
6379-
return false;
63806378

63816379
auto attrInfo = importer::ReturnOwnershipInfo(ND);
63826380
if (attrInfo.hasRetainAttr())
@@ -6454,7 +6452,7 @@ static void diagnoseCxxFunctionCalls(const Expr *E, const DeclContext *DC) {
64546452
if (shouldDiagnoseMissingReturnsRetained(ND, retType, Ctx)) {
64556453
SourceLoc diagnosticLoc = func->getLoc();
64566454
if (diagnosticLoc.isInvalid() && func->getClangDecl()) {
6457-
// Fixme: Remove the diagnosticLoc once the source locations of the
6455+
// FIXME: Remove the diagnosticLoc once the source locations of the
64586456
// objc method declarations are imported correctly.
64596457
diagnosticLoc = Ctx.getClangModuleLoader()->importSourceLocation(
64606458
ND->getLocation());

test/Interop/C/struct/Inputs/module.modulemap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@ module StructAsOptionSet {
1818
module NoncopyableStructs {
1919
header "noncopyable-struct.h"
2020
}
21+
22+
module ReturnForeignReference {
23+
header "return-foreign-reference.h"
24+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#ifndef __RETURN_FOREIGN_REFERENCE_H
2+
#define __RETURN_FOREIGN_REFERENCE_H
3+
4+
struct
5+
__attribute__((swift_attr("import_reference")))
6+
__attribute__((swift_attr("retain:FRTRetain")))
7+
__attribute__((swift_attr("release:FRTRelease")))
8+
FRT {
9+
int value;
10+
};
11+
12+
struct Value { int value; };
13+
14+
void FRTRetain(struct FRT *x);
15+
void FRTRelease(struct FRT *x);
16+
17+
struct FRT *getFRTNoAnnotations(void); // expected-note {{annotate}}
18+
struct FRT *getFRTRetained() __attribute__((swift_attr("returns_retained")));
19+
struct FRT *getFRTUnretained() __attribute__((swift_attr("returns_unretained")));
20+
21+
struct FRT *getFRTUnretained() __attribute__((swift_attr("returns_unretained")));
22+
23+
struct FRT *getFRTConflictingAnnotations()
24+
__attribute__((swift_attr("returns_retained")))
25+
__attribute__((swift_attr("returns_unretained")));
26+
// expected-error@-3 {{cannot be annotated with both}}
27+
28+
struct Value *getValueRetained() __attribute__((swift_attr("returns_retained")));
29+
// expected-warning@-1 {{should not be annotated}}
30+
struct Value *getValueUnretained() __attribute__((swift_attr("returns_unretained")));
31+
// expected-warning@-1 {{should not be annotated}}
32+
33+
#endif /* __RETURN_FOREIGN_REFERENCE_H */
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-typecheck-verify-swift -cxx-interoperability-mode=off \
2+
// RUN: -disable-availability-checking \
3+
// RUN: -I %S%{fs-sep}Inputs \
4+
// RUN: -verify-additional-file %S%{fs-sep}Inputs%{fs-sep}return-foreign-reference.h
5+
6+
import ReturnForeignReference
7+
8+
let _: FRT = getFRTNoAnnotations() // expected-warning {{cannot infer ownership}}
9+
let _: FRT = getFRTRetained()
10+
let _: FRT = getFRTUnretained()
11+
12+
13+
// These calls to incorrectly annotated functions are necessary to force
14+
// diagnostics to appear in the header file.
15+
let _: FRT = getFRTConflictingAnnotations()
16+
let _ = getValueRetained()
17+
let _ = getValueUnretained()

test/Interop/Cxx/class/safe-interop-mode.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ using TTakeUnsafeTuple = TTake<UnsafeTuple>;
9797
struct HoldsShared {
9898
SharedObject* obj;
9999

100-
SharedObject* getObj() const SWIFT_RETURNS_INDEPENDENT_VALUE;
100+
SharedObject* getObj() const SWIFT_RETURNS_INDEPENDENT_VALUE
101+
SWIFT_RETURNS_UNRETAINED;
101102
};
102103

103104
//--- test.swift

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,12 @@ __attribute__((swift_attr("unsafe")));
179179

180180
// C++ APIs returning cxx frts (for testing diagnostics)
181181
struct StructWithAPIsReturningCxxFrt {
182-
static FRTStruct *_Nonnull StaticMethodReturningCxxFrt(); // expected-note {{'StaticMethodReturningCxxFrt()' is defined here}}
182+
static FRTStruct *_Nonnull StaticMethodReturningCxxFrt(); // expected-note {{annotate 'StaticMethodReturningCxxFrt()' with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED}}
183183
static FRTStruct *_Nonnull StaticMethodReturningCxxFrtWithAnnotation()
184184
__attribute__((swift_attr("returns_retained")));
185185
};
186186

187-
FRTStruct *_Nonnull global_function_returning_cxx_frt(); // expected-note {{'global_function_returning_cxx_frt()' is defined here}}
187+
FRTStruct *_Nonnull global_function_returning_cxx_frt(); // expected-note {{annotate 'global_function_returning_cxx_frt()' with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED}}
188188
FRTStruct *_Nonnull global_function_returning_cxx_frt_with_annotations()
189189
__attribute__((swift_attr("returns_retained")));
190190

@@ -303,7 +303,9 @@ __attribute__((swift_attr(
303303
operator-(const FRTOverloadedOperators &other);
304304
};
305305

306-
FRTOverloadedOperators *_Nonnull returnFRTOverloadedOperators(); // expected-note {{'returnFRTOverloadedOperators()' is defined here}} // expected-note {{'returnFRTOverloadedOperators()' is defined here}}
306+
FRTOverloadedOperators *_Nonnull returnFRTOverloadedOperators();
307+
// expected-note@-1 {{annotate 'returnFRTOverloadedOperators()' with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED}}
308+
// expected-note@-2 {{annotate 'returnFRTOverloadedOperators()' with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED}}
307309

308310
void retain_FRTOverloadedOperators(FRTOverloadedOperators *_Nonnull v);
309311
void release_FRTOverloadedOperators(FRTOverloadedOperators *_Nonnull v);
@@ -371,7 +373,7 @@ struct __attribute__((swift_attr("import_reference")))
371373
__attribute__((swift_attr("retain:rretain")))
372374
__attribute__((swift_attr("release:rrelease"))) RefType {};
373375

374-
RefType *returnRefType() { return new RefType(); } // expected-note {{'returnRefType()' is defined here}}
376+
RefType *returnRefType() { return new RefType(); } // expected-note {{annotate 'returnRefType()' with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED}}
375377

376378
struct __attribute__((swift_attr("import_reference")))
377379
__attribute__((swift_attr("retain:dretain")))
@@ -420,10 +422,10 @@ __attribute__((swift_attr("retain:dRetain")))
420422
__attribute__((swift_attr("release:dRelease"))) DerivedTypeNonDefault
421423
: public BaseTypeNonDefault {};
422424

423-
BaseTypeNonDefault *createBaseTypeNonDefault() { // expected-note {{'createBaseTypeNonDefault()' is defined here}}
425+
BaseTypeNonDefault *createBaseTypeNonDefault() { // expected-note {{annotate 'createBaseTypeNonDefault()' with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED}}
424426
return new BaseTypeNonDefault();
425427
}
426-
DerivedTypeNonDefault *createDerivedTypeNonDefault() { // expected-note {{'createDerivedTypeNonDefault()' is defined here}}
428+
DerivedTypeNonDefault *createDerivedTypeNonDefault() { // expected-note {{annotate 'createDerivedTypeNonDefault()' with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED}}
427429
return new DerivedTypeNonDefault();
428430
}
429431

@@ -464,7 +466,9 @@ __attribute__((swift_attr("release:release_SourceLocCacheB"))) TypeB {};
464466

465467
template <typename T>
466468
struct Factory {
467-
static T *make() { return new T(); } // expected-note {{'make()' is defined here}} // expected-note {{'make()' is defined here}}
469+
static T *make() { return new T(); }
470+
// expected-note@-1 {{annotate 'make()' with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED}}
471+
// expected-note@-2 {{annotate 'make()' with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED}}
468472
};
469473

470474
using FactoryA = Factory<TypeA>;
@@ -508,7 +512,7 @@ class RefTemplate<FRTStruct> {
508512
return &instance;
509513
}
510514

511-
FRTStruct* value() const { // expected-note {{'value()' is defined here}}
515+
FRTStruct* value() const { // expected-note {{annotate 'value()' with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED}}
512516
return new FRTStruct;
513517
}
514518
};

0 commit comments

Comments
 (0)