diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index f3f6a446cd3e2..de466879e09a8 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -8232,6 +8232,9 @@ CxxRecordSemantics::evaluate(Evaluator &evaluator, auto cxxDecl = dyn_cast(decl); if (!cxxDecl) { + if (hasNonCopyableAttr(decl)) + return CxxRecordSemanticsKind::MoveOnly; + return CxxRecordSemanticsKind::Trivial; } diff --git a/test/Interop/C/struct/Inputs/module.modulemap b/test/Interop/C/struct/Inputs/module.modulemap index 641158b9978ef..ba61a05b26407 100644 --- a/test/Interop/C/struct/Inputs/module.modulemap +++ b/test/Interop/C/struct/Inputs/module.modulemap @@ -10,3 +10,7 @@ module ForeignReference { module StructAsOptionSet { header "struct-as-option-set.h" } + +module NoncopyableStructs { + header "noncopyable-struct.h" +} \ No newline at end of file diff --git a/test/Interop/C/struct/Inputs/noncopyable-struct.h b/test/Interop/C/struct/Inputs/noncopyable-struct.h new file mode 100644 index 0000000000000..14a96c396f86d --- /dev/null +++ b/test/Interop/C/struct/Inputs/noncopyable-struct.h @@ -0,0 +1,5 @@ +// RUN: %target-typecheck-verify-swift -I %S/Inputs/ + +typedef struct __attribute__((swift_attr("~Copyable"))) NonCopyable { + float x, y; +} NonCopyable; diff --git a/test/Interop/C/struct/noncopyable_structs.swift b/test/Interop/C/struct/noncopyable_structs.swift new file mode 100644 index 0000000000000..c1e3ca8bcf64d --- /dev/null +++ b/test/Interop/C/struct/noncopyable_structs.swift @@ -0,0 +1,29 @@ + +// Check that we get the expected errors for incorrect uses of noncopyable +// imported types with both C and C++ interoperability. + +// RUN: %target-swift-frontend -emit-sil -I %S/Inputs/ %s -verify -DERRORS +// RUN: %target-swift-frontend -emit-sil -I %S/Inputs/ %s -verify -DERRORS -cxx-interoperability-mode=default + +// Check that we get the expected IR + +// RUN: %target-swift-frontend -emit-ir -I %S/Inputs/ %s -o - | %FileCheck %s +// RUN: %target-swift-frontend -emit-ir -I %S/Inputs/ %s -o - -cxx-interoperability-mode=default| %FileCheck %s + +import NoncopyableStructs + +// CHECK-LABEL: define hidden swiftcc void @"$s19noncopyable_structs9consumeNCyySo11NonCopyableVnF"(float %0, float %1) #0 { +// CHECK: call ptr @"$sSo11NonCopyableVWOh" +// CHECK: define linkonce_odr hidden ptr @"$sSo11NonCopyableVWOh"(ptr %0) +// CHECK-NEXT: entry: +// CHECK-NEXT: ret ptr +func consumeNC(_ nc: consuming NonCopyable) { } + +func testNC() { + let nc = NonCopyable() // expected-error{{'nc' consumed more than once}} + consumeNC(nc) // expected-note{{consumed here}} + + #if ERRORS + consumeNC(nc) // expected-note{{consumed again here}} + #endif +}