Author: Liming Liu Date: 2023-01-04T07:47:17-08:00 New Revision: 85960043d594fc12d340ccb66a30861b023ab496
URL: https://github.com/llvm/llvm-project/commit/85960043d594fc12d340ccb66a30861b023ab496 DIFF: https://github.com/llvm/llvm-project/commit/85960043d594fc12d340ccb66a30861b023ab496.diff LOG: [clang] Add the check of membership in decltype for the issue #58674# Originally, the code would take a lookup result as a member in the current scope and build a member expression accordingly, if the lookup result was not an operand of the address operator, or it was a field declaration. However, a field declaration may come from another class, and cause the issue #58674. Thus, this patch fixes the issue via checking where does the field declaration comes from, and if it comes from another class, then marks it as not member in the current scope. The parent scopes of the current scope are also checked, as the current scope may be associated to a lambda or friend declaration. Differential Revision: https://reviews.llvm.org/D137531 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaExpr.cpp clang/test/SemaCXX/decltype.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 0fe009740082..c4030387ae55 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -331,6 +331,9 @@ Bug Fixes `Issue 58800 <https://github.com/llvm/llvm-project/issues/58800>`_ - Fix an issue that triggers a crash if we instantiate a hidden friend functions. This fixes `Issue 54457 <https://github.com/llvm/llvm-project/issues/54457>`_ +- Fix an issue about ``decltype`` in the members of class templates derived from + templates with related parameters. + `Issue 58674 <https://github.com/llvm/llvm-project/issues/58674>`_ Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 94f52004cf6c..39ba75a557df 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2692,20 +2692,34 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, // to get this right here so that we don't end up making a // spuriously dependent expression if we're inside a dependent // instance method. + // + // We also don't need to do this if R resolved to a member in another + // class, which can happen in an unevaluated operand: + // + // C++ [expr.prim.id]p3.3: + // If that id-expression denotes a non-static data member and it + // appears in an unevaluated operand. if (!R.empty() && (*R.begin())->isCXXClassMember()) { - bool MightBeImplicitMember; - if (!IsAddressOfOperand) - MightBeImplicitMember = true; - else if (!SS.isEmpty()) - MightBeImplicitMember = false; - else if (R.isOverloadedResult()) - MightBeImplicitMember = false; - else if (R.isUnresolvableResult()) - MightBeImplicitMember = true; - else - MightBeImplicitMember = isa<FieldDecl>(R.getFoundDecl()) || - isa<IndirectFieldDecl>(R.getFoundDecl()) || - isa<MSPropertyDecl>(R.getFoundDecl()); + bool MightBeImplicitMember = true, CheckField = true; + if (IsAddressOfOperand) { + MightBeImplicitMember = SS.isEmpty() && !R.isOverloadedResult(); + CheckField = !R.isUnresolvableResult(); + } + if (MightBeImplicitMember && CheckField) { + if (R.isSingleResult() && + isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(R.getFoundDecl())) { + auto Class = cast<CXXRecordDecl>((*R.begin())->getDeclContext()); + for (auto Curr = S->getLookupEntity(); Curr && !Curr->isFileContext(); + Curr = Curr->getParent()) { + if (auto ThisClass = dyn_cast_if_present<CXXRecordDecl>(Curr)) { + if ((MightBeImplicitMember = ThisClass->Equals(Class) || + ThisClass->isDerivedFrom(Class))) + break; + } + } + } else if (IsAddressOfOperand) + MightBeImplicitMember = false; + } if (MightBeImplicitMember) return BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, diff --git a/clang/test/SemaCXX/decltype.cpp b/clang/test/SemaCXX/decltype.cpp index 32c61bbccc84..96abb60836e4 100644 --- a/clang/test/SemaCXX/decltype.cpp +++ b/clang/test/SemaCXX/decltype.cpp @@ -101,6 +101,44 @@ namespace D5789 { template<class T> void foo(decltype(T(LP1{ .p1 = g1, .p1.x[1] = 'x' }))) {} } +namespace GH58674 { + struct Foo { + float value_; + struct nested { + float value_; + }; + }; + + template <typename T> + struct TemplateFoo { + float value_; + }; + + float bar; + + template <typename T> + struct Animal{}; + + template <typename T> + class Cat : Animal<T> { + using okay = decltype(Foo::value_); + using also_okay = decltype(bar); + using okay2 = decltype(Foo::nested::value_); + using okay3 = decltype(TemplateFoo<T>::value_); + public: + void meow() { + using okay = decltype(Foo::value_); + using also_okay = decltype(bar); + using okay2 = decltype(Foo::nested::value_); + using okay3 = decltype(TemplateFoo<T>::value_); + } + }; + + void baz() { + Cat<void>{}.meow(); + } +} + template<typename> class conditional { }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits