Skip to content

Commit e58347e

Browse files
Xazax-hunGabor Horvath
authored andcommitted
[6.2][cxx-interop] Basic support for anonymous structs with non-copyable fields
Explanation: Anonymous structs cannot be copied or moved, these operations only can happen to their enclosing non-anonymous types. Stop trying to emit special member functions and value witness tables for these structs. This fix is required to unblock a high priority libc++ change that fixes an unintended ABI break. Issues: rdar://159928354 Original PRs: #84105 Risk: Medium. I believe this is the right change but hard to anticipate if something depends on the presence of these operations (which is likely to be a bug). But this is required to unblock an important libc++ fix. Testing: Added a compiler test. Reviewers: @rjmccall
1 parent 64e98e6 commit e58347e

File tree

4 files changed

+22
-2
lines changed

4 files changed

+22
-2
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3064,11 +3064,11 @@ namespace {
30643064
}
30653065
}
30663066
}
3067-
if (copyCtor) {
3067+
if (copyCtor && !decl->isAnonymousStructOrUnion()) {
30683068
clangSema.DefineImplicitCopyConstructor(clang::SourceLocation(),
30693069
copyCtor);
30703070
}
3071-
if (moveCtor) {
3071+
if (moveCtor && !decl->isAnonymousStructOrUnion()) {
30723072
clangSema.DefineImplicitMoveConstructor(clang::SourceLocation(),
30733073
moveCtor);
30743074
}

lib/IRGen/GenMeta.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6935,6 +6935,10 @@ namespace {
69356935
}
69366936

69376937
void addValueWitnessTable() {
6938+
if (auto cd = Target->getClangDecl())
6939+
if (auto rd = dyn_cast<clang::RecordDecl>(cd))
6940+
if (rd->isAnonymousStructOrUnion())
6941+
return;
69386942
auto vwtPointer = emitValueWitnessTable(/*relative*/ false).getValue();
69396943
B.addSignedPointer(vwtPointer,
69406944
IGM.getOptions().PointerAuth.ValueWitnessTable,

test/Interop/Cxx/class/move-only/Inputs/move-only-cxx-value-type.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,16 @@ struct NonCopyableHolderDerivedDerived: NonCopyableHolderDerived {
5656
inline NonCopyable *getNonCopyablePtr() { return nullptr; }
5757
inline NonCopyableDerived *getNonCopyableDerivedPtr() { return nullptr; }
5858

59+
template <typename T>
60+
struct FieldInAnonStruct {
61+
FieldInAnonStruct() : field(5) {}
62+
FieldInAnonStruct(const FieldInAnonStruct &) = delete;
63+
FieldInAnonStruct(FieldInAnonStruct &&) = default;
64+
struct {
65+
T field;
66+
};
67+
};
68+
69+
using FieldInAnonStructNC = FieldInAnonStruct<NonCopyable>;
70+
5971
#endif // TEST_INTEROP_CXX_CLASS_MOVE_ONLY_VT_H

test/Interop/Cxx/class/move-only/move-only-cxx-value-type.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,8 @@ MoveOnlyCxxValueType.test("Test move only field access in derived holder") {
7676
}
7777
#endif
7878

79+
MoveOnlyCxxValueType.test("Test move only field in anonymous struct") {
80+
let a = FieldInAnonStructNC()
81+
let b = a
82+
}
7983
runAllTests()

0 commit comments

Comments
 (0)