1 // Support parsing of concepts
3 // RUN: %clang_cc1 -std=c++20 -verify %s
4 template<typename T
> concept C1
= true; // expected-note 2{{previous}}
6 template<typename T
> concept C1
= true; // expected-error{{redefinition}}
8 template<concept T
> concept D1
= true;
9 // expected-error@-1{{expected template parameter}}
10 // expected-error@-2{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
12 template<template<typename
> concept T
> concept D2
= true;
13 // expected-error@-1{{expected identifier}}
14 // expected-error@-2{{template template parameter requires 'class' or 'typename' after the parameter list}}
15 // expected-error@-3{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
18 template<typename T
> concept C1
= true; // expected-error {{concept declarations may only appear in global or namespace scope}}
22 template<typename T
> concept C1
= true; // expected-error{{redefinition}}
27 concept C2
= true; // expected-error {{extraneous template parameter list in concept definition}}
29 template<typename T
> concept C3
= true; // expected-note {{previous}} expected-note {{previous}}
30 int C3
; // expected-error {{redefinition}}
31 struct C3
{}; // expected-error {{redefinition}}
33 struct C4
{}; // expected-note{{previous definition is here}}
34 template<typename T
> concept C4
= true;
35 // expected-error@-1{{redefinition of 'C4' as different kind of symbol}}
37 // TODO: Add test to prevent explicit specialization, partial specialization
38 // and explicit instantiation of concepts.
40 template<typename T
, T v
>
41 struct integral_constant
{ static constexpr T value
= v
; };
44 template<typename T
> concept C5
= true;
48 template <bool word
> concept C6
= integral_constant
<bool, wor
>::value
;
49 // expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
50 // expected-note@-2{{'word' declared here}}
52 template<typename T
> concept
bool C7
= true;
53 // expected-warning@-1{{ISO C++20 does not permit the 'bool' keyword after 'concept'}}
55 template<> concept C8
= false;
56 // expected-error@-1{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
58 template<> concept C7
<int> = false;
59 // expected-error@-1{{name defined in concept definition must be an identifier}}
61 template<typename T
> concept
N::C9
= false;
62 // expected-error@-1{{name defined in concept definition must be an identifier}}
65 // expected-note@-1{{'A' declared here}}
67 template<typename T
> concept
A::C10
= false;
68 // expected-error@-1{{expected namespace name}}
70 template<typename T
> concept
operator int = false;
71 // expected-error@-1{{name defined in concept definition must be an identifier}}
73 template<bool x
> concept C11
= 2; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
74 template<bool x
> concept C12
= 2 && x
; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
75 template<bool x
> concept C13
= x
|| 2 || x
; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
76 template<bool x
> concept C14
= 8ull && x
|| x
; // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long long')}}
77 template<typename T
> concept C15
= sizeof(T
); // expected-error {{atomic constraint must be of type 'bool'}}
78 template<typename T
> concept C16
= true && (0 && 0); // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
79 // expected-warning@-1{{use of logical '&&' with constant operand}}
80 // expected-note@-2{{use '&' for a bitwise operation}}
81 // expected-note@-3{{remove constant to silence this warning}}
82 template<typename T
> concept C17
= T
{};
83 static_assert(!C17
<bool>);
84 template<typename T
> concept C18
= (bool&&)true;
85 static_assert(C18
<int>);
86 template<typename T
> concept C19
= (const bool&)true;
87 static_assert(C19
<int>);
88 template<typename T
> concept C20
= (const bool)true;
89 static_assert(C20
<int>);
90 template <bool c
> concept C21
= integral_constant
<bool, c
>::value
&& true;
91 static_assert(C21
<true>);
92 static_assert(!C21
<false>);
93 template <bool c
> concept C22
= integral_constant
<bool, c
>::value
;
94 static_assert(C22
<true>);
95 static_assert(!C22
<false>);
97 template <bool word
> concept C23
= integral_constant
<bool, wor
>::value
;
98 // expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
99 // expected-note@-2{{'word' declared here}}