Skip to content

Commit c1a50cf

Browse files
authored
Merge pull request #63506 from zoecarver/runtime-crash-ref-in-ctor
2 parents ee41f32 + c00c762 commit c1a50cf

File tree

6 files changed

+65
-13
lines changed

6 files changed

+65
-13
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3073,6 +3073,13 @@ class CFunctionConventions : public CFunctionTypeConventions {
30733073
}
30743074

30753075
ResultConvention getResult(const TypeLowering &tl) const override {
3076+
// C++ constructors return indirectly.
3077+
// TODO: this may be different depending on the ABI, so we may have to
3078+
// check with clang here.
3079+
if (isa<clang::CXXConstructorDecl>(TheDecl)) {
3080+
return ResultConvention::Indirect;
3081+
}
3082+
30763083
if (isCFTypedef(tl, TheDecl->getReturnType())) {
30773084
// The CF attributes aren't represented in the type, so we need
30783085
// to check them here.
@@ -3177,15 +3184,19 @@ static CanSILFunctionType getSILFunctionTypeForClangDecl(
31773184
}
31783185

31793186
if (auto method = dyn_cast<clang::CXXMethodDecl>(clangDecl)) {
3180-
AbstractionPattern origPattern = AbstractionPattern::getCXXMethod(origType, method,
3181-
foreignInfo.self);
3182-
bool isMutating =
3183-
TC.Context.getClangModuleLoader()->isCXXMethodMutating(method);
3184-
auto conventions = CXXMethodConventions(method, isMutating);
3185-
return getSILFunctionType(TC, TypeExpansionContext::minimal(), origPattern,
3186-
substInterfaceType, extInfoBuilder, conventions,
3187-
foreignInfo, constant, constant, None,
3188-
ProtocolConformanceRef());
3187+
// Static methods and ctors should be lowered like plane functions
3188+
// (case below).
3189+
if (!isa<clang::CXXConstructorDecl>(method) || method->isStatic()) {
3190+
AbstractionPattern origPattern = AbstractionPattern::getCXXMethod(origType, method,
3191+
foreignInfo.self);
3192+
bool isMutating =
3193+
TC.Context.getClangModuleLoader()->isCXXMethodMutating(method);
3194+
auto conventions = CXXMethodConventions(method, isMutating);
3195+
return getSILFunctionType(TC, TypeExpansionContext::minimal(), origPattern,
3196+
substInterfaceType, extInfoBuilder, conventions,
3197+
foreignInfo, constant, constant, None,
3198+
ProtocolConformanceRef());
3199+
}
31893200
}
31903201

31913202
if (auto func = dyn_cast<clang::FunctionDecl>(clangDecl)) {

test/Interop/Cxx/class/method/Inputs/methods.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,13 @@ struct HasMethods {
2727
NonTrivialInWrapper constPassThroughAsWrapper(int a) const { return {a}; }
2828
};
2929

30+
struct ReferenceParams {
31+
int a;
32+
int b;
33+
ReferenceParams(const int &a, const int &b) : a(a), b(b) { }
34+
static void staticMethod(const int &a, const int &b) {
35+
ReferenceParams t{a, b};
36+
}
37+
};
38+
3039
#endif // TEST_INTEROP_CXX_CLASS_METHOD_METHODS_H
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-swift-emit-silgen -I %S/Inputs -enable-experimental-cxx-interop %s | %FileCheck %s
2+
3+
import Methods
4+
5+
// clang name: ReferenceParams::ReferenceParams
6+
// CHECK: sil [clang ReferenceParams.init] @{{_ZN15ReferenceParamsC1ERKiS1_|\?\?0ReferenceParams@@QEAA@AEBH0@Z}} : $@convention(c) (@in_guaranteed Int32, @in_guaranteed Int32) -> @out ReferenceParams
7+
8+
// clang name: ReferenceParams::staticMethod
9+
// CHECK: sil [clang ReferenceParams.staticMethod] @{{_ZN15ReferenceParams12staticMethodERKiS1_|\?staticMethod@ReferenceParams@@SAXAEBH0@Z}} : $@convention(c) (@in_guaranteed Int32, @in_guaranteed Int32) -> ()
10+
11+
public func use() {
12+
let a = CInt(42)
13+
let b = CInt(42)
14+
_ = ReferenceParams(a, b)
15+
ReferenceParams.staticMethod(a, b)
16+
}

test/Interop/Cxx/class/method/methods.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,20 @@ CxxMethodTestSuite.test("(Int) -> NonTrivialInWrapper") {
5252
expectEqual(42, instance.constPassThroughAsWrapper(42).value)
5353
}
5454

55+
CxxMethodTestSuite.test("Constructor with ref params") {
56+
let a = CInt(42)
57+
let b = CInt(11)
58+
var instance = ReferenceParams(a, b)
59+
60+
expectEqual(42, instance.a)
61+
expectEqual(11, instance.b)
62+
}
63+
64+
// Just make sure we don't crash
65+
CxxMethodTestSuite.test("Static method with ref params") {
66+
let a = CInt(42)
67+
let b = CInt(11)
68+
ReferenceParams.staticMethod(a, b)
69+
}
70+
5571
runAllTests()

test/Interop/Cxx/reference/const-ref-parameter.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ func testFunction() {
5252
// CHECK-NEXT: apply [[FN4]]
5353
// CHECK-SAME: : $@convention(objc_method) (@in_guaranteed OptionsStruct, @objc_metatype OptionsConsumerObjC.Type) -> Int32
5454

55-
// CHECK: [[FN5:%[0-9]+]] = function_ref @_ZN18OptionsConsumerCxxC1ERK13OptionsStruct : $@convention(c) (OptionsStruct) -> @out OptionsConsumerCxx
55+
// CHECK: [[FN5:%[0-9]+]] = function_ref @_ZN18OptionsConsumerCxxC1ERK13OptionsStruct : $@convention(c) (@in_guaranteed OptionsStruct) -> @out OptionsConsumerCxx
5656
// CHECK-NEXT: apply [[FN5]]
57-
// CHECK-SAME: : $@convention(c) (OptionsStruct) -> @out OptionsConsumerCxx
57+
// CHECK-SAME: : $@convention(c) (@in_guaranteed OptionsStruct) -> @out OptionsConsumerCxx
5858

5959
// CHECK: [[FN6:%[0-9]+]] = function_ref @_ZN18OptionsConsumerCxx12doOtherThingERK13OptionsStruct : $@convention(cxx_method) (@in_guaranteed OptionsStruct, @inout OptionsConsumerCxx) -> Float
6060
// CHECK-NEXT: apply [[FN6]]

test/Interop/Cxx/reference/reference-silgen-cxx-objc-ctors+init.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ var b = IntWrapper(a)
88
var c = ObjCSwiftBridge(embedded: b)
99

1010
// FIXME: the const-ref C++ Consructor here is not getting an @in_guaranteed or even an @in convention here.
11-
// CHECK: {{%[0-9]+}} = function_ref @_ZN10IntWrapperC1ERKi : $@convention(c) (Int32) -> @out IntWrapper
12-
// CHECK: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(c) (Int32) -> @out IntWrapper
11+
// CHECK: {{%[0-9]+}} = function_ref @_ZN10IntWrapperC1ERKi : $@convention(c) (@in_guaranteed Int32) -> @out IntWrapper
12+
// CHECK: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(c) (@in_guaranteed Int32) -> @out IntWrapper
1313
// CHECK: alloc_global @$s4main1cSo15ObjCSwiftBridgeCSgvp
1414
// CHECK: {{%[0-9]+}} = global_addr @$s4main1cSo15ObjCSwiftBridgeCSgvp : $*Optional<ObjCSwiftBridge>
1515
// CHECK: {{%[0-9]+}} = load {{%[0-9]+}} : $*IntWrapper

0 commit comments

Comments
 (0)