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@-1 {{because 'T::a' would be invalid: no member named 'a' in 'PR48656::T1'}} + +template <C...> struct A {}; +// expected-note@-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@-1 {{constraints not satisfied}} + // expected-note@-2 {{type 'int' cannot be used prior to '::'}} +}; +template <typename... Args> void t3(Args... args) { (..., T3<int>::m(args)); } +// expected-error@-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())
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@-1 {{because 'T::a' would be invalid: no member named 'a' in 'PR48656::T1'}} + +template <C...> struct A {}; +// expected-note@-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@-1 {{constraints not satisfied}} + // expected-note@-2 {{type 'int' cannot be used prior to '::'}} +}; +template <typename... Args> void t3(Args... args) { (..., T3<int>::m(args)); } +// expected-error@-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())
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits