[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