diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index cbf89cb342c73b..6430bf2936b551 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -331,9 +331,6 @@ Bug Fixes `Issue 58800 `_ - Fix an issue that triggers a crash if we instantiate a hidden friend functions. This fixes `Issue 54457 `_ -- Fix an issue about ``decltype`` in the members of class templates derived from - templates with related parameters. - `Issue 58674 `_ Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 39ba75a557df6d..94f52004cf6c27 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2692,34 +2692,20 @@ 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 = true, CheckField = true; - if (IsAddressOfOperand) { - MightBeImplicitMember = SS.isEmpty() && !R.isOverloadedResult(); - CheckField = !R.isUnresolvableResult(); - } - if (MightBeImplicitMember && CheckField) { - if (R.isSingleResult() && - isa(R.getFoundDecl())) { - auto Class = cast((*R.begin())->getDeclContext()); - for (auto Curr = S->getLookupEntity(); Curr && !Curr->isFileContext(); - Curr = Curr->getParent()) { - if (auto ThisClass = dyn_cast_if_present(Curr)) { - if ((MightBeImplicitMember = ThisClass->Equals(Class) || - ThisClass->isDerivedFrom(Class))) - break; - } - } - } else if (IsAddressOfOperand) - MightBeImplicitMember = false; - } + 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(R.getFoundDecl()) || + isa(R.getFoundDecl()) || + isa(R.getFoundDecl()); if (MightBeImplicitMember) return BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, diff --git a/clang/test/SemaCXX/decltype.cpp b/clang/test/SemaCXX/decltype.cpp index 96abb60836e400..32c61bbccc8428 100644 --- a/clang/test/SemaCXX/decltype.cpp +++ b/clang/test/SemaCXX/decltype.cpp @@ -101,44 +101,6 @@ namespace D5789 { template void foo(decltype(T(LP1{ .p1 = g1, .p1.x[1] = 'x' }))) {} } -namespace GH58674 { - struct Foo { - float value_; - struct nested { - float value_; - }; - }; - - template - struct TemplateFoo { - float value_; - }; - - float bar; - - template - struct Animal{}; - - template - class Cat : Animal { - using okay = decltype(Foo::value_); - using also_okay = decltype(bar); - using okay2 = decltype(Foo::nested::value_); - using okay3 = decltype(TemplateFoo::value_); - public: - void meow() { - using okay = decltype(Foo::value_); - using also_okay = decltype(bar); - using okay2 = decltype(Foo::nested::value_); - using okay3 = decltype(TemplateFoo::value_); - } - }; - - void baz() { - Cat{}.meow(); - } -} - template class conditional { };