================ @@ -2083,6 +2086,97 @@ static void DiagnoseNonTriviallyRelocatableReason(Sema &SemaRef, SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D; } +static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef, + SourceLocation Loc, + const CXXRecordDecl *D) { + for (const CXXBaseSpecifier &B : D->bases()) { + assert(B.getType()->getAsCXXRecordDecl() && "invalid base?"); + if (B.isVirtual()) + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::VBase << B.getType() + << B.getSourceRange(); + if (!B.getType().isTriviallyCopyableType(D->getASTContext())) { + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::NTCBase << B.getType() + << B.getSourceRange(); + } + } + for (const FieldDecl *Field : D->fields()) { + if (!Field->getType().isTriviallyCopyableType(Field->getASTContext())) + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::NTCField << Field + << Field->getType() << Field->getSourceRange(); + } + if (D->hasDeletedDestructor()) + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::DeletedDtr << 0 + << D->getDestructor()->getSourceRange(); + + if (D->isUnion()) { + auto DiagSPM = [&](CXXSpecialMemberKind K, bool Has) { + if (Has) + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K; + }; + DiagSPM(CXXSpecialMemberKind::CopyConstructor, + D->hasUserDeclaredCopyConstructor()); + DiagSPM(CXXSpecialMemberKind::CopyAssignment, + D->hasUserDeclaredCopyAssignment()); + DiagSPM(CXXSpecialMemberKind::MoveConstructor, + D->hasUserDeclaredMoveConstructor()); + DiagSPM(CXXSpecialMemberKind::MoveAssignment, + D->hasUserDeclaredMoveAssignment()); + return; + } + + if (!D->hasSimpleMoveConstructor() && !D->hasSimpleCopyConstructor()) { + const auto *Decl = cast<CXXConstructorDecl>( + LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false)); + if (Decl && Decl->isUserProvided()) + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::UserProvidedCtr + << Decl->isMoveConstructor() << Decl->getSourceRange(); + } + if (!D->hasSimpleMoveAssignment() && !D->hasSimpleCopyAssignment()) { + CXXMethodDecl *Decl = + LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true); + if (Decl && Decl->isUserProvided()) + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::UserProvidedAssign + << Decl->isMoveAssignmentOperator() << Decl->getSourceRange(); + } + CXXDestructorDecl *Dtr = D->getDestructor(); + if (Dtr && Dtr->isUserProvided() && !Dtr->isDefaulted()) + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::DeletedDtr << 1 + << Dtr->getSourceRange(); +} + +static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef, + SourceLocation Loc, QualType T) { + SemaRef.Diag(Loc, diag::note_unsatisfied_trait) + << T << diag::TraitName::TriviallyCopyable; + + if (T->isReferenceType()) + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::Ref; + + T = T.getNonReferenceType(); + + if (T.hasNonTrivialObjCLifetime()) + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::HasArcLifetime; ---------------- cor3ntin wrote:
Arc lifetimes do not impact the ability to copy a type afaik (but they might impact the ability to copy a class containing them, in which case they should have a deleted constructor) @ojhunt https://github.com/llvm/llvm-project/pull/142341 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits