@@ -6574,6 +6574,17 @@ static bool hasDestroyTypeOperations(const clang::CXXRecordDecl *decl) {
65746574 return false ;
65756575}
65766576
6577+ static bool hasCustomCopyOrMoveConstructor (const clang::CXXRecordDecl *decl) {
6578+ // std::pair and std::tuple might have copy and move constructors, but that
6579+ // doesn't mean they are safe to use from Swift, e.g. std::pair<UnsafeType, T>
6580+ if (decl->isInStdNamespace () &&
6581+ (decl->getName () == " pair" || decl->getName () == " tuple" )) {
6582+ return false ;
6583+ }
6584+ return decl->hasUserDeclaredCopyConstructor () ||
6585+ decl->hasUserDeclaredMoveConstructor ();
6586+ }
6587+
65776588static bool isSwiftClassType (const clang::CXXRecordDecl *decl) {
65786589 // Swift type must be annotated with external_source_symbol attribute.
65796590 auto essAttr = decl->getAttr <clang::ExternalSourceSymbolAttr>();
@@ -6641,8 +6652,7 @@ CxxRecordSemantics::evaluate(Evaluator &evaluator,
66416652 return CxxRecordSemanticsKind::Iterator;
66426653 }
66436654
6644- if (!cxxDecl->hasUserDeclaredCopyConstructor () &&
6645- !cxxDecl->hasUserDeclaredMoveConstructor () &&
6655+ if (!hasCustomCopyOrMoveConstructor (cxxDecl) &&
66466656 hasPointerInSubobjects (cxxDecl)) {
66476657 return CxxRecordSemanticsKind::UnsafePointerMember;
66486658 }
@@ -6730,8 +6740,7 @@ bool IsSafeUseOfCxxDecl::evaluate(Evaluator &evaluator,
67306740 return true ;
67316741 }
67326742
6733- if (!cxxRecordReturnType->hasUserDeclaredCopyConstructor () &&
6734- !cxxRecordReturnType->hasUserDeclaredMoveConstructor () &&
6743+ if (!hasCustomCopyOrMoveConstructor (cxxRecordReturnType) &&
67356744 !hasOwnedValueAttr (cxxRecordReturnType) &&
67366745 hasPointerInSubobjects (cxxRecordReturnType)) {
67376746 return false ;
0 commit comments