Skip to content

Commit 004ef74

Browse files
authored
Merge pull request #77646 from swiftlang/egorzhdan/reland-copy-ctor
Re-land "[cxx-interop] Check the presence of copy constructor correctly"
2 parents 74b5a5c + aa584bf commit 004ef74

File tree

4 files changed

+36
-8
lines changed

4 files changed

+36
-8
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7718,17 +7718,16 @@ static bool hasCopyTypeOperations(const clang::CXXRecordDecl *decl) {
77187718
decl->getName() == "_Optional_construct_base")
77197719
return true;
77207720

7721+
if (decl->hasSimpleCopyConstructor())
7722+
return true;
7723+
77217724
// If we have no way of copying the type we can't import the class
77227725
// at all because we cannot express the correct semantics as a swift
77237726
// struct.
7724-
if (llvm::any_of(decl->ctors(), [](clang::CXXConstructorDecl *ctor) {
7725-
return ctor->isCopyConstructor() &&
7726-
(ctor->isDeleted() || ctor->getAccess() != clang::AS_public);
7727-
}))
7728-
return false;
7729-
7730-
// TODO: this should probably check to make sure we actually have a copy ctor.
7731-
return true;
7727+
return llvm::any_of(decl->ctors(), [](clang::CXXConstructorDecl *ctor) {
7728+
return ctor->isCopyConstructor() && !ctor->isDeleted() &&
7729+
ctor->getAccess() == clang::AccessSpecifier::AS_public;
7730+
});
77327731
}
77337732

77347733
static bool hasMoveTypeOperations(const clang::CXXRecordDecl *decl) {

test/Interop/Cxx/class/Inputs/constructors.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,25 @@ struct TemplatedConstructorWithExtraArg {
7171
TemplatedConstructorWithExtraArg(T value, U other) { }
7272
};
7373

74+
struct TemplatedCopyConstructor {
75+
int x = 0;
76+
77+
TemplatedCopyConstructor(int x) : x(x) {}
78+
79+
template <class T>
80+
TemplatedCopyConstructor(const T &value) : x(value.x) {}
81+
};
82+
83+
struct TemplatedCopyConstructorWithExtraArg {
84+
int x = 0;
85+
86+
TemplatedCopyConstructorWithExtraArg(int x) : x(x) {}
87+
88+
template <class T>
89+
TemplatedCopyConstructorWithExtraArg(const T &value, int add = 0)
90+
: x(value.x + add) {}
91+
};
92+
7493
struct __attribute__((swift_attr("import_unsafe")))
7594
HasUserProvidedCopyConstructor {
7695
int numCopies;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
// RUN: %target-swift-ide-test -print-module -module-to-print=Constructors -I %S/Inputs -source-filename=x -enable-experimental-cxx-interop | %FileCheck %s
22

3+
// CHECK: struct TemplatedCopyConstructor
4+
// CHECK: struct TemplatedCopyConstructorWithExtraArg
5+
36
// Make sure we don't import non-copyable types because we will have no way to
47
// represent and copy/move these in swift with correct semantics.
58
// CHECK-NOT: DeletedCopyConstructor

test/Interop/Cxx/class/constructors-typechecker.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import Constructors
44

5+
func takesCopyable<T: Copyable>(_ x: T.Type) {}
6+
57
let explicit = ExplicitDefaultConstructor()
68

79
let implicit = ImplicitDefaultConstructor()
@@ -12,3 +14,8 @@ let onlyCopyAndMove = CopyAndMoveConstructor() // expected-warning {{'init()' is
1214
let deletedExplicitly = DefaultConstructorDeleted() // expected-error {{missing argument for parameter 'a' in call}}
1315

1416
let withArg = ConstructorWithParam(42)
17+
18+
let _ = TemplatedCopyConstructor(123)
19+
let _ = TemplatedCopyConstructorWithExtraArg(123)
20+
takesCopyable(TemplatedCopyConstructor.self)
21+
takesCopyable(TemplatedCopyConstructorWithExtraArg.self)

0 commit comments

Comments
 (0)