xref: /llvm-project/clang/test/SemaCXX/static-assert.cpp (revision 09117b21890c652994f7ada0229d309b35b44259)
1 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -pedantic -triple=x86_64-linux-gnu -Wno-invalid-utf8
2 
3 int f(); // expected-note {{declared here}}
4 
5 static_assert(f(), "f"); // expected-error {{static assertion expression is not an integral constant expression}} expected-note {{non-constexpr function 'f' cannot be used in a constant expression}}
6 static_assert(true, "true is not false");
7 static_assert(false, "false is false"); // expected-error {{static assertion failed: false is false}}
8 
9 void g() {
10     static_assert(false, "false is false"); // expected-error {{static assertion failed: false is false}}
11 }
12 
13 class C {
14     static_assert(false, "false is false"); // expected-error {{static assertion failed: false is false}}
15 };
16 
17 template<int N> struct T {
18     static_assert(N == 2, "N is not 2!"); // expected-error {{static assertion failed due to requirement '1 == 2': N is not 2!}}
19 };
20 
21 T<1> t1; // expected-note {{in instantiation of template class 'T<1>' requested here}}
22 T<2> t2;
23 
24 template<typename T> struct S {
25     static_assert(sizeof(T) > sizeof(char), "Type not big enough!"); // expected-error {{static assertion failed due to requirement 'sizeof(char) > sizeof(char)': Type not big enough!}} \
26                                                                      // expected-note {{1 > 1}}
27 };
28 
29 S<char> s1; // expected-note {{in instantiation of template class 'S<char>' requested here}}
30 S<int> s2;
31 
32 static_assert(false, L"\xFFFFFFFF"); // expected-error {{static assertion failed: L"\xFFFFFFFF"}}
33 static_assert(false, u"\U000317FF"); // expected-error {{static assertion failed: u"\U000317FF"}}
34 
35 static_assert(false, u8"Ω"); // expected-error {{static assertion failed: u8"\316\251"}}
36 static_assert(false, L"\u1234"); // expected-error {{static assertion failed: L"\x1234"}}
37 static_assert(false, L"\x1ff" "0\x123" "fx\xfffff" "goop"); // expected-error {{static assertion failed: L"\x1FF""0\x123""fx\xFFFFFgoop"}}
38 
39 static_assert(false, R"(a
40 \tb
41 c
42 )"); // expected-error@-3 {{static assertion failed: a\n\tb\nc\n}}
43 
44 static_assert(false, "\u0080\u0081\u0082\u0083\u0099\u009A\u009B\u009C\u009D\u009E\u009F");
45 // expected-error@-1 {{static assertion failed: <U+0080><U+0081><U+0082><U+0083><U+0099><U+009A><U+009B><U+009C><U+009D><U+009E><U+009F>}}
46 
47 //! Contains RTL/LTR marks
48 static_assert(false, "\u200Eabc\u200Fdef\u200Fgh"); // expected-error {{static assertion failed: ‎abc‏def‏gh}}
49 
50 //! Contains ZWJ/regional indicators
51 static_assert(false, "��️‍�� �������������� ����"); // expected-error {{static assertion failed: ��️‍�� �������������� ����}}
52 
53 template<typename T> struct AlwaysFails {
54   // Only give one error here.
55   static_assert(false, ""); // expected-error {{static assertion failed}}
56 };
57 AlwaysFails<int> alwaysFails;
58 
59 template<typename T> struct StaticAssertProtected {
60   static_assert(__is_literal(T), ""); // expected-error {{static assertion failed}}
61   static constexpr T t = {}; // no error here
62 };
63 struct X { ~X(); };
64 StaticAssertProtected<int> sap1;
65 StaticAssertProtected<X> sap2; // expected-note {{instantiation}}
66 
67 static_assert(true); // expected-warning {{C++17 extension}}
68 static_assert(false); // expected-error-re {{failed{{$}}}} expected-warning {{extension}}
69 
70 
71 // Diagnostics for static_assert with multiple conditions
72 template<typename T> struct first_trait {
73   static const bool value = false;
74 };
75 
76 template<>
77 struct first_trait<X> {
78   static const bool value = true;
79 };
80 
81 template<typename T> struct second_trait {
82   static const bool value = false;
83 };
84 
85 static_assert(first_trait<X>::value && second_trait<X>::value, "message"); // expected-error{{static assertion failed due to requirement 'second_trait<X>::value': message}}
86 
87 namespace std {
88 
89 template <class Tp, Tp v>
90 struct integral_constant {
91   static const Tp value = v;
92   typedef Tp value_type;
93   typedef integral_constant type;
94   constexpr operator value_type() const noexcept { return value; }
95   constexpr value_type operator()() const noexcept { return value; }
96 };
97 
98 template <class Tp, Tp v>
99 const Tp integral_constant<Tp, v>::value;
100 
101 typedef integral_constant<bool, true> true_type;
102 typedef integral_constant<bool, false> false_type;
103 
104 template <class Tp>
105 struct is_const : public false_type {};
106 template <class Tp>
107 struct is_const<Tp const> : public true_type {};
108 
109 // We do not define is_same in terms of integral_constant to check that both implementations are supported.
110 template <typename T, typename U>
111 struct is_same {
112   static const bool value = false;
113 };
114 
115 template <typename T>
116 struct is_same<T, T> {
117   static const bool value = true;
118 };
119 
120 } // namespace std
121 
122 struct ExampleTypes {
123   explicit ExampleTypes(int);
124   using T = int;
125   using U = float;
126 };
127 
128 static_assert(std::is_same<ExampleTypes::T, ExampleTypes::U>::value, "message");
129 // expected-error@-1{{static assertion failed due to requirement 'std::is_same<int, float>::value': message}}
130 static_assert(std::is_const<ExampleTypes::T>::value, "message");
131 // expected-error@-1{{static assertion failed due to requirement 'std::is_const<int>::value': message}}
132 static_assert(!std::is_const<const ExampleTypes::T>::value, "message");
133 // expected-error@-1{{static assertion failed due to requirement '!std::is_const<const int>::value': message}}
134 static_assert(!(std::is_const<const ExampleTypes::T>::value), "message");
135 // expected-error@-1{{static assertion failed due to requirement '!(std::is_const<const int>::value)': message}}
136 static_assert(std::is_const<const ExampleTypes::T>::value == false, "message");
137 // expected-error@-1{{static assertion failed due to requirement 'std::is_const<const int>::value == false': message}}
138 static_assert(!(std::is_const<const ExampleTypes::T>::value == true), "message");
139 // expected-error@-1{{static assertion failed due to requirement '!(std::is_const<const int>::value == true)': message}}
140 static_assert(std::is_const<ExampleTypes::T>(), "message");
141 // expected-error@-1{{static assertion failed due to requirement 'std::is_const<int>()': message}}
142 static_assert(!(std::is_const<const ExampleTypes::T>()()), "message");
143 // expected-error@-1{{static assertion failed due to requirement '!(std::is_const<const int>()())': message}}
144 static_assert(std::is_same<decltype(std::is_const<const ExampleTypes::T>()), int>::value, "message");
145 // expected-error@-1{{static assertion failed due to requirement 'std::is_same<std::is_const<const int>, int>::value': message}}
146 static_assert(std::is_const<decltype(ExampleTypes::T(3))>::value, "message");
147 // expected-error@-1{{static assertion failed due to requirement 'std::is_const<int>::value': message}}
148 static_assert(std::is_const<decltype(ExampleTypes::T())>::value, "message");
149 // expected-error@-1{{static assertion failed due to requirement 'std::is_const<int>::value': message}}
150 static_assert(std::is_const<decltype(ExampleTypes(3))>::value, "message");
151 // expected-error@-1{{static assertion failed due to requirement 'std::is_const<ExampleTypes>::value': message}}
152 
153 struct BI_tag {};
154 struct RAI_tag : BI_tag {};
155 struct MyIterator {
156   using tag = BI_tag;
157 };
158 struct MyContainer {
159   using iterator = MyIterator;
160 };
161 template <class Container>
162 void foo() {
163   static_assert(std::is_same<RAI_tag, typename Container::iterator::tag>::value, "message");
164   // expected-error@-1{{static assertion failed due to requirement 'std::is_same<RAI_tag, BI_tag>::value': message}}
165 }
166 template void foo<MyContainer>();
167 // expected-note@-1{{in instantiation of function template specialization 'foo<MyContainer>' requested here}}
168 
169 namespace ns {
170 template <typename T, int v>
171 struct NestedTemplates1 {
172   struct NestedTemplates2 {
173     template <typename U>
174     struct NestedTemplates3 : public std::is_same<T, U> {};
175   };
176 };
177 } // namespace ns
178 
179 template <typename T, typename U, int a>
180 void foo2() {
181   static_assert(::ns::NestedTemplates1<T, a>::NestedTemplates2::template NestedTemplates3<U>::value, "message");
182   // expected-error@-1{{static assertion failed due to requirement '::ns::NestedTemplates1<int, 3>::NestedTemplates2::NestedTemplates3<float>::value': message}}
183 }
184 template void foo2<int, float, 3>();
185 // expected-note@-1{{in instantiation of function template specialization 'foo2<int, float, 3>' requested here}}
186 
187 template <class T>
188 void foo3(T t) {
189   static_assert(std::is_const<T>::value, "message");
190   // expected-error-re@-1{{static assertion failed due to requirement 'std::is_const<(lambda at {{.*}}static-assert.cpp:{{[0-9]*}}:{{[0-9]*}})>::value': message}}
191   static_assert(std::is_const<decltype(t)>::value, "message");
192   // expected-error-re@-1{{static assertion failed due to requirement 'std::is_const<(lambda at {{.*}}static-assert.cpp:{{[0-9]*}}:{{[0-9]*}})>::value': message}}
193 }
194 void callFoo3() {
195   foo3([]() {});
196   // expected-note@-1{{in instantiation of function template specialization 'foo3<(lambda at }}
197 }
198 
199 template <class T>
200 void foo4(T t) {
201   static_assert(std::is_const<typename T::iterator>::value, "message");
202   // expected-error@-1{{type 'int' cannot be used prior to '::' because it has no members}}
203 }
204 void callFoo4() { foo4(42); }
205 // expected-note@-1{{in instantiation of function template specialization 'foo4<int>' requested here}}
206 
207 static_assert(42, "message");
208 static_assert(42.0, "message"); // expected-warning {{implicit conversion from 'double' to 'bool' changes value from 42 to true}}
209 constexpr int *p = 0;
210 static_assert(p, "message"); // expected-error {{static assertion failed}}
211 
212 struct NotBool {
213 } notBool;
214 constexpr NotBool constexprNotBool;
215 static_assert(notBool, "message");          // expected-error {{value of type 'struct NotBool' is not contextually convertible to 'bool'}}
216 static_assert(constexprNotBool, "message"); // expected-error {{value of type 'const NotBool' is not contextually convertible to 'bool'}}
217 
218 static_assert(1 , "") // expected-error {{expected ';' after 'static_assert'}}
219 
220 
221 namespace Diagnostics {
222   /// No notes for literals.
223   static_assert(false, ""); // expected-error {{failed}}
224   static_assert(1.0 > 2.0, ""); // expected-error {{failed}}
225   static_assert('c' == 'd', ""); // expected-error {{failed}}
226   static_assert(1 == 2, ""); // expected-error {{failed}}
227 
228   /// Simple things are ignored.
229   static_assert(1 == (-(1)), ""); //expected-error {{failed}}
230 
231   /// Chars are printed as chars.
232   constexpr char getChar() {
233     return 'c';
234   }
235   static_assert(getChar() == 'a', ""); // expected-error {{failed}} \
236                                        // expected-note {{evaluates to ''c' == 'a''}}
237 
238   /// Bools are printed as bools.
239   constexpr bool invert(bool b) {
240     return !b;
241   }
242   static_assert(invert(true) == invert(false), ""); // expected-error {{failed}} \
243                                                     // expected-note {{evaluates to 'false == true'}}
244 
245   /// No notes here since we compare a bool expression with a bool literal.
246   static_assert(invert(true) == true, ""); // expected-error {{failed}}
247 
248 #pragma clang diagnostic push
249 #pragma clang diagnostic ignored "-Wc99-extensions"
250   constexpr _Complex float com = {5,6};
251   constexpr _Complex float com2 = {1, 9};
252   static_assert(com == com2, ""); // expected-error {{failed}} \
253                                   // expected-note {{evaluates to '(5 + 6i) == (1 + 9i)'}}
254 #pragma clang diagnostic pop
255 
256 #define CHECK_4(x) ((x) == 4)
257 #define A_IS_B (a == b)
258   static_assert(CHECK_4(5), ""); // expected-error {{failed}}
259 
260   constexpr int a = 4;
261   constexpr int b = 5;
262   static_assert(CHECK_4(a) && A_IS_B, ""); // expected-error {{failed}} \
263                                            // expected-note {{evaluates to '4 == 5'}}
264 
265 
266 }
267