diff options
| author | Saar Raz <saar@raz.email> | 2020-01-09 15:07:51 +0200 |
|---|---|---|
| committer | Saar Raz <saar@raz.email> | 2020-01-09 15:07:51 +0200 |
| commit | b65b1f322bd88513586a4539d2b5f18aeb698f3f (patch) | |
| tree | a5d8eb911df5b6d857675415efc125270826a740 /clang/test/Parser | |
| parent | 9c91d79dadc660cb6a0ec736389341debd8cd118 (diff) | |
| download | bcm5719-llvm-b65b1f322bd88513586a4539d2b5f18aeb698f3f.tar.gz bcm5719-llvm-b65b1f322bd88513586a4539d2b5f18aeb698f3f.zip | |
[Concepts] Function trailing requires clauses
Function trailing requires clauses now parsed, supported in overload resolution and when calling, referencing and taking the address of functions or function templates.
Differential Revision: https://reviews.llvm.org/D43357
Diffstat (limited to 'clang/test/Parser')
| -rw-r--r-- | clang/test/Parser/cxx-concepts-ambig-constraint-expr.cpp | 24 | ||||
| -rw-r--r-- | clang/test/Parser/cxx-concepts-requires-clause.cpp | 99 |
2 files changed, 89 insertions, 34 deletions
diff --git a/clang/test/Parser/cxx-concepts-ambig-constraint-expr.cpp b/clang/test/Parser/cxx-concepts-ambig-constraint-expr.cpp index 12ab338a6b0..1cd2605ce05 100644 --- a/clang/test/Parser/cxx-concepts-ambig-constraint-expr.cpp +++ b/clang/test/Parser/cxx-concepts-ambig-constraint-expr.cpp @@ -5,25 +5,5 @@ // the syntax is consumed without backtracking. // type-specifier-seq in conversion-type-id -template <typename T> requires (bool)&T::operator short -unsigned int foo(); // expected-error {{C++ requires a type specifier for all declarations}} - -// type-specifier-seq in new-type-id -template <typename T> requires (bool)sizeof new (T::f()) short -unsigned int bar(); // expected-error {{C++ requires a type specifier for all declarations}} - -template<typename T> requires (bool)sizeof new (T::f()) unsigned // expected-error {{'struct' cannot be signed or unsigned}} -struct X { }; // expected-error {{'X' cannot be defined in a type specifier}} - -// C-style cast -// of function call on function-style cast -template <typename T> requires (bool(T())) -T (*fp)(); // expected-error {{use of undeclared identifier 'fp'}} - -// function-style cast -// as the callee in a function call -struct A { - static int t; - template <typename T> requires bool(T()) - (A(T (&t))) { } // expected-error {{called object type 'bool' is not a function or function pointer}} -}; +template <typename T> requires T::operator short +unsigned int foo(); // expected-error {{C++ requires a type specifier for all declarations}}
\ No newline at end of file diff --git a/clang/test/Parser/cxx-concepts-requires-clause.cpp b/clang/test/Parser/cxx-concepts-requires-clause.cpp index 01893a94cbc..60e7004e081 100644 --- a/clang/test/Parser/cxx-concepts-requires-clause.cpp +++ b/clang/test/Parser/cxx-concepts-requires-clause.cpp @@ -1,13 +1,11 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ %s -verify -// expected-no-diagnostics +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify // Test parsing of the optional requires-clause in a template-declaration. template <typename T> requires true void foo() { } - -template <typename T> requires !0 +template <typename T> requires (!0) struct A { void foo(); struct AA; @@ -27,31 +25,30 @@ struct A { using MQ = M<TT>; }; -template <typename T> requires !0 +template <typename T> requires (!0) void A<T>::foo() { } -template <typename T> requires !0 +template <typename T> requires (!0) struct A<T>::AA { }; -template <typename T> requires !0 +template <typename T> requires (!0) enum A<T>::E : int { E0 }; -template <typename T> requires !0 +template <typename T> requires (!0) int A<T>::x = 0; -template <typename T> requires !0 +template <typename T> requires (!0) template <typename> requires true void A<T>::Mfoo() { } -template <typename T> requires !0 +template <typename T> requires (!0) template <typename> requires true struct A<T>::M { }; -template <typename T> requires !0 +template <typename T> requires (!0) template <typename> requires true int A<T>::Mx = 0; - template <typename T> requires true int x = 0; @@ -80,3 +77,81 @@ struct C::M { }; template <typename> requires true int C::Mx = 0; + +// Test behavior with non-primary-expression requires clauses + +template<typename T> requires foo<T>() +// expected-error@-1{{parentheses are required around this expression in a requires clause}} +struct B1 { }; + +int func() { } + +template<typename T> requires func() +// expected-error@-1{{atomic constraint must be of type 'bool' (found '<overloaded function type>')}} +// expected-note@-2{{parentheses are required around this expression in a requires clause}} +struct B2 { }; + +template<typename T> requires (foo<T>()) +struct B3 { }; + +template<typename T> requires T{} +// expected-error@-1{{parentheses are required around this expression in a requires clause}} +struct B4 { }; + +template<typename T> requires sizeof(T) == 0 +// expected-error@-1{{parentheses are required around this expression in a requires clause}} +struct B5 { }; + +template<typename T> requires (sizeof(T)) == 0 +// expected-error@-1{{parentheses are required around this expression in a requires clause}} +struct B6 { }; + +template<typename T> requires 0 +// expected-error@-1{{atomic constraint must be of type 'bool' (found 'int')}} +(int) bar() { }; + +template<typename T> requires foo<T> +(int) bar() { }; +// expected-error@-1{{expected '(' for function-style cast or type construction}} + +template<typename T> +void bar() requires foo<T>(); +// expected-error@-1{{parentheses are required around this expression in a requires clause}} + +template<typename T> +void bar() requires (foo<T>()); + +template<typename T> +void bar() requires func(); +// expected-error@-1{{atomic constraint must be of type 'bool' (found '<overloaded function type>')}} +// expected-note@-2{{parentheses are required around this expression in a requires clause}} + +template<typename T> +void bar() requires T{}; +// expected-error@-1{{parentheses are required around this expression in a requires clause}} + +template<typename T> +void bar() requires sizeof(T) == 0; +// expected-error@-1{{parentheses are required around this expression in a requires clause}} + +template<typename T> +void bar() requires (sizeof(T)) == 0; +// expected-error@-1{{parentheses are required around this expression in a requires clause}} + +void bar(int x, int y) requires (x, y, true); + +struct B { + int x; + void foo(int y) requires (x, this, this->x, y, true); + static void bar(int y) requires (x, true); + // expected-error@-1{{'this' cannot be implicitly used in a static member function declaration}} + static void baz(int y) requires (this, true); + // expected-error@-1{{'this' cannot be used in a static member function declaration}} +}; + +auto lambda1 = [] (auto x) requires (sizeof(decltype(x)) == 1) { }; + +auto lambda2 = [] (auto x) constexpr -> int requires (sizeof(decltype(x)) == 1) { return 0; }; + +auto lambda3 = [] requires (sizeof(char) == 1) { }; +// expected-error@-1{{lambda requires '()' before 'requires' clause}}
\ No newline at end of file |

