diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -9772,11 +9772,9 @@ case CXXCopyConstructor: case CXXCopyAssignment: { - // Trivial copy operations always have const, non-volatile parameter types. - ConstArg = true; const ParmVarDecl *Param0 = MD->getParamDecl(0); const ReferenceType *RT = Param0->getType()->getAs(); - if (!RT || RT->getPointeeType().getCVRQualifiers() != Qualifiers::Const) { + if (!RT) { if (Diagnose) Diag(Param0->getLocation(), diag::note_nontrivial_param_type) << Param0->getSourceRange() << Param0->getType() @@ -9784,6 +9782,10 @@ Context.getRecordType(RD).withConst()); return false; } + + if (RT && ((RT->getPointeeType().getCVRQualifiers() & Qualifiers::Const) == Qualifiers::Const)) { + ConstArg = true; + } break; } diff --git a/clang/test/CXX/special/class.copy/p12-0x.cpp b/clang/test/CXX/special/class.copy/p12-0x.cpp --- a/clang/test/CXX/special/class.copy/p12-0x.cpp +++ b/clang/test/CXX/special/class.copy/p12-0x.cpp @@ -28,7 +28,18 @@ struct NonConstCopy { NonConstCopy(NonConstCopy &) = default; }; -using _ = not_trivially_copyable; +static_assert(__has_trivial_copy(NonConstCopy), ""); +static_assert(__is_trivially_constructible(NonConstCopy, NonConstCopy&), ""); +static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy), ""); +static_assert(!__is_trivially_constructible(NonConstCopy, const NonConstCopy &), ""); +static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy &&), ""); + +struct DefaultedSpecialMembers { + DefaultedSpecialMembers(const DefaultedSpecialMembers&) = default; + DefaultedSpecialMembers(DefaultedSpecialMembers &) = default; + DefaultedSpecialMembers(DefaultedSpecialMembers &&) = default; +}; +using _ = trivially_copyable; // class X has no virtual functions struct VFn { diff --git a/clang/test/CXX/special/class.copy/p25-0x.cpp b/clang/test/CXX/special/class.copy/p25-0x.cpp --- a/clang/test/CXX/special/class.copy/p25-0x.cpp +++ b/clang/test/CXX/special/class.copy/p25-0x.cpp @@ -31,7 +31,22 @@ struct NonConstCopy { NonConstCopy &operator=(NonConstCopy &) = default; }; -using _ = not_trivially_assignable; +static_assert(__has_trivial_assign(NonConstCopy), ""); +static_assert(__is_trivially_assignable(NonConstCopy&, NonConstCopy&), ""); +static_assert(!__is_trivially_assignable(NonConstCopy&, const NonConstCopy &), ""); +static_assert(!__is_trivially_assignable(NonConstCopy&, NonConstCopy), ""); +static_assert(!__is_trivially_assignable(NonConstCopy&, NonConstCopy&&), ""); +static_assert(__is_trivially_assignable(NonConstCopy&&, NonConstCopy&), ""); +static_assert(!__is_trivially_assignable(NonConstCopy&&, const NonConstCopy &), ""); +static_assert(!__is_trivially_assignable(NonConstCopy&&, NonConstCopy), ""); +static_assert(!__is_trivially_assignable(NonConstCopy&&, NonConstCopy&&), ""); + +struct DefaultedSpecialMembers { + DefaultedSpecialMembers &operator=(const DefaultedSpecialMembers &) = default; + DefaultedSpecialMembers &operator=(DefaultedSpecialMembers &) = default; + DefaultedSpecialMembers &operator=(DefaultedSpecialMembers &&) = default; +}; +using _ = trivially_assignable; // class X has no virtual functions struct VFn {