https://github.com/a-tarasyuk created https://github.com/llvm/llvm-project/pull/96228
Fixes #96043 >From 3345a48624a6f5795cbbdac21b5504322871ea90 Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Thu, 20 Jun 2024 21:51:42 +0300 Subject: [PATCH] [Clang] resolve record declaration of defaulted comparison method by using the first argument --- clang/docs/ReleaseNotes.rst | 2 +- clang/lib/Sema/SemaDeclCXX.cpp | 12 +++++++----- .../SemaCXX/defaulted-comparison-struct.cpp | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 clang/test/SemaCXX/defaulted-comparison-struct.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d0e5e67651364..510804efc6023 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -889,7 +889,7 @@ Bug Fixes to C++ Support between the addresses of two labels (a GNU extension) to a pointer within a constant expression. (#GH95366). - Fix immediate escalation bugs in the presence of dependent call arguments. (#GH94935) - Clang now diagnoses explicit specializations with storage class specifiers in all contexts. - +- Fixed failed assertion when resolving context of defaulted comparison method outside of struct. (#GH96043). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index d38700d56e4ff..066a89edaf6e7 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -9127,6 +9127,11 @@ void Sema::DeclareImplicitEqualityComparison(CXXRecordDecl *RD, popCodeSynthesisContext(); } +static inline CXXRecordDecl *getRecordDeclFromFirstParameter(FunctionDecl *FD) { + auto PT = FD->getParamDecl(0)->getType(); + return PT.getNonReferenceType()->getAsCXXRecordDecl(); +} + void Sema::DefineDefaultedComparison(SourceLocation UseLoc, FunctionDecl *FD, DefaultedComparisonKind DCK) { assert(FD->isDefaulted() && !FD->isDeleted() && @@ -9141,10 +9146,7 @@ void Sema::DefineDefaultedComparison(SourceLocation UseLoc, FunctionDecl *FD, { // Build and set up the function body. - // The first parameter has type maybe-ref-to maybe-const T, use that to get - // the type of the class being compared. - auto PT = FD->getParamDecl(0)->getType(); - CXXRecordDecl *RD = PT.getNonReferenceType()->getAsCXXRecordDecl(); + auto RD = getRecordDeclFromFirstParameter(FD); SourceLocation BodyLoc = FD->getEndLoc().isValid() ? FD->getEndLoc() : FD->getLocation(); StmtResult Body = @@ -9192,7 +9194,7 @@ ComputeDefaultedComparisonExceptionSpec(Sema &S, SourceLocation Loc, EnterExpressionEvaluationContext Context( S, Sema::ExpressionEvaluationContext::Unevaluated); - CXXRecordDecl *RD = cast<CXXRecordDecl>(FD->getLexicalParent()); + auto RD = getRecordDeclFromFirstParameter(FD); SourceLocation BodyLoc = FD->getEndLoc().isValid() ? FD->getEndLoc() : FD->getLocation(); StmtResult Body = diff --git a/clang/test/SemaCXX/defaulted-comparison-struct.cpp b/clang/test/SemaCXX/defaulted-comparison-struct.cpp new file mode 100644 index 0000000000000..de4ec2852a137 --- /dev/null +++ b/clang/test/SemaCXX/defaulted-comparison-struct.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s +// expected-no-diagnostics + +template <typename> class a {}; +template <typename b> b c(a<b>); +template <typename d> class e { +public: + typedef a<d *> f; + f begin(); +}; +template <typename d, typename g> constexpr bool operator==(d h, g i) { + return *c(h.begin()) == *c(i.begin()); +} +struct j { + e<j> bar; + bool operator==(const j &) const; +}; +bool j::operator==(const j &) const = default; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits