saar.raz created this revision. saar.raz added a reviewer: rsmith. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Allow unconstrained template template parameters to accept constrainted templates as arguments. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D73155 Files: clang/lib/Sema/SemaTemplate.cpp clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp =================================================================== --- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp +++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp @@ -7,9 +7,9 @@ // expected-note@-1{{similar constraint expressions not considered equivalent}} template<template<C> class P> struct S1 { }; // expected-note 2{{'P' declared here}} -template<C> struct X { }; // expected-note{{'X' declared here}} +template<C> struct X { }; -template<D> struct Y { }; // expected-note 2{{'Y' declared here}} +template<D> struct Y { }; // expected-note{{'Y' declared here}} template<typename T> struct Z { }; template<F> struct W { }; // expected-note{{'W' declared here}} @@ -18,10 +18,10 @@ S1<Z> s13; S1<W> s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}} -template<template<typename> class P> struct S2 { }; // expected-note 2{{'P' declared here}} +template<template<typename> class P> struct S2 { }; -S2<X> s21; // expected-error{{template template argument 'X' is more constrained than template template parameter 'P'}} -S2<Y> s22; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}} +S2<X> s21; +S2<Y> s22; S2<Z> s23; template <template <typename...> class C> Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -7164,6 +7164,11 @@ // [temp.constr.order]. SmallVector<const Expr *, 3> ParamsAC, TemplateAC; Params->getAssociatedConstraints(ParamsAC); + // C++2a[temp.arg.template]p3 + // [...] In this comparison, if P is unconstrained, the constraints on A + // are not considered. + if (ParamsAC.empty()) + return false; Template->getAssociatedConstraints(TemplateAC); bool IsParamAtLeastAsConstrained; if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC,
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp =================================================================== --- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp +++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp @@ -7,9 +7,9 @@ // expected-note@-1{{similar constraint expressions not considered equivalent}} template<template<C> class P> struct S1 { }; // expected-note 2{{'P' declared here}} -template<C> struct X { }; // expected-note{{'X' declared here}} +template<C> struct X { }; -template<D> struct Y { }; // expected-note 2{{'Y' declared here}} +template<D> struct Y { }; // expected-note{{'Y' declared here}} template<typename T> struct Z { }; template<F> struct W { }; // expected-note{{'W' declared here}} @@ -18,10 +18,10 @@ S1<Z> s13; S1<W> s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}} -template<template<typename> class P> struct S2 { }; // expected-note 2{{'P' declared here}} +template<template<typename> class P> struct S2 { }; -S2<X> s21; // expected-error{{template template argument 'X' is more constrained than template template parameter 'P'}} -S2<Y> s22; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}} +S2<X> s21; +S2<Y> s22; S2<Z> s23; template <template <typename...> class C> Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -7164,6 +7164,11 @@ // [temp.constr.order]. SmallVector<const Expr *, 3> ParamsAC, TemplateAC; Params->getAssociatedConstraints(ParamsAC); + // C++2a[temp.arg.template]p3 + // [...] In this comparison, if P is unconstrained, the constraints on A + // are not considered. + if (ParamsAC.empty()) + return false; Template->getAssociatedConstraints(TemplateAC); bool IsParamAtLeastAsConstrained; if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits