diff options
author | Richard Smith <richard@metafoo.co.uk> | 2019-12-10 19:50:26 -0800 |
---|---|---|
committer | Richard Smith <richard@metafoo.co.uk> | 2019-12-10 19:54:35 -0800 |
commit | ffe612922cb5aa2767c79d47a1b162811a08583f (patch) | |
tree | 6bb9a155e5dc06a24077030144c19aa624231854 /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | 8e0c9e21bf5f3e7a427b07e3eaf3bc80d2c74cb6 (diff) | |
download | bcm5719-llvm-ffe612922cb5aa2767c79d47a1b162811a08583f.tar.gz bcm5719-llvm-ffe612922cb5aa2767c79d47a1b162811a08583f.zip |
[c++20] Implement P1946R0: allow defaulted comparisons to take their
arguments by value.
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 36528609769..5373bb422ad 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -7921,22 +7921,41 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD, // non-template function declared in the member-specification of C that is // -- a non-static const member of C having one parameter of type // const C&, or - // -- a friend of C having two parameters of type const C&. - QualType ExpectedParmType = - Context.getLValueReferenceType(Context.getRecordType(RD).withConst()); + // -- a friend of C having two parameters of type const C& or two + // parameters of type C. + QualType ExpectedParmType1 = Context.getRecordType(RD); + QualType ExpectedParmType2 = + Context.getLValueReferenceType(ExpectedParmType1.withConst()); + if (isa<CXXMethodDecl>(FD)) + ExpectedParmType1 = ExpectedParmType2; for (const ParmVarDecl *Param : FD->parameters()) { if (!Param->getType()->isDependentType() && - !Context.hasSameType(Param->getType(), ExpectedParmType)) { + !Context.hasSameType(Param->getType(), ExpectedParmType1) && + !Context.hasSameType(Param->getType(), ExpectedParmType2)) { // Don't diagnose an implicit 'operator=='; we will have diagnosed the // corresponding defaulted 'operator<=>' already. if (!FD->isImplicit()) { Diag(FD->getLocation(), diag::err_defaulted_comparison_param) - << (int)DCK << Param->getType() << ExpectedParmType - << Param->getSourceRange(); + << (int)DCK << Param->getType() << ExpectedParmType1 + << !isa<CXXMethodDecl>(FD) + << ExpectedParmType2 << Param->getSourceRange(); } return true; } } + if (FD->getNumParams() == 2 && + !Context.hasSameType(FD->getParamDecl(0)->getType(), + FD->getParamDecl(1)->getType())) { + if (!FD->isImplicit()) { + Diag(FD->getLocation(), diag::err_defaulted_comparison_param_mismatch) + << (int)DCK + << FD->getParamDecl(0)->getType() + << FD->getParamDecl(0)->getSourceRange() + << FD->getParamDecl(1)->getType() + << FD->getParamDecl(1)->getSourceRange(); + } + return true; + } // ... non-static const member ... if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) { |