brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · 5dcb188 Raw
244 lines · cpp
1// RUN: %clang_cc1 %s -I%S -std=c++2a -verify2 3namespace std { struct type_info; }4 5static_assert(requires { 0; });6static_assert(requires { "aaaa"; });7static_assert(requires { (0).da; }); // expected-error{{member reference base type 'int' is not a structure or union}}8 9struct A {};10struct B {11    B operator+(const B &other) const { return other; }12};13struct C {14    C operator+(C &other) const { return other; }15};16 17template<typename T> requires requires (T a, const T& b) { a + b; }18// expected-note@-1{{because 'a + b' would be invalid: invalid operands to binary expression ('A' and 'const A')}}19// expected-note@-2{{because 'a + b' would be invalid: invalid operands to binary expression ('C' and 'const C')}}20struct r1 {};21 22using r1i1 = r1<int>;23using r1i2 = r1<A>; // expected-error{{constraints not satisfied for class template 'r1' [with T = A]}}24using r1i3 = r1<B>;25using r1i4 = r1<C>; // expected-error{{constraints not satisfied for class template 'r1' [with T = C]}}26 27struct D { void foo() {} };28 29template<typename T> requires requires (T a) { a.foo(); }30// expected-note@-1{{because 'a.foo()' would be invalid: no member named 'foo' in 'A'}}31// expected-note@-2{{because 'a.foo()' would be invalid: member reference base type 'int' is not a structure or union}}32// expected-note@-3{{because 'a.foo()' would be invalid: 'this' argument to member function 'foo' has type 'const D', but function is not marked const}}33struct r2 {};34 35using r2i1 = r2<int>; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}}36using r2i2 = r2<A>; // expected-error{{constraints not satisfied for class template 'r2' [with T = A]}}37using r2i3 = r2<D>;38using r2i4 = r2<const D>; // expected-error{{constraints not satisfied for class template 'r2' [with T = const D]}}39 40template<typename T> requires requires { sizeof(T); }41// expected-note@-1{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'void'}}42// expected-note@-2{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'class nonexistent'}}43struct r3 {};44 45using r3i1 = r3<int>;46using r3i2 = r3<A>;47using r3i3 = r3<A &>;48using r3i4 = r3<void>; // expected-error{{constraints not satisfied for class template 'r3' [with T = void]}}49using r3i4 = r3<class nonexistent>; // expected-error{{constraints not satisfied for class template 'r3' [with T = class nonexistent]}}50 51template<typename T> requires requires (T t) { 0; "a"; (void)'a'; }52struct r4 {};53 54using r4i1 = r4<int>;55using r4i2 = r4<int[10]>;56using r4i3 = r4<int(int)>;57 58template<class T> void f(T) = delete;59template<class T> requires (sizeof(T) == 1) void f(T) { }60 61template<typename T> requires requires(T t) { f(t); }62// expected-note@-1{{because 'f(t)' would be invalid: call to deleted function 'f'}}63struct r5 {};64 65using r5i1 = r5<int>;66// expected-error@-1 {{constraints not satisfied for class template 'r5' [with T = int]}}67using r5i2 = r5<char>;68 69template<typename T>70struct E {71  struct non_default_constructible { non_default_constructible(T t) { } };72};73 74template<typename T> requires requires(T t) { typename E<T>::non_default_constructible{}; }75// expected-note@-1 {{because 'typename E<T>::non_default_constructible{}' would be invalid: no matching constructor for initialization of 'typename E<int>::non_default_constructible'}}76struct r6 {};77 78using r6i1 = r6<int>;79// expected-error@-1 {{constraints not satisfied for class template 'r6' [with T = int]}}80 81template<typename T> requires requires(T t) { typename E<T>::non_default_constructible(); }82// expected-note@-1 {{because 'typename E<T>::non_default_constructible()' would be invalid: no matching constructor for initialization of 'typename E<int>::non_default_constructible'}}83struct r7 {};84 85using r7i1 = r7<int>;86// expected-error@-1 {{constraints not satisfied for class template 'r7' [with T = int]}}87 88// C++ [expr.prim.req.simple] Example89namespace std_example {90  template<typename T> concept C =91    requires (T a, T b) { // expected-note{{because 'a' would be invalid: argument may not have 'void' type}}92      a + b; // expected-note{{because 'a + b' would be invalid: invalid operands to binary expression ('int *' and 'int *')}}93    };94 95  static_assert(C<int>);96  template<C T> struct C_check {}; // expected-note{{because 'void' does not satisfy 'C'}} expected-note{{because 'int *' does not satisfy 'C'}}97  using c1c1 = C_check<void>; // expected-error{{constraints not satisfied for class template 'C_check' [with T = void]}}98  using c1c2 = C_check<int *>; // expected-error{{constraints not satisfied for class template 'C_check' [with T = int *]}}99}100 101// typeid() of an expression becomes potentially evaluated if the expression is102// of a polymorphic type.103class X { virtual ~X(); };104constexpr bool b = requires (X &x) { static_cast<int(*)[(typeid(x), 0)]>(nullptr); };105// expected-warning@-1 {{left operand of comma operator has no effect}}106// expected-warning@-2 {{variable length arrays in C++ are a Clang extension}}107// expected-note@-3{{function parameter 'x' with unknown value cannot be used in a constant expression}}108// expected-note@-4{{declared here}}109 110namespace access_checks {111namespace in_requires_expression {112template<auto>113struct A {114    static constexpr bool foo();115    static constexpr bool bar();116    static constexpr bool baz();117    static constexpr bool faz();118};119 120class C{};121 122class B {123    void p() {}124    bool data_member = true;125    static const bool static_member = true;126    friend struct A<0>;127};128 129template<auto x>130constexpr bool A<x>::foo() {131    return requires(B b) { b.p(); };132}133static_assert(!A<1>::foo());134static_assert(A<0>::foo());135 136template<auto x>137constexpr bool A<x>::bar() {138    return requires() { B::static_member; };139}140static_assert(!A<1>::bar());141static_assert(A<0>::bar());142 143template<auto x>144constexpr bool A<x>::baz() {145    return requires(B b) { b.data_member; };146}147static_assert(!A<1>::baz());148static_assert(A<0>::baz());149 150template<auto x>151constexpr bool A<x>::faz() {152    return requires(B a, B b) { 153      a.p();154      b.data_member;155      B::static_member;156    };157}158static_assert(!A<1>::faz());159static_assert(A<0>::faz());160} // namespace in_requires_expression161 162namespace in_concepts {163// Dependent access does not cause hard errors.164template<int N> class A;165 166template <> class A<0> {167  static void f() {}168};169template<int N>170concept C1 = requires() { A<N>::f(); };171static_assert(!C1<0>);172 173template <> class A<1> {174public: 175  static void f() {}176};177static_assert(C1<1>);178 179// Non-dependent access to private member is a hard error.180class B{181   static void f() {} // expected-note 2{{implicitly declared private here}}182};183template<class T>184concept C2 = requires() { B::f(); }; // expected-error {{'f' is a private member}}185 186constexpr bool non_template_func() {187  return requires() {188      B::f(); // expected-error {{'f' is a private member}}189  };190}191template<int x>192constexpr bool template_func() {193  return requires() {194      A<x>::f();195  };196}197static_assert(!template_func<0>());198static_assert(template_func<1>());199} // namespace in_concepts200 201namespace in_trailing_requires {202template <class> struct B;203class A {204   static void f();205   friend struct B<short>;206};207 208template <class T> struct B {209  static constexpr int index() requires requires{ A::f(); } {210    return 1;211  }212  static constexpr int index() {213    return 2;214  }215};216 217static_assert(B<short>::index() == 1);218static_assert(B<int>::index() == 2);219 220namespace missing_member_function {221template <class T> struct Use;222class X { 223  int a;224  static int B;225  friend struct Use<short>;226};227template <class T> struct Use {228  constexpr static int foo() requires requires(X x) { x.a; } {229    return 1;230  }231  constexpr static int bar() requires requires { X::B; } {232    return 1;233  }234};235 236void test() {237  // FIXME: Propagate diagnostic.238  Use<int>::foo(); //expected-error {{invalid reference to function 'foo': constraints not satisfied}}239  static_assert(Use<short>::foo() == 1);240}241} // namespace missing_member_function242} // namespace in_trailing_requires243} // namespace access_check244