Skip to content

Commit 9424f2b

Browse files
authored
Merge pull request #7137 from rintaro/printasobjc-noreturn
[PrintAsObjC] Add '__attribute__((return))' for 'Never' return methods
2 parents 47e0079 + f02c155 commit 9424f2b

File tree

3 files changed

+37
-18
lines changed

3 files changed

+37
-18
lines changed

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -628,9 +628,10 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
628628
if (looksLikeInitMethod(AFD->getObjCSelector())) {
629629
os << " SWIFT_METHOD_FAMILY(none)";
630630
}
631-
if (!methodTy->getResult()->isVoid() &&
632-
!methodTy->getResult()->isUninhabited() &&
633-
!AFD->getAttrs().hasAttribute<DiscardableResultAttr>()) {
631+
if (methodTy->getResult()->isUninhabited()) {
632+
os << " SWIFT_NORETURN";
633+
} else if (!methodTy->getResult()->isVoid() &&
634+
!AFD->getAttrs().hasAttribute<DiscardableResultAttr>()) {
634635
os << " SWIFT_WARN_UNUSED_RESULT";
635636
}
636637
}
@@ -648,10 +649,8 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
648649
= FD->getForeignErrorConvention();
649650
assert(!FD->getGenericSignature() &&
650651
"top-level generic functions not supported here");
651-
auto resultTy = getForeignResultType(
652-
FD,
653-
FD->getInterfaceType()->castTo<FunctionType>(),
654-
errorConvention);
652+
auto funcTy = FD->getInterfaceType()->castTo<FunctionType>();
653+
auto resultTy = getForeignResultType(FD, funcTy, errorConvention);
655654

656655
// The result type may be a partial function type we need to close
657656
// up later.
@@ -665,18 +664,29 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
665664

666665
assert(FD->getParameterLists().size() == 1 && "not a C-compatible func");
667666
auto params = FD->getParameterLists().back();
668-
interleave(*params,
669-
[&](const ParamDecl *param) {
670-
print(param->getInterfaceType(), OTK_None, param->getName(),
671-
IsFunctionParam);
672-
},
673-
[&]{ os << ", "; });
667+
if (params->size()) {
668+
interleave(*params,
669+
[&](const ParamDecl *param) {
670+
print(param->getInterfaceType(), OTK_None, param->getName(),
671+
IsFunctionParam);
672+
},
673+
[&]{ os << ", "; });
674+
} else {
675+
os << "void";
676+
}
674677

675678
os << ')';
676679

677680
// Finish the result type.
678681
multiPart.finish();
679682

683+
if (funcTy->getResult()->isUninhabited()) {
684+
os << " SWIFT_NORETURN";
685+
} else if (!funcTy->getResult()->isVoid() &&
686+
!FD->getAttrs().hasAttribute<DiscardableResultAttr>()) {
687+
os << " SWIFT_WARN_UNUSED_RESULT";
688+
}
689+
680690
appendAvailabilityAttribute(FD);
681691

