@@ -22,6 +22,8 @@ extern "C" {
2222 extern char *strchr (const char *s, int c);
2323 extern wchar_t *wmemchr (const wchar_t *s, wchar_t c, size_t n);
2424 extern wchar_t *wcschr (const wchar_t *s, wchar_t c);
25+ extern int wcscmp (const wchar_t *s1, const wchar_t *s2);
26+ extern int wcsncmp (const wchar_t *s1, const wchar_t *s2, size_t n);
2527}
2628
2729namespace strcmp {
@@ -66,6 +68,50 @@ namespace strcmp {
6668 static_assert (__builtin_strncmp(" abab\0 banana" , " abab\0 canada" , 100 ) == 0 );
6769}
6870
71+ namespace WcsCmp {
72+ constexpr wchar_t kFoobar [6 ] = {L' f' ,L' o' ,L' o' ,L' b' ,L' a' ,L' r' };
73+ constexpr wchar_t kFoobazfoobar [12 ] = {L' f' ,L' o' ,L' o' ,L' b' ,L' a' ,L' z' ,L' f' ,L' o' ,L' o' ,L' b' ,L' a' ,L' r' };
74+
75+ static_assert (__builtin_wcscmp(L" abab" , L" abab" ) == 0 );
76+ static_assert (__builtin_wcscmp(L" abab" , L" abba" ) == -1 );
77+ static_assert (__builtin_wcscmp(L" abab" , L" abaa" ) == 1 );
78+ static_assert (__builtin_wcscmp(L" ababa" , L" abab" ) == 1 );
79+ static_assert (__builtin_wcscmp(L" abab" , L" ababa" ) == -1 );
80+ static_assert (__builtin_wcscmp(L" abab\0 banana" , L" abab" ) == 0 );
81+ static_assert (__builtin_wcscmp(L" abab" , L" abab\0 banana" ) == 0 );
82+ static_assert (__builtin_wcscmp(L" abab\0 banana" , L" abab\0 canada" ) == 0 );
83+ #if __WCHAR_WIDTH__ == 32
84+ static_assert (__builtin_wcscmp(L" a\x83838383 " , L" a" ) == (wchar_t )-1U >> 31);
85+ #endif
86+ static_assert (__builtin_wcscmp(0 , L" abab" ) == 0 ); // both-error {{not an integral constant}} \
87+ // both-note {{dereferenced null}}
88+ static_assert (__builtin_wcscmp(L" abab" , 0 ) == 0 ); // both-error {{not an integral constant}} \
89+ // both-note {{dereferenced null}}
90+
91+ static_assert (__builtin_wcscmp(kFoobar , kFoobazfoobar ) == -1 );
92+ static_assert (__builtin_wcscmp(kFoobar , kFoobazfoobar + 6 ) == 0 ); // both-error {{not an integral constant}} \
93+ // both-note {{dereferenced one-past-the-end}}
94+
95+ static_assert (__builtin_wcsncmp(L" abaa" , L" abba" , 5 ) == -1 );
96+ static_assert (__builtin_wcsncmp(L" abaa" , L" abba" , 4 ) == -1 );
97+ static_assert (__builtin_wcsncmp(L" abaa" , L" abba" , 3 ) == -1 );
98+ static_assert (__builtin_wcsncmp(L" abaa" , L" abba" , 2 ) == 0 );
99+ static_assert (__builtin_wcsncmp(L" abaa" , L" abba" , 1 ) == 0 );
100+ static_assert (__builtin_wcsncmp(L" abaa" , L" abba" , 0 ) == 0 );
101+ static_assert (__builtin_wcsncmp(0 , 0 , 0 ) == 0 );
102+ static_assert (__builtin_wcsncmp(L" abab\0 banana" , L" abab\0 canada" , 100 ) == 0 );
103+ #if __WCHAR_WIDTH__ == 32
104+ static_assert (__builtin_wcsncmp(L" a\x83838383 " , L" aa" , 2 ) ==
105+ (wchar_t )-1U >> 31);
106+ #endif
107+
108+ static_assert (__builtin_wcsncmp(kFoobar , kFoobazfoobar , 6 ) == -1 );
109+ static_assert (__builtin_wcsncmp(kFoobar , kFoobazfoobar , 7 ) == -1 );
110+ static_assert (__builtin_wcsncmp(kFoobar , kFoobazfoobar + 6 , 6 ) == 0 );
111+ static_assert (__builtin_wcsncmp(kFoobar , kFoobazfoobar + 6 , 7 ) == 0 ); // both-error {{not an integral constant}} \
112+ // both-note {{dereferenced one-past-the-end}}
113+ }
114+
69115// / Copied from constant-expression-cxx11.cpp
70116namespace strlen {
71117constexpr const char *a = " foo\0 quux" ;
@@ -1290,6 +1336,12 @@ namespace BuiltinMemcpy {
12901336 return Result1 && Result2;
12911337 }
12921338 static_assert (memmoveOverlapping());
1339+
1340+ #define fold (x ) (__builtin_constant_p(0 ) ? (x) : (x))
1341+ static_assert (__builtin_memcpy(&global, fold((wchar_t *)123 ), sizeof (wchar_t ))); // both-error {{not an integral constant expression}} \
1342+ // both-note {{source of 'memcpy' is (void *)123}}
1343+ static_assert (__builtin_memcpy(fold(reinterpret_cast <wchar_t *>(123 )), &global, sizeof (wchar_t ))); // both-error {{not an integral constant expression}} \
1344+ // both-note {{destination of 'memcpy' is (void *)123}}
12931345}
12941346
12951347namespace Memcmp {
0 commit comments