===================================================================
@@ -3021,6 +3021,13 @@
case PARM_DECL:
case USING_DECL:
case PLACEHOLDER_EXPR:
+ case REQUIRES_EXPR:
+ case EXPR_REQ:
+ case TYPE_REQ:
+ case NESTED_REQ:
+ case VALIDEXPR_EXPR:
+ case VALIDTYPE_EXPR:
+ case CONSTEXPR_EXPR:
return true;
case AGGR_INIT_EXPR:
===================================================================
@@ -2490,6 +2490,9 @@
case CPTK_IS_CLASS:
pp_cxx_ws_string (pp, "__is_class");
break;
+ case CPTK_IS_CONVERTIBLE_TO:
+ pp_cxx_ws_string (pp, "__is_convertible_to");
+ break;
case CPTK_IS_EMPTY:
pp_cxx_ws_string (pp, "__is_empty");
break;
===================================================================
@@ -7629,7 +7629,8 @@
case CPTK_IS_UNION:
case CPTK_IS_SAME_AS:
break;
-
+
+ case CPTK_IS_CONVERTIBLE_TO:
if (!check_trait_type (type1))
return error_mark_node;
if (!check_trait_type (type2))
===================================================================
@@ -0,0 +1,24 @@
+// { dg-options "-std=c++1z" }
+
+template<typename T>
+struct S1 {};
+
+template<typename T>
+concept bool C() { return requires(T x) { { x.fn() } -> S1<T>; }; }
+
+template<C U>
+void fn(U x)
+{
+ x.fn();
+}
+
+struct S2
+{
+ auto fn() const { return S1<S2>(); }
+};
+
+int main()
+{
+ fn(S2{});
+ return 0;
+}