Skip to content

Commit 30df58c

Browse files
committed
Delete implicit members whose definition does not compile
1 parent e962dbf commit 30df58c

2 files changed

Lines changed: 31 additions & 5 deletions

File tree

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,27 +1636,42 @@ void DefineImplicitMembers(clang::Sema &sema, clang::CXXRecordDecl *decl) {
16361636
tu_scope.setEntity(sema.Context.getTranslationUnitDecl());
16371637
auto *saved_tu_scope = std::exchange(sema.TUScope, &tu_scope);
16381638
sema.ForceDeclarationOfImplicitMembers(decl);
1639+
auto define = [&](clang::FunctionDecl *fn, auto &&definer) {
1640+
RuleDecls::Trial trial(sema);
1641+
definer();
1642+
if (trial.failed()) {
1643+
fn->setDeletedAsWritten(true);
1644+
}
1645+
};
16391646
for (auto ctor : decl->ctors()) {
16401647
if (ctor->isCopyConstructor() && ctor->isImplicit() &&
16411648
!ctor->doesThisDeclarationHaveABody() && !ctor->isDeleted()) {
1642-
sema.DefineImplicitCopyConstructor(decl->getLocation(), ctor);
1649+
define(ctor, [&] {
1650+
sema.DefineImplicitCopyConstructor(decl->getLocation(), ctor);
1651+
});
16431652
}
16441653
if (ctor->isMoveConstructor() && !ctor->isUserProvided() &&
16451654
!ctor->doesThisDeclarationHaveABody() && !ctor->isDeleted() &&
16461655
!HasDefaultedCopyConstructor(decl)) {
1647-
sema.DefineImplicitMoveConstructor(decl->getLocation(), ctor);
1656+
define(ctor, [&] {
1657+
sema.DefineImplicitMoveConstructor(decl->getLocation(), ctor);
1658+
});
16481659
}
16491660
}
16501661
for (auto *method : decl->methods()) {
16511662
if (method->isMoveAssignmentOperator() && !method->isUserProvided() &&
16521663
!method->doesThisDeclarationHaveABody() && !method->isDeleted() &&
16531664
!HasDefaultedCopyAssignment(decl)) {
1654-
sema.DefineImplicitMoveAssignment(decl->getLocation(), method);
1665+
define(method, [&] {
1666+
sema.DefineImplicitMoveAssignment(decl->getLocation(), method);
1667+
});
16551668
}
16561669
if (method->isCopyAssignmentOperator() && !method->isUserProvided() &&
16571670
!method->doesThisDeclarationHaveABody() && !method->isDeleted() &&
16581671
NeedsDefaultedCopyAssignment(decl)) {
1659-
sema.DefineImplicitCopyAssignment(decl->getLocation(), method);
1672+
define(method, [&] {
1673+
sema.DefineImplicitCopyAssignment(decl->getLocation(), method);
1674+
});
16601675
}
16611676
}
16621677
auto define_defaulted_comparison = [&](clang::FunctionDecl *fn) {
@@ -1669,7 +1684,9 @@ void DefineImplicitMembers(clang::Sema &sema, clang::CXXRecordDecl *decl) {
16691684
#else
16701685
auto kind = sema.getDefaultedComparisonKind(fn);
16711686
#endif
1672-
sema.DefineDefaultedComparison(decl->getLocation(), fn, kind);
1687+
define(fn, [&] {
1688+
sema.DefineDefaultedComparison(decl->getLocation(), fn, kind);
1689+
});
16731690
};
16741691
for (auto *method : decl->methods()) {
16751692
define_defaulted_comparison(method);

‎tests/unit/copy_move_deleted.cpp‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <cassert>
22
#include <utility>
3+
#include <vector>
34

45
struct NoCopy {
56
int v;
@@ -43,6 +44,10 @@ struct Container {
4344
int tag;
4445
};
4546

47+
struct VecHolder {
48+
std::vector<NoCopy> items;
49+
};
50+
4651
static void bump(NoCopy *p) { p->v++; }
4752
static void bump_ref(Immovable &r) { r.v++; }
4853

@@ -71,5 +76,9 @@ int main() {
7176
Container c{NoCopy(6), 7};
7277
Container d(std::move(c));
7378
assert(d.inner.v == 6 && d.tag == 7 && c.inner.v == 0);
79+
80+
VecHolder h;
81+
VecHolder h2(std::move(h));
82+
assert(h2.items.size() == 0);
7483
return 0;
7584
}

0 commit comments

Comments
 (0)