682692
os << ';';
@@ -2337,6 +2347,11 @@ class ModuleWriter {
23372347
"#else\n"
23382348
"# define SWIFT_WARN_UNUSED_RESULT\n"
23392349
"#endif\n"
2350+
"#if defined(__has_attribute) && __has_attribute(noreturn)\n"
2351+
"# define SWIFT_NORETURN __attribute__((noreturn))\n"
2352+
"#else\n"
2353+
"# define SWIFT_NORETURN\n"
2354+
"#endif\n"
23402355
"#if !defined(SWIFT_CLASS_EXTRA)\n"
23412356
"# define SWIFT_CLASS_EXTRA\n"
23422357
"#endif\n"

test/PrintAsObjC/cdecl.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
// REQUIRES: objc_interop
1010

1111
// CHECK: /// What a nightmare!
12-
// CHECK-LABEL: double (^ _Nonnull block_nightmare(SWIFT_NOESCAPE float (^ _Nonnull x)(NSInteger)))(char);
12+
// CHECK-LABEL: double (^ _Nonnull block_nightmare(SWIFT_NOESCAPE float (^ _Nonnull x)(NSInteger)))(char) SWIFT_WARN_UNUSED_RESULT;
1313

1414
/// What a nightmare!
1515
@_cdecl("block_nightmare")
1616
public func block_nightmare(x: @convention(block) (Int) -> Float)
1717
-> @convention(block) (CChar) -> Double { return { _ in 0 } }
1818

19-
// CHECK-LABEL: double (^ _Nonnull block_recurring_nightmare(float (^ _Nonnull x)(SWIFT_NOESCAPE NSInteger (^ _Nonnull)(double))))(SWIFT_NOESCAPE char (^ _Nonnull)(unsigned char));
19+
// CHECK-LABEL: double (^ _Nonnull block_recurring_nightmare(float (^ _Nonnull x)(SWIFT_NOESCAPE NSInteger (^ _Nonnull)(double))))(SWIFT_NOESCAPE char (^ _Nonnull)(unsigned char)) SWIFT_WARN_UNUSED_RESULT;
2020
@_cdecl("block_recurring_nightmare")
2121
public func block_recurring_nightmare(x: @escaping @convention(block) (@convention(block) (Double) -> Int) -> Float)
2222
-> @convention(block) (_ asdfasdf: @convention(block) (CUnsignedChar) -> CChar) -> Double {
@@ -27,12 +27,12 @@ public func block_recurring_nightmare(x: @escaping @convention(block) (@conventi
2727
@_cdecl("foo_bar")
2828
func foo(x: Int, bar y: Int) {}
2929

30-
// CHECK-LABEL: double (* _Nonnull function_pointer_nightmare(SWIFT_NOESCAPE float (* _Nonnull x)(NSInteger)))(char);
30+
// CHECK-LABEL: double (* _Nonnull function_pointer_nightmare(SWIFT_NOESCAPE float (* _Nonnull x)(NSInteger)))(char) SWIFT_WARN_UNUSED_RESULT;
3131
@_cdecl("function_pointer_nightmare")
3232
func function_pointer_nightmare(x: @convention(c) (Int) -> Float)
3333
-> @convention(c) (CChar) -> Double { return { _ in 0 } }
3434

35-
// CHECK-LABEL: double (* _Nonnull function_pointer_recurring_nightmare(float (* _Nonnull x)(SWIFT_NOESCAPE NSInteger (* _Nonnull)(double))))(SWIFT_NOESCAPE char (* _Nonnull)(unsigned char));
35+
// CHECK-LABEL: double (* _Nonnull function_pointer_recurring_nightmare(float (* _Nonnull x)(SWIFT_NOESCAPE NSInteger (* _Nonnull)(double))))(SWIFT_NOESCAPE char (* _Nonnull)(unsigned char)) SWIFT_WARN_UNUSED_RESULT;
3636
@_cdecl("function_pointer_recurring_nightmare")
3737
public func function_pointer_recurring_nightmare(x: @escaping @convention(c) (@convention(c) (Double) -> Int) -> Float)
3838
-> @convention(c) (@convention(c) (CUnsignedChar) -> CChar) -> Double {
@@ -42,3 +42,7 @@ public func function_pointer_recurring_nightmare(x: @escaping @convention(c) (@c
4242
// CHECK-LABEL: void has_keyword_arg_names(NSInteger auto_, NSInteger union_);
4343
@_cdecl("has_keyword_arg_names")
4444
func keywordArgNames(auto: Int, union: Int) {}
45+
46+
// CHECK-LABEL: void return_never(void) SWIFT_NORETURN;
47+
@_cdecl("return_never")
48+
func returnNever() -> Never { fatalError() }

test/PrintAsObjC/never.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@
1212
}
1313

1414
// CHECK-LABEL: @interface NeverClass
15-
// CHECK: - (void)doesNotReturn;
15+
// CHECK: - (void)doesNotReturn SWIFT_NORETURN;
1616
// CHECK: @end

0 commit comments

Comments
 (0)