1 // Support parsing of concepts 2 3 // RUN: %clang_cc1 -std=c++20 -verify %s 4 template<typename T> concept C1 = true; // expected-note 2{{previous}} 5 6 template<typename T> concept C1 = true; // expected-error{{redefinition}} 7 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}} 11 12 template<template<typename> concept T> concept D2 = true; 13 // expected-error@-1{{expected identifier}} 14 // expected-error@-2{{template template parameter requires 'class' 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}} 16 17 struct S1 { 18 template<typename T> concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}} 19 }; 20 21 extern "C++" { 22 template<typename T> concept C1 = true; // expected-error{{redefinition}} 23 } 24 25 template<typename A> 26 template<typename B> 27 concept C2 = true; // expected-error {{extraneous template parameter list in concept definition}} 28 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}} 32 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}} 36 37 // TODO: Add test to prevent explicit specialization, partial specialization 38 // and explicit instantiation of concepts. 39 40 template<typename T, T v> 41 struct integral_constant { static constexpr T value = v; }; 42 43 namespace N { 44 template<typename T> concept C5 = true; 45 } 46 using N::C5; 47 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}} 51 52 template<typename T> concept bool C7 = true; 53 // expected-warning@-1{{ISO C++20 does not permit the 'bool' keyword after 'concept'}} 54 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}} 57 58 template<> concept C7<int> = false; 59 // expected-error@-1{{name defined in concept definition must be an identifier}} 60 61 template<typename T> concept N::C9 = false; 62 // expected-error@-1{{name defined in concept definition must be an identifier}} 63 64 class A { }; 65 // expected-note@-1{{'A' declared here}} 66 67 template<typename T> concept A::C10 = false; 68 // expected-error@-1{{expected namespace name}} 69 70 template<typename T> concept operator int = false; 71 // expected-error@-1{{name defined in concept definition must be an identifier}} 72 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>); 96 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}} 100 101