Ensure comparison of constraints creates a code synth context
authorErich Keane <erich.keane@intel.com>
Thu, 18 May 2023 16:05:51 +0000 (09:05 -0700)
committerErich Keane <erich.keane@intel.com>
Thu, 18 May 2023 16:07:42 +0000 (09:07 -0700)
This is a regression from 6db007a0 that was reported in:
https://github.com/llvm/llvm-project/issues/62697

The assertion was because we require a code synthesis context for the
instantiation of templates, and this reproducer causes a comparison that
doesn't have a parent-template causing one to exists.

This patch fixes it by creating a ConstraintNormalization context.

clang/lib/Sema/SemaConcept.cpp
clang/test/SemaTemplate/concepts-out-of-line-def.cpp

index 2f5fb8f..2588483 100644 (file)
@@ -764,6 +764,15 @@ static const Expr *SubstituteConstraintExpression(Sema &S, const NamedDecl *ND,
     return ConstrExpr;
 
   Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/false);
+
+  Sema::InstantiatingTemplate Inst(
+      S, ND->getLocation(),
+      Sema::InstantiatingTemplate::ConstraintNormalization{},
+      const_cast<NamedDecl *>(ND), SourceRange{});
+
+  if (Inst.isInvalid())
+    return nullptr;
+
   std::optional<Sema::CXXThisScopeRAII> ThisScope;
   if (auto *RD = dyn_cast<CXXRecordDecl>(ND->getDeclContext()))
     ThisScope.emplace(S, const_cast<CXXRecordDecl *>(RD), Qualifiers());
index b7c9171..25b34f0 100644 (file)
@@ -399,3 +399,16 @@ inline void W0<T7, 0>::W1<T8>::f(const T9 &) {}
 } // namespace three_level
 
 } // namespace MultilevelTemplateWithPartialSpecialization
+
+namespace PR62697 {
+template<typename>
+concept c = true;
+
+template<typename T>
+struct s {
+    void f() requires c<void(T)>;
+};
+
+template<typename T>
+void s<T>::f() requires c<void(T)> { }
+}