https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/90646
>From 50aa5b64f6d2cf98706bfb4792f274bd071e3b9c Mon Sep 17 00:00:00 2001 From: Qizhi Hu <836744...@qq.com> Date: Wed, 1 May 2024 02:25:04 +0800 Subject: [PATCH 1/2] [Clang][Sema] fix a bug on constraint check with template friend function --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Sema/SemaTemplateInstantiate.cpp | 14 +++++++ clang/test/SemaCXX/PR90349.cpp | 43 ++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 clang/test/SemaCXX/PR90349.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 2c5308fbcb319a..ac90e3933798cb 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -630,6 +630,7 @@ Bug Fixes to C++ Support - Fix a bug on template partial specialization with issue on deduction of nontype template parameter whose type is `decltype(auto)`. Fixes (#GH68885). - Clang now correctly treats the noexcept-specifier of a friend function to be a complete-class context. +- Fix a bug on constraint check with template friend function. Fixes (#GH90349). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 3a9fd906b7af86..1805f8f6e5ad90 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -281,6 +281,20 @@ Response HandleFunction(Sema &SemaRef, const FunctionDecl *Function, if (Function->getPrimaryTemplate()->isMemberSpecialization()) return Response::Done(); + if (Function->getFriendObjectKind()) + if (const ClassTemplateSpecializationDecl *TD = + dyn_cast<ClassTemplateSpecializationDecl>( + Function->getLexicalDeclContext())) { + const CXXRecordDecl *TemplatePattern = + TD->getTemplateInstantiationPattern(); + const FunctionDecl *FunctionPattern = + Function->getTemplateInstantiationPattern(); + if (TemplatePattern && FunctionPattern && + TemplatePattern->getTemplateDepth() == + FunctionPattern->getTemplateDepth()) + return Response::Done(); + } + // If this function is a generic lambda specialization, we are done. if (!ForConstraintInstantiation && isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function)) { diff --git a/clang/test/SemaCXX/PR90349.cpp b/clang/test/SemaCXX/PR90349.cpp new file mode 100644 index 00000000000000..6a4b5c21e88f3b --- /dev/null +++ b/clang/test/SemaCXX/PR90349.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s + +// expected-no-diagnostics + +namespace std { +template<class T> +concept floating_point = __is_same(T,double) || __is_same(T,float); + +template<class T> +concept integral = __is_same(T,int); + +} + +template<std::integral T, std::floating_point Float> +class Blob; + +template<std::floating_point Float, std::integral T> +Blob<T, Float> MakeBlob(); + +template<std::integral T, std::floating_point Float> +class Blob { +private: + Blob() {} + + friend Blob<T, Float> MakeBlob<Float, T>(); +}; + +template<std::floating_point Float, std::integral T> +Blob<T, Float> MakeBlob() +{ + return Blob<T, Float>(); +} + +template<std::floating_point Float, std::integral T> +Blob<T, Float> FindBlobs() +{ + return MakeBlob<Float, T>(); +} + +int main(int argc, const char * argv[]) { + FindBlobs<double, int>(); + return 0; +} >From 3d27f11d79b00608bf9135bcc4b4cb859027933a Mon Sep 17 00:00:00 2001 From: Qizhi Hu <836744...@qq.com> Date: Thu, 2 May 2024 20:05:10 +0800 Subject: [PATCH 2/2] continue to handle context instead of finish --- clang/lib/Sema/SemaTemplateInstantiate.cpp | 2 +- clang/test/SemaCXX/PR90349.cpp | 24 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 1805f8f6e5ad90..22789c72b2c90f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -292,7 +292,7 @@ Response HandleFunction(Sema &SemaRef, const FunctionDecl *Function, if (TemplatePattern && FunctionPattern && TemplatePattern->getTemplateDepth() == FunctionPattern->getTemplateDepth()) - return Response::Done(); + return Response::UseNextDecl(Function); } // If this function is a generic lambda specialization, we are done. diff --git a/clang/test/SemaCXX/PR90349.cpp b/clang/test/SemaCXX/PR90349.cpp index 6a4b5c21e88f3b..570a49fd2073bb 100644 --- a/clang/test/SemaCXX/PR90349.cpp +++ b/clang/test/SemaCXX/PR90349.cpp @@ -41,3 +41,27 @@ int main(int argc, const char * argv[]) { FindBlobs<double, int>(); return 0; } + +template<typename T, typename U> +concept D = sizeof(T) == sizeof(U); + +template<typename T> +struct A +{ + template<typename U, typename V> requires D<U, V> + static void f(); +}; + +template<typename T, typename U> +struct B +{ + template<typename V> + struct C + { + friend void A<char>::f<T, U>(); + }; +}; + +template struct B<int, int>::C<short>; + +extern template void A<char>::f<int, int>(); // crash here _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits