luken-google updated this revision to Diff 472029.
luken-google added a comment.

Check template constraint satisfaction logic


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133052/new/

https://reviews.llvm.org/D133052

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaTemplate/concepts.cpp


Index: clang/test/SemaTemplate/concepts.cpp
===================================================================
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -764,3 +764,18 @@
   __iterator_traits_member_pointer_or_arrow_or_void<counted_iterator<int>> f;
 }
 }// namespace InheritedFromPartialSpec
+
+namespace Issue50891 {
+template <typename T>
+concept Numeric =
+    requires(T a) {
+        foo(a);
+    };
+
+struct Deferred {
+    friend void foo(Deferred);
+    template <Numeric TO> operator TO();
+};
+
+static_assert(Numeric<Deferred>); // should not crash clang
+} // namespace Issue50891
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -7675,6 +7675,26 @@
     return;
   }
 
+  if (FunctionTemplate->hasAssociatedConstraints()) {
+    TemplateDeductionInfo ConstraintInfo(FunctionTemplate->getLocation());
+    llvm::SmallVector<const Expr *> AC;
+    FunctionTemplate->getAssociatedConstraints(AC);
+    for (const Expr *ConstraintExpr : AC) {
+      Sema::InstantiatingTemplate Inst(
+          *this, ConstraintExpr->getBeginLoc(),
+          Sema::InstantiatingTemplate::ConstraintSubstitution{},
+          FunctionTemplate, ConstraintInfo, ConstraintExpr->getSourceRange());
+      if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) {
+        OverloadCandidate &Candidate = CandidateSet.addCandidate();
+        Candidate.FoundDecl = FoundDecl;
+        Candidate.Function = FunctionTemplate->getTemplatedDecl();
+        Candidate.Viable = false;
+        Candidate.FailureKind = ovl_fail_constraints_not_satisfied;
+        return;
+      }
+    }
+  }
+
   TemplateDeductionInfo Info(CandidateSet.getLocation());
   CXXConversionDecl *Specialization = nullptr;
   if (TemplateDeductionResult Result
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -588,9 +588,10 @@
   ([temp.func.order]p6.2.1 is not implemented, matching GCC).
 - Implemented `P0857R0 
<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0857r0.html>`_,
   which specifies constrained lambdas and constrained template 
*template-parameter*\s.
-
 - Do not hide templated base members introduced via using-decl in derived class
   (useful specially for constrained members). Fixes `GH50886 
<https://github.com/llvm/llvm-project/issues/50886>`_.
+- Fixed a crash during template instantiation on a conversion operator during 
constraint
+  evaulation. Fixes `GH50891 
<https://github.com/llvm/llvm-project/issues/50891>`_.
 
 C++2b Feature Support
 ^^^^^^^^^^^^^^^^^^^^^


Index: clang/test/SemaTemplate/concepts.cpp
===================================================================
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -764,3 +764,18 @@
   __iterator_traits_member_pointer_or_arrow_or_void<counted_iterator<int>> f;
 }
 }// namespace InheritedFromPartialSpec
+
+namespace Issue50891 {
+template <typename T>
+concept Numeric =
+    requires(T a) {
+        foo(a);
+    };
+
+struct Deferred {
+    friend void foo(Deferred);
+    template <Numeric TO> operator TO();
+};
+
+static_assert(Numeric<Deferred>); // should not crash clang
+} // namespace Issue50891
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -7675,6 +7675,26 @@
     return;
   }
 
+  if (FunctionTemplate->hasAssociatedConstraints()) {
+    TemplateDeductionInfo ConstraintInfo(FunctionTemplate->getLocation());
+    llvm::SmallVector<const Expr *> AC;
+    FunctionTemplate->getAssociatedConstraints(AC);
+    for (const Expr *ConstraintExpr : AC) {
+      Sema::InstantiatingTemplate Inst(
+          *this, ConstraintExpr->getBeginLoc(),
+          Sema::InstantiatingTemplate::ConstraintSubstitution{},
+          FunctionTemplate, ConstraintInfo, ConstraintExpr->getSourceRange());
+      if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) {
+        OverloadCandidate &Candidate = CandidateSet.addCandidate();
+        Candidate.FoundDecl = FoundDecl;
+        Candidate.Function = FunctionTemplate->getTemplatedDecl();
+        Candidate.Viable = false;
+        Candidate.FailureKind = ovl_fail_constraints_not_satisfied;
+        return;
+      }
+    }
+  }
+
   TemplateDeductionInfo Info(CandidateSet.getLocation());
   CXXConversionDecl *Specialization = nullptr;
   if (TemplateDeductionResult Result
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -588,9 +588,10 @@
   ([temp.func.order]p6.2.1 is not implemented, matching GCC).
 - Implemented `P0857R0 <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0857r0.html>`_,
   which specifies constrained lambdas and constrained template *template-parameter*\s.
-
 - Do not hide templated base members introduced via using-decl in derived class
   (useful specially for constrained members). Fixes `GH50886 <https://github.com/llvm/llvm-project/issues/50886>`_.
+- Fixed a crash during template instantiation on a conversion operator during constraint
+  evaulation. Fixes `GH50891 <https://github.com/llvm/llvm-project/issues/50891>`_.
 
 C++2b Feature Support
 ^^^^^^^^^^^^^^^^^^^^^
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to