[clang] [Clang][Sema] fix a bug on constraint check with template friend function (PR #90646)

via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 30 11:35:35 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Qizhi Hu (jcsxky)

<details>
<summary>Changes</summary>

attempt to fix https://github.com/llvm/llvm-project/issues/90349
Skip to add outer class template arguments to `MTAL` when the friend function has the same depth with its lexical context(`CXXRecordDecl`).

---
Full diff: https://github.com/llvm/llvm-project/pull/90646.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1) 
- (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+14) 
- (added) clang/test/SemaCXX/PR90349.cpp (+43) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c11f117cd6e8b4..ec10c82a3a5403 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -627,6 +627,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;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/90646


More information about the cfe-commits mailing list