@@ -528,12 +528,21 @@ IsConvertibleImplicitMemberParent(const clang::CXXRecordDecl *decl) {
528528 decl->getNumBases () == 0 ;
529529}
530530
531+ static bool HasFieldWithMoveFrom (const clang::RecordDecl *decl) {
532+ return llvm::any_of (decl->fields (), [](const clang::FieldDecl *field) {
533+ auto *record = field->getType ()->getAsRecordDecl ();
534+ return record && HasMoveFromConstructor (record);
535+ });
536+ }
537+
531538bool IsConvertibleMoveConstructor (const clang::CXXConstructorDecl *ctor) {
532- return ctor->isMoveConstructor () && !ctor->isDeleted () &&
533- IsConvertibleImplicitMemberParent (ctor->getParent ()) &&
534- (ctor->isUserProvided () ||
535- !HasDefaultedCopyConstructor (ctor->getParent ())) &&
536- ctor->hasBody ();
539+ auto *parent = ctor->getParent ();
540+ if (!ctor->isMoveConstructor () || ctor->isDeleted () || !ctor->hasBody () ||
541+ !IsConvertibleImplicitMemberParent (parent)) {
542+ return false ;
543+ }
544+ return ctor->isUserProvided () || !HasDefaultedCopyConstructor (parent) ||
545+ HasFieldWithMoveFrom (parent);
537546}
538547
539548bool HasMoveFromConstructor (const clang::RecordDecl *decl) {
@@ -544,12 +553,23 @@ bool HasMoveFromConstructor(const clang::RecordDecl *decl) {
544553 });
545554}
546555
556+ static bool HasFieldWithMoveAssign (const clang::RecordDecl *decl) {
557+ return llvm::any_of (decl->fields (), [](const clang::FieldDecl *field) {
558+ auto *record = field->getType ()->getAsCXXRecordDecl ();
559+ return record && llvm::any_of (record->methods (), [](auto *method) {
560+ return IsConvertibleMoveAssignment (method);
561+ });
562+ });
563+ }
564+
547565bool IsConvertibleMoveAssignment (const clang::CXXMethodDecl *method) {
548- return method->isMoveAssignmentOperator () && !method->isDeleted () &&
549- IsConvertibleImplicitMemberParent (method->getParent ()) &&
550- (method->isUserProvided () ||
551- !HasDefaultedCopyAssignment (method->getParent ())) &&
552- method->hasBody ();
566+ auto *parent = method->getParent ();
567+ if (!method->isMoveAssignmentOperator () || method->isDeleted () ||
568+ !method->hasBody () || !IsConvertibleImplicitMemberParent (parent)) {
569+ return false ;
570+ }
571+ return method->isUserProvided () || !HasDefaultedCopyAssignment (parent) ||
572+ HasFieldWithMoveAssign (parent);
553573}
554574
555575bool IsConvertibleImplicitMember (const clang::CXXMethodDecl *method) {
0 commit comments