@@ -30,6 +30,7 @@ extern "C" {
30
30
extern wchar_t *wcschr (const wchar_t *s, wchar_t c);
31
31
extern int wcscmp (const wchar_t *s1, const wchar_t *s2);
32
32
extern int wcsncmp (const wchar_t *s1, const wchar_t *s2, size_t n);
33
+ extern wchar_t *wmemcpy (wchar_t *d, const wchar_t *s, size_t n);
33
34
}
34
35
35
36
namespace strcmp {
@@ -1592,6 +1593,67 @@ namespace WMemChr {
1592
1593
// both-note {{non-constexpr function 'wcschr' cannot be used in a constant expression}}
1593
1594
}
1594
1595
1596
+ namespace WMemCpy {
1597
+ template <typename T>
1598
+ constexpr T result (T (&arr)[4]) {
1599
+ return arr[0 ] * 1000 + arr[1 ] * 100 + arr[2 ] * 10 + arr[3 ];
1600
+ }
1601
+ constexpr int test_wmemcpy (int a, int b, int n) {
1602
+ wchar_t arr[4 ] = {1 , 2 , 3 , 4 };
1603
+ __builtin_wmemcpy (arr + a, arr + b, n);
1604
+ // both-note@-1 2{{overlapping memory regions}}
1605
+ // both-note@-2 {{source is not a contiguous array of at least 2 elements of type 'wchar_t'}}
1606
+ // both-note@-3 {{destination is not a contiguous array of at least 3 elements of type 'wchar_t'}}
1607
+ return result (arr);
1608
+ }
1609
+ static_assert (test_wmemcpy(1 , 2 , 1 ) == 1334 );
1610
+ static_assert (test_wmemcpy(2 , 1 , 1 ) == 1224 );
1611
+ static_assert (test_wmemcpy(0 , 1 , 2 ) == 2334 ); // both-error {{constant}} both-note {{in call}}
1612
+ static_assert (test_wmemcpy(1 , 0 , 2 ) == 1124 ); // both-error {{constant}} both-note {{in call}}
1613
+ static_assert (test_wmemcpy(1 , 2 , 1 ) == 1334 );
1614
+ static_assert (test_wmemcpy(0 , 3 , 1 ) == 4234 );
1615
+ static_assert (test_wmemcpy(0 , 3 , 2 ) == 4234 ); // both-error {{constant}} both-note {{in call}}
1616
+ static_assert (test_wmemcpy(2 , 0 , 3 ) == 4234 ); // both-error {{constant}} both-note {{in call}}
1617
+
1618
+ wchar_t global;
1619
+ constexpr wchar_t *null = 0 ;
1620
+ static_assert (__builtin_wmemcpy(&global, null, sizeof (wchar_t ))); // both-error {{}} \
1621
+ // both-note {{source of 'wmemcpy' is nullptr}}
1622
+ static_assert (__builtin_wmemcpy(null, &global, sizeof (wchar_t ))); // both-error {{}} \
1623
+ // both-note {{destination of 'wmemcpy' is nullptr}}
1624
+ }
1625
+
1626
+ namespace WMemMove {
1627
+ template <typename T>
1628
+ constexpr T result (T (&arr)[4]) {
1629
+ return arr[0 ] * 1000 + arr[1 ] * 100 + arr[2 ] * 10 + arr[3 ];
1630
+ }
1631
+
1632
+ constexpr int test_wmemmove (int a, int b, int n) {
1633
+ wchar_t arr[4 ] = {1 , 2 , 3 , 4 };
1634
+ __builtin_wmemmove (arr + a, arr + b, n);
1635
+ // both-note@-1 {{source is not a contiguous array of at least 2 elements of type 'wchar_t'}}
1636
+ // both-note@-2 {{destination is not a contiguous array of at least 3 elements of type 'wchar_t'}}
1637
+ return result (arr);
1638
+ }
1639
+
1640
+ static_assert (test_wmemmove(1 , 2 , 1 ) == 1334 );
1641
+ static_assert (test_wmemmove(2 , 1 , 1 ) == 1224 );
1642
+ static_assert (test_wmemmove(0 , 1 , 2 ) == 2334 );
1643
+ static_assert (test_wmemmove(1 , 0 , 2 ) == 1124 );
1644
+ static_assert (test_wmemmove(1 , 2 , 1 ) == 1334 );
1645
+ static_assert (test_wmemmove(0 , 3 , 1 ) == 4234 );
1646
+ static_assert (test_wmemmove(0 , 3 , 2 ) == 4234 ); // both-error {{constant}} both-note {{in call}}
1647
+ static_assert (test_wmemmove(2 , 0 , 3 ) == 4234 ); // both-error {{constant}} both-note {{in call}}
1648
+
1649
+ wchar_t global;
1650
+ constexpr wchar_t *null = 0 ;
1651
+ static_assert (__builtin_wmemmove(&global, null, sizeof (wchar_t ))); // both-error {{}} \
1652
+ // both-note {{source of 'wmemmove' is nullptr}}
1653
+ static_assert (__builtin_wmemmove(null, &global, sizeof (wchar_t ))); // both-error {{}} \
1654
+ // both-note {{destination of 'wmemmove' is nullptr}}
1655
+ }
1656
+
1595
1657
namespace Invalid {
1596
1658
constexpr int test () { // both-error {{never produces a constant expression}}
1597
1659
__builtin_abort (); // both-note 2{{subexpression not valid in a constant expression}}
0 commit comments