[PATCH] D107399: [clang] fix crash on template instantiation of invalid requires expressions

Matheus Izvekov via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 3 14:16:26 PDT 2021


This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGe64e6924b8ae: [clang] fix crash on template instantiation of invalid requires expressions (authored by mizvekov).

Changed prior to commit:
  https://reviews.llvm.org/D107399?vs=363864&id=363878#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D107399

Files:
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp


Index: clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp
===================================================================
--- clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp
+++ clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp
@@ -91,7 +91,7 @@
 template<class T> concept C1 = sizeof(T) != 0;
 template<class T> concept C2 = C1<typename T::template Y<1>::type>;
 
-template<class T> requires C1<T> void t1() = delete;          // expected-note {{candidate function}}
+template<class T> requires C1<T> void t1() {};                // expected-note {{candidate function}}
 template<class T> requires C1<T> && C2<T> void t1() = delete; // expected-note {{candidate function}}
 template void t1<X>();
 void t1() { t1<X>(); } // expected-error {{call to deleted function 't1'}}
Index: clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
===================================================================
--- clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
+++ clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
@@ -192,3 +192,29 @@
   using c3 = C2_check<has_inner>; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = std_example::has_inner]}}
   using c4 = C3_check<void>; // expected-error{{constraints not satisfied for class template 'C3_check' [with T = void]}}
 }
+
+namespace PR48656 {
+
+template <typename T> concept C = requires { requires requires { T::a; }; };
+// expected-note at -1 {{because 'T::a' would be invalid: no member named 'a' in 'PR48656::T1'}}
+
+template <C...> struct A {};
+// expected-note at -1 {{because 'PR48656::T1' does not satisfy 'C'}}
+
+struct T1 {};
+template struct A<T1>; // expected-error {{constraints not satisfied for class template 'A' [with $0 = <PR48656::T1>]}}
+
+struct T2 { static constexpr bool a = false; };
+template struct A<T2>;
+
+template <typename T> struct T3 {
+  static void m(auto) requires requires { T::fail; } {}
+  // expected-note at -1 {{constraints not satisfied}}
+  // expected-note at -2 {{type 'int' cannot be used prior to '::'}}
+};
+template <typename... Args> void t3(Args... args) { (..., T3<int>::m(args)); }
+// expected-error at -1 {{no matching function for call to 'm'}}
+
+template void t3<int>(int); // expected-note {{requested here}}
+
+} // namespace PR48656
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1934,25 +1934,23 @@
     return Req;
 
   Sema::SFINAETrap Trap(SemaRef);
-  TemplateDeductionInfo Info(Req->getExpr()->getBeginLoc());
 
   llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *>
       TransExpr;
   if (Req->isExprSubstitutionFailure())
     TransExpr = Req->getExprSubstitutionDiagnostic();
   else {
-    Sema::InstantiatingTemplate ExprInst(SemaRef, Req->getExpr()->getBeginLoc(),
-                                         Req, Info,
-                                         Req->getExpr()->getSourceRange());
+    Expr *E = Req->getExpr();
+    TemplateDeductionInfo Info(E->getBeginLoc());
+    Sema::InstantiatingTemplate ExprInst(SemaRef, E->getBeginLoc(), Req, Info,
+                                         E->getSourceRange());
     if (ExprInst.isInvalid())
       return nullptr;
-    ExprResult TransExprRes = TransformExpr(Req->getExpr());
+    ExprResult TransExprRes = TransformExpr(E);
     if (TransExprRes.isInvalid() || Trap.hasErrorOccurred())
-      TransExpr = createSubstDiag(SemaRef, Info,
-          [&] (llvm::raw_ostream& OS) {
-              Req->getExpr()->printPretty(OS, nullptr,
-                                          SemaRef.getPrintingPolicy());
-          });
+      TransExpr = createSubstDiag(SemaRef, Info, [&](llvm::raw_ostream &OS) {
+        E->printPretty(OS, nullptr, SemaRef.getPrintingPolicy());
+      });
     else
       TransExpr = TransExprRes.get();
   }
@@ -1966,6 +1964,7 @@
   else if (RetReq.isTypeConstraint()) {
     TemplateParameterList *OrigTPL =
         RetReq.getTypeConstraintTemplateParameterList();
+    TemplateDeductionInfo Info(OrigTPL->getTemplateLoc());
     Sema::InstantiatingTemplate TPLInst(SemaRef, OrigTPL->getTemplateLoc(),
                                         Req, Info, OrigTPL->getSourceRange());
     if (TPLInst.isInvalid())


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D107399.363878.patch
Type: text/x-patch
Size: 4413 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210803/fde322e5/attachment-0001.bin>


More information about the cfe-commits mailing list