summaryrefslogtreecommitdiffstats
path: root/clang/test/Parser
diff options
context:
space:
mode:
authorSaar Raz <saar@raz.email>2020-01-09 15:07:51 +0200
committerSaar Raz <saar@raz.email>2020-01-09 15:07:51 +0200
commitb65b1f322bd88513586a4539d2b5f18aeb698f3f (patch)
treea5d8eb911df5b6d857675415efc125270826a740 /clang/test/Parser
parent9c91d79dadc660cb6a0ec736389341debd8cd118 (diff)
downloadbcm5719-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.cpp24
-rw-r--r--clang/test/Parser/cxx-concepts-requires-clause.cpp99
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
OpenPOWER on IntegriCloud