Skip to content

Commit dc5f896

Browse files
authored
Merge pull request #28551 from slavapestov/c-self-capture-crash
SILGen: Fix crash when referencing dynamic Self from @convention(c) closure
2 parents c8be802 + af7f127 commit dc5f896

File tree

5 files changed

+32
-15
lines changed

5 files changed

+32
-15
lines changed

include/swift/AST/CaptureInfo.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ class CaptureInfo {
170170

171171
ArrayRef<CapturedValue> getCaptures() const {
172172
// FIXME: Ideally, everywhere that synthesizes a function should include
173-
// its capture info.
173+
// its capture info.
174174
if (!hasBeenComputed())
175175
return None;
176176
return StorageAndFlags.getPointer()->getCaptures();
@@ -188,7 +188,7 @@ class CaptureInfo {
188188
/// \returns true if the function captures any generic type parameters.
189189
bool hasGenericParamCaptures() const {
190190
// FIXME: Ideally, everywhere that synthesizes a function should include
191-
// its capture info.
191+
// its capture info.
192192
if (!hasBeenComputed())
193193
return false;
194194
return StorageAndFlags.getInt().contains(Flags::HasGenericParamCaptures);
@@ -202,7 +202,7 @@ class CaptureInfo {
202202
/// \returns the captured dynamic Self type, if any.
203203
DynamicSelfType *getDynamicSelfType() const {
204204
// FIXME: Ideally, everywhere that synthesizes a function should include
205-
// its capture info.
205+
// its capture info.
206206
if (!hasBeenComputed())
207207
return nullptr;
208208
return StorageAndFlags.getPointer()->getDynamicSelfType();
@@ -214,7 +214,7 @@ class CaptureInfo {
214214

215215
OpaqueValueExpr *getOpaqueValue() const {
216216
// FIXME: Ideally, everywhere that synthesizes a function should include
217-
// its capture info.
217+
// its capture info.
218218
if (!hasBeenComputed())
219219
return nullptr;
220220
return StorageAndFlags.getPointer()->getOpaqueValue();

include/swift/AST/DiagnosticsSIL.def

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ ERROR(unsupported_c_function_pointer_conversion,none,
116116
ERROR(c_function_pointer_from_function_with_context,none,
117117
"a C function pointer cannot be formed from a "
118118
"%select{local function|closure}0 that captures "
119-
"%select{context|generic parameters|dynamic Self type|<<error>}1",
119+
"%select{context|generic parameters|dynamic Self type}1",
120120
(bool, unsigned))
121121

122122
ERROR(objc_selector_malformed,none,"the type ObjectiveC.Selector is malformed",

lib/SILGen/SILGenExpr.cpp

+7-10
Original file line numberDiff line numberDiff line change
@@ -1550,25 +1550,22 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
15501550
// C function pointers cannot capture anything from their context.
15511551
auto captures = SGF.SGM.Types.getLoweredLocalCaptures(constant);
15521552

1553-
if (captures.hasGenericParamCaptures() ||
1553+
if (!captures.getCaptures().empty() ||
1554+
captures.hasGenericParamCaptures() ||
15541555
captures.hasDynamicSelfCapture() ||
1555-
captures.hasLocalCaptures() ||
15561556
captures.hasOpaqueValueCapture()) {
1557-
unsigned kind;
1558-
if (captures.hasLocalCaptures())
1559-
kind = 0;
1560-
else if (captures.hasGenericParamCaptures())
1557+
unsigned kind = 0;
1558+
if (captures.hasGenericParamCaptures())
15611559
kind = 1;
1562-
else if (captures.hasLocalCaptures())
1560+
else if (captures.hasDynamicSelfCapture())
15631561
kind = 2;
1564-
else
1565-
kind = 3;
15661562
SGF.SGM.diagnose(expr->getLoc(),
15671563
diag::c_function_pointer_from_function_with_context,
15681564
/*closure*/ constant.hasClosureExpr(),
15691565
kind);
15701566

1571-
return SGF.emitUndef(constantInfo.getSILType());
1567+
auto loweredTy = SGF.getLoweredType(conversionExpr->getType());
1568+
return SGF.emitUndef(loweredTy);
15721569
}
15731570

15741571
return convertCFunctionSignature(

test/IDE/print_swift_module.swift

+13
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-frontend -emit-module-path %t/print_swift_module.swiftmodule -emit-module-doc -emit-module-doc-path %t/print_swift_module.swiftdoc %s
33
// RUN: %target-swift-ide-test -print-module -print-interface -no-empty-line-between-members -module-to-print=print_swift_module -I %t -source-filename=%s > %t.syn.txt
4+
// RUN: %target-swift-ide-test -print-module -access-filter-internal -no-empty-line-between-members -module-to-print=print_swift_module -I %t -source-filename=%s > %t.syn.internal.txt
45
// RUN: %FileCheck %s -check-prefix=CHECK1 < %t.syn.txt
6+
// RUN: %FileCheck %s -check-prefix=CHECK2 < %t.syn.internal.txt
57

68
public protocol P1 {
79
/// foo1 comment from P1
@@ -53,3 +55,14 @@ public struct City {
5355

5456
// CHECK1: /// returnsAlias() comment
5557
// CHECK1-NEXT: func returnsAlias() -> print_swift_module.Alias<Int>
58+
59+
// CHECK2: struct Event {
60+
public struct Event {
61+
public var start: Int
62+
public var end: Int?
63+
public var repeating: ((), Int?)
64+
public var name = "untitled event"
65+
66+
// CHECK2: init(start: Int, end: Int? = nil, repeating: ((), Int?) = ((), nil), name: String = "untitled event")
67+
}
68+
// CHECK2: }

test/SILGen/c_function_pointers.swift

+7
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,10 @@ func pointers_to_nested_local_functions_in_generics<T>(x: T) -> Int{
105105
func capture_list_no_captures(x: Int) {
106106
calls({ [x] in $0 }, 0) // expected-warning {{capture 'x' was never used}}
107107
}
108+
109+
class Selfless {
110+
func capture_dynamic_self() {
111+
calls_no_args { _ = Self.self; return 0 }
112+
// expected-error@-1 {{a C function pointer cannot be formed from a closure that captures dynamic Self type}}
113+
}
114+
}

0 commit comments

Comments
 (0)