https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/86817
>From 468e3d9414a797ea73411a779343dee351e09e42 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski <sdkryst...@gmail.com> Date: Wed, 27 Mar 2024 11:23:19 -0400 Subject: [PATCH 1/4] [Clang][Sema] Fix explicit specializations of member function templates with a deduced return type --- .../clang-tidy/infrastructure/diagnostic.cpp | 2 - clang/lib/Sema/SemaDecl.cpp | 46 ++++++++++++------- .../SemaCXX/deduced-return-type-cxx14.cpp | 18 ++++++++ 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp index d0efc5ca763753..e333c83b895ee7 100644 --- a/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp +++ b/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp @@ -68,6 +68,4 @@ auto S<>::foo(auto) { return 1; } -// CHECK8: error: conflicting types for 'foo' [clang-diagnostic-error] -// CHECK8: note: previous declaration is here #endif diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 9a286e0b26a4c6..be9a05dd2ce570 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -10119,23 +10119,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_auto_fn_virtual); } - if (getLangOpts().CPlusPlus14 && - (NewFD->isDependentContext() || - (isFriend && CurContext->isDependentContext())) && - NewFD->getReturnType()->isUndeducedType()) { - // If the function template is referenced directly (for instance, as a - // member of the current instantiation), pretend it has a dependent type. - // This is not really justified by the standard, but is the only sane - // thing to do. - // FIXME: For a friend function, we have not marked the function as being - // a friend yet, so 'isDependentContext' on the FD doesn't work. - const FunctionProtoType *FPT = - NewFD->getType()->castAs<FunctionProtoType>(); - QualType Result = SubstAutoTypeDependent(FPT->getReturnType()); - NewFD->setType(Context.getFunctionType(Result, FPT->getParamTypes(), - FPT->getExtProtoInfo())); - } - // C++ [dcl.fct.spec]p3: // The inline specifier shall not appear on a block scope function // declaration. @@ -12107,6 +12090,35 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, CheckConstPureAttributesUsage(*this, NewFD); + // C++23 [dcl.spec.auto.general]p12: + // Return type deduction for a templated function with a placeholder in its + // declared type occurs when the definition is instantiated even if the + // function body contains a return statement with a non-type-dependent + // operand. + // + // C++23 [temp.dep.expr]p3: + // An id-expression is type-dependent if it is a template-id that is not a + // concept-id and is dependent; or if its terminal name is: + // - [...] + // - associated by name lookup with one or more declarations of member + // functions of a class that is the current instantiation declared with a + // return type that contains a placeholder type, + // - [...] + // + // If this is a templated function with a placeholder in its return type, + // make the placeholder type dependent since it won't be deduced until the + // definition is instantiated. We do this here because it needs to happen + // for implicitly instantiated member functions/member function templates. + if (getLangOpts().CPlusPlus14 && + (NewFD->isDependentContext() && + NewFD->getReturnType()->isUndeducedType())) { + const FunctionProtoType *FPT = + NewFD->getType()->castAs<FunctionProtoType>(); + QualType NewReturnType = SubstAutoTypeDependent(FPT->getReturnType()); + NewFD->setType(Context.getFunctionType(NewReturnType, FPT->getParamTypes(), + FPT->getExtProtoInfo())); + } + // C++11 [dcl.constexpr]p8: // A constexpr specifier for a non-static member function that is not // a constructor declares that member function to be const. diff --git a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp index 431d77ca785b8e..c33e07088ba32f 100644 --- a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp +++ b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp @@ -237,6 +237,24 @@ namespace Templates { int (S::*(*p)())(double) = f; int (S::*(*q)())(double) = f<S, double>; } + + template<typename T> + struct MemberSpecialization { + auto f(); + template<typename U> auto f(U); + template<typename U> auto *f(U); + }; + + template<> + auto MemberSpecialization<int>::f(); + + template<> + template<typename U> + auto MemberSpecialization<int>::f(U); + + template<> + template<typename U> + auto *MemberSpecialization<int>::f(U); } auto fwd_decl_using(); >From 9afc0c29c96959a175cbccfea38e8021630fe6f5 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski <sdkryst...@gmail.com> Date: Thu, 28 Mar 2024 10:52:21 -0400 Subject: [PATCH 2/4] [FOLD] fix clang-tidy test --- clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp index e333c83b895ee7..57d930b26e64c0 100644 --- a/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp +++ b/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp @@ -25,7 +25,7 @@ // RUN: not clang-tidy -checks='-*,modernize-use-override' %T/diagnostics/input.cpp -- -DCOMPILATION_ERROR 2>&1 | FileCheck -check-prefix=CHECK6 -implicit-check-not='{{warning:|error:}}' %s // RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE -std=c++20 | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s // RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined,clang-diagnostic-literal-conversion' %s -- -DMACRO_FROM_COMMAND_LINE -std=c++20 -Wno-macro-redefined | FileCheck --check-prefix=CHECK7 -implicit-check-not='{{warning:|error:}}' %s -// RUN: not clang-tidy -checks='-*,modernize-use-override' %s -- -std=c++20 -DPR64602 | FileCheck -check-prefix=CHECK8 -implicit-check-not='{{warning:|error:}}' %s +// RUN: clang-tidy -checks='-*,modernize-use-override' %s -- -std=c++20 -DPR64602 // CHECK1: error: no input files [clang-diagnostic-error] // CHECK1: error: no such file or directory: '{{.*}}nonexistent.cpp' [clang-diagnostic-error] >From d1ef19a5f9d9c6c790d477e9a22d7e842ff1ba56 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski <sdkryst...@gmail.com> Date: Thu, 28 Mar 2024 10:59:40 -0400 Subject: [PATCH 3/4] [FOLD] add release note --- clang/docs/ReleaseNotes.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7fbe2fec6ca065..09b87207c74f78 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -345,6 +345,10 @@ Bug Fixes in This Version - Fixes an assertion failure on invalid code when trying to define member functions in lambdas. +- Clang now allows for member function templates of class templates declared with a deduced return type + to be explicitly specialized for a given implicit instantiation of the class template. + + Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >From 3c8edd4b10f44b859a91ad4ce831e87e333795f4 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski <sdkryst...@gmail.com> Date: Fri, 29 Mar 2024 11:51:18 -0400 Subject: [PATCH 4/4] [FOLD] address review comments --- clang/docs/ReleaseNotes.rst | 6 ++---- clang/lib/Sema/SemaDecl.cpp | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 09b87207c74f78..c6e4b9e5310505 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -345,10 +345,6 @@ Bug Fixes in This Version - Fixes an assertion failure on invalid code when trying to define member functions in lambdas. -- Clang now allows for member function templates of class templates declared with a deduced return type - to be explicitly specialized for a given implicit instantiation of the class template. - - Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -449,6 +445,8 @@ Bug Fixes to C++ Support - Fix a crash when instantiating a lambda that captures ``this`` outside of its context. Fixes (#GH85343). - Fix an issue where a namespace alias could be defined using a qualified name (all name components following the first `::` were ignored). +- Fixed a bug that prevented member function templates of class templates declared with a deduced return type + from being explicitly specialized for a given implicit instantiation of the class template. Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index be9a05dd2ce570..1bc37307433004 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12090,13 +12090,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, CheckConstPureAttributesUsage(*this, NewFD); - // C++23 [dcl.spec.auto.general]p12: + // C++ [dcl.spec.auto.general]p12: // Return type deduction for a templated function with a placeholder in its // declared type occurs when the definition is instantiated even if the // function body contains a return statement with a non-type-dependent // operand. // - // C++23 [temp.dep.expr]p3: + // C++ [temp.dep.expr]p3: // An id-expression is type-dependent if it is a template-id that is not a // concept-id and is dependent; or if its terminal name is: // - [...] _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits