Skip to content

Commit aa584bf

Browse files
committed
[cxx-interop] Check the presence of copy constructor correctly
This reverts commit 3066bd6. This re-lands a change after it got reverted because of a regression in the build of SwiftCompilerSources. rdar://136838485
1 parent c7318ee commit aa584bf

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
@@ -7653,17 +7653,16 @@ static bool hasCopyTypeOperations(const clang::CXXRecordDecl *decl) {
76537653
decl->getName() == "_Optional_construct_base")
76547654
return true;
76557655

7656+
if (decl->hasSimpleCopyConstructor())
7657+
return true;
7658+
76567659
// If we have no way of copying the type we can't import the class
76577660
// at all because we cannot express the correct semantics as a swift
76587661
// struct.
7659-
if (llvm::any_of(decl->ctors(), [](clang::CXXConstructorDecl *ctor) {
7660-
return ctor->isCopyConstructor() &&
7661-
(ctor->isDeleted() || ctor->getAccess() != clang::AS_public);
7662-
}))
7663-
return false;
7664-
7665-
// TODO: this should probably check to make sure we actually have a copy ctor.
7666-
return true;
7662+
return llvm::any_of(decl->ctors(), [](clang::CXXConstructorDecl *ctor) {
7663+
return ctor->isCopyConstructor() && !ctor->isDeleted() &&
7664+
ctor->getAccess() == clang::AccessSpecifier::AS_public;
7665+
});
76677666
}
76687667

76697668
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)