This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [REVISED PATCH 3/9]: C++ P0482R5 char8_t: New core language tests


Attached is a revised patch that addresses changes in P0482R6 as well as feedback provided by Jason for patch 2/9. Changes from the prior patch include:
- New tests to ensure -fchar8_t is implicitly enabled when targeting
  C++2a per adoption of P0482R6 in San Diego.
  - gcc/testsuite/g++.dg/cpp2a/char8_t1.C
  - gcc/testsuite/g++.dg/cpp2a/char8_t2.C
- Updated the value of the __cpp_char8_t feature test macro to 201811
  per P0482R6.
- Updated tests to exercise initialization of signed char and unsigned
  char arrays with ordinary and UTF-8 string literals.
  - gcc/testsuite/g++.dg/ext/char8_t-init-1.C
  - gcc/testsuite/g++.dg/ext/char8_t-init-2.C

Tested on x86_64-linux.

gcc/testsuite/ChangeLog:

2018-11-04  Tom Honermann  <tom@honermann.net>
     * g++.dg/cpp0x/udlit-implicit-conv-neg-char8_t.C: New test cloned
     from udlit-implicit-conv-neg.C.  Validates handling of ill-formed
     uses of char8_t based user defined literals.
     * g++.dg/cpp0x/udlit-resolve-char8_t.C: New test cloned from
     udlit-resolve.C.  Validates handling of well-formed uses of char8_t
     based user defined literals.
     * g++.dg/cpp2a/char8_t1.C: New test; validates char8_t support is
     implicitly enabled when targeting C++2a.
     * g++.dg/cpp2a/char8_t2.C: New test; validates char8_t support is
     disabled when -fno-char8_t is specified when targeting C++2a.
     * g++.dg/ext/char8_t-aliasing-1.C: New test; validates warnings
     for type punning with char8_t types.  Illustrates that char8_t does
     not alias.
     * g++.dg/ext/char8_t-char-literal-1.C: New test; validates u8
     character literals have type char if char8_t support is not
     enabled.
     * g++.dg/ext/char8_t-char-literal-2.C: New test; validates u8
     character literals have type char8_t if char8_t support is
     enabled.
     * g++.dg/ext/char8_t-deduction-1.C: New test; validates char is
     deduced for u8 character and string literals if char8_t support is
     not enabled.
     * g++.dg/ext/char8_t-deduction-2.C: New test; validates char8_t is
     deduced for u8 character and string literals if char8_t support is
     enabled.
     * g++.dg/ext/char8_t-feature-test-macro-1.C: New test; validates
     that the __cpp_char8_t feature test macro is not defined if char8_t
     support is not enabled.
     * g++.dg/ext/char8_t-feature-test-macro-2.C: New test; validates
     that the __cpp_char8_t feature test macro is defined with the
     correct value if char8_t support is enabled.
     * g++.dg/ext/char8_t-init-1.C: New test; validates initialization
     by u8 character and string literals when support for char8_t is not
     enabled.
     * g++.dg/ext/char8_t-init-2.C: New test; validates initialization
     by u8 character and string literals when support for char8_t is
     enabled.
     * g++.dg/ext/char8_t-keyword-1.C: New test; validates that char8_t
     is not a keyword if support for char8_t is not enabled.
     * g++.dg/ext/char8_t-keyword-2.C: New test; validates that char8_t
     is a keyword if support for char8_t is enabled.
     * g++.dg/ext/char8_t-limits-1.C: New test; validates that char8_t
     is unsigned and sufficiently large to store the required range of
     char8_t values.
     * g++.dg/ext/char8_t-overload-1.C: New test; validates overload
     resolution for u8 character and string literal arguments when
     support for char8_t is not enabled.
     * g++.dg/ext/char8_t-overload-2.C: New test; validates overload
     resolution for u8 character and string literal arguments when
     support for char8_t is enabled.
     * g++.dg/ext/char8_t-predefined-macros-1.C: New test; validates
     that the __CHAR8_TYPE__ and __GCC_ATOMIC_CHAR8_T_LOCK_FREE
     predefined macros are not defined when support for char8_t is not
     enabled.
     * g++.dg/ext/char8_t-predefined-macros-2.C: New test; validates
     that the __CHAR8_TYPE__ and __GCC_ATOMIC_CHAR8_T_LOCK_FREE
     predefined macros are defined when support for char8_t is enabled.
     * g++.dg/ext/char8_t-sizeof-1.C: New test; validates that the size
     of char8_t and u8 character literals is 1.
     * g++.dg/ext/char8_t-specialization-1.C: New test; validate
     template specialization for u8 character literal template
     arguments when support for char8_t is not enabled.
     * g++.dg/ext/char8_t-specialization-2.C: New test; validate
     template specialization for char8_t and u8 character literal
     template arguments when support for char8_t is enabled.
     * g++.dg/ext/char8_t-string-literal-1.C: New test; validate the
     type of u8 string literals when support for char8_t is not enabled.
     * g++.dg/ext/char8_t-string-literal-2.C: New test; validate the
     type of u8 string literals when support for char8_t is enabled.
     * g++.dg/ext/char8_t-type-specifier-1.C: New test; validate that
     char8_t is not recognized as a type specifier when support for
     char8_t is not enabled.
     * g++.dg/ext/char8_t-type-specifier-2.C: New test; validate that
     char8_t is recognized as a type specifier when support for char8_t
     is enabled.
     * g++.dg/ext/char8_t-typedef-1.C: New test; validate declarations
     of char8_t as a typedef are accepted when support for char8_t is
     not enabled.
     * g++.dg/ext/char8_t-typedef-2.C: New test; validate declarations
     of char8_t as a typedef are not accepted when support for char8_t
     is enabled.
     * g++.dg/ext/char8_t-udl-1.C: New test; validates overloading for
     u8 character and string literal arguments when support for char8_t
     is not enabled.
     * g++.dg/ext/char8_t-udl-2.C: New test; validates overloading for
     u8 character and string literal arguments when support for char8_t
     is enabled.
     * g++.dg/ext/utf-cvt-char8_t.C: New test cloned from utf-cvt.C;
     validates char8_t conversions.
     * g++.dg/ext/utf-type-char8_t.C: New test cloned from utf-type.C;
     validates that __CHAR8_TYPE__ matches char8_t.

Tom.


diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-implicit-conv-neg-char8_t.C b/gcc/testsuite/g++.dg/cpp0x/udlit-implicit-conv-neg-char8_t.C
new file mode 100644
index 00000000000..b917b5f6b90
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/udlit-implicit-conv-neg-char8_t.C
@@ -0,0 +1,81 @@
+// { dg-options "-std=c++17 -fchar8_t" }
+
+#include <cstdint>
+
+int operator"" _bar (long double);
+
+double operator"" _foo (long long unsigned);
+
+int i = 12_bar; // { dg-error "unable to find numeric literal operator|with|argument" }
+
+double d = 1.2_foo; // { dg-error "unable to find numeric literal operator|with|argument" }
+
+int operator"" _char(char);
+
+int operator"" _char8_t(char8_t);
+
+int operator"" _wchar_t(wchar_t);
+
+int operator"" _char16_t(char16_t);
+
+int operator"" _char32_t(char32_t);
+
+int cwcx = 'c'_wchar_t; // { dg-error "unable to find character literal operator|with|argument" }
+int cc8  = 'c'_char8_t; // { dg-error "unable to find character literal operator|with|argument" }
+int cc16 = 'c'_char16_t; // { dg-error "unable to find character literal operator|with|argument" }
+int cc32 = 'c'_char32_t; // { dg-error "unable to find character literal operator|with|argument" }
+
+int wccx = L'c'_char; // { dg-error "unable to find character literal operator|with|argument" }
+int wcc8 = L'c'_char8_t; // { dg-error "unable to find character literal operator|with|argument" }
+int wcc16 = L'c'_char16_t; // { dg-error "unable to find character literal operator|with|argument" }
+int wcc32 = L'c'_char32_t; // { dg-error "unable to find character literal operator|with|argument" }
+
+int c8c  = u8'c'_char; // { dg-error "unable to find character literal operator|with|argument" }
+int c8wc = u8'c'_wchar_t; // { dg-error "unable to find character literal operator|with|argument" }
+int c8c16 = u8'c'_char16_t; // { dg-error "unable to find character literal operator|with|argument" }
+int c8c32 = u8'c'_char32_t; // { dg-error "unable to find character literal operator|with|argument" }
+
+int c16c = u'c'_char; // { dg-error "unable to find character literal operator|with|argument" }
+int c16c8 = u'c'_char8_t; // { dg-error "unable to find character literal operator|with|argument" }
+int c16wc = u'c'_wchar_t; // { dg-error "unable to find character literal operator|with|argument" }
+int c16c32 = u'c'_char32_t; // { dg-error "unable to find character literal operator|with|argument" }
+
+int c32c = U'c'_char; // { dg-error "unable to find character literal operator|with|argument" }
+int c32c8 = U'c'_char8_t; // { dg-error "unable to find character literal operator|with|argument" }
+int c32wc = U'c'_wchar_t; // { dg-error "unable to find character literal operator|with|argument" }
+int c32c16 = U'c'_char16_t; // { dg-error "unable to find character literal operator|with|argument" }
+
+int operator"" _char_str(const char*, std::size_t);
+
+int operator"" _wchar_t_str(const wchar_t*, std::size_t);
+
+int operator"" _char8_t_str(const char8_t*, std::size_t);
+
+int operator"" _char16_t_str(const char16_t*, std::size_t);
+
+int operator"" _char32_t_str(const char32_t*, std::size_t);
+
+int strwstr = "str"_wchar_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int strstr8 = "str"_char8_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int strstr16 = "str"_char16_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int strstr32 = "str"_char32_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+
+int str8str = u8"str"_char_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str8wstr = u8"str"_wchar_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str8str16 = u8"str"_char16_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str8str32 = u8"str"_char32_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+
+int wstrstr = L"str"_char_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int wstrstr8 = L"str"_char8_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int wstrstr16 = L"str"_char16_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int wstrstr32 = L"str"_char32_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+
+int str16str = u"str"_char_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str16wstr = u"str"_wchar_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str16str8 = u"str"_char8_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str16str32 = u"str"_char32_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+
+int str32str = U"str"_char_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str32wstr = U"str"_wchar_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str32str8 = U"str"_char8_t_str; // { dg-error "unable to find string literal operator string operator|with|arguments" }
+int str32str16 = U"str"_char16_t_str; // { dg-error "unable to find string literal operator string operator|with|arguments" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-resolve-char8_t.C b/gcc/testsuite/g++.dg/cpp0x/udlit-resolve-char8_t.C
new file mode 100644
index 00000000000..19cbd519a86
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/udlit-resolve-char8_t.C
@@ -0,0 +1,38 @@
+// { dg-options "-std=c++17 -fchar8_t" }
+
+#include <cstdint>
+#include <cassert>
+
+int operator"" _foo(const char*)                  { return 0; }
+int operator"" _foo(unsigned long long int)       { return 1; }
+int operator"" _foo(long double)                  { return 2; }
+int operator"" _foo(char)                         { return 3; }
+int operator"" _foo(wchar_t)                      { return 4; }
+int operator"" _foo(char8_t)                      { return 5; }
+int operator"" _foo(char16_t)                     { return 6; }
+int operator"" _foo(char32_t)                     { return 7; }
+int operator"" _foo(const char*, std::size_t)     { return 8; }
+int operator"" _foo(const wchar_t*, std::size_t)  { return 9; }
+int operator"" _foo(const char8_t*, std::size_t)  { return 10; }
+int operator"" _foo(const char16_t*, std::size_t) { return 11; }
+int operator"" _foo(const char32_t*, std::size_t) { return 12; }
+template<char...> int operator"" _foo2()          { return 20; }
+int operator"" _foo2(unsigned long long int)      { return 21; }
+
+int
+main()
+{
+  assert(123_foo == 1);
+  assert(0.123_foo == 2);
+  assert('c'_foo == 3);
+  assert(L'c'_foo == 4);
+  assert(u8'c'_foo == 5);
+  assert(u'c'_foo == 6);
+  assert(U'c'_foo == 7);
+  assert("abc"_foo == 8);
+  assert(L"abc"_foo == 9);
+  assert(u8"abc"_foo == 10);
+  assert(u"abc"_foo == 11);
+  assert(U"abc"_foo == 12);
+  assert(123_foo2 == 21);
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/char8_t1.C b/gcc/testsuite/g++.dg/cpp2a/char8_t1.C
new file mode 100644
index 00000000000..aa0860b9f63
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/char8_t1.C
@@ -0,0 +1,5 @@
+// P0482R6
+// { dg-do compile }
+// { dg-options "-std=c++2a" }
+
+char8_t c8;
diff --git a/gcc/testsuite/g++.dg/cpp2a/char8_t2.C b/gcc/testsuite/g++.dg/cpp2a/char8_t2.C
new file mode 100644
index 00000000000..71eea7952d3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/char8_t2.C
@@ -0,0 +1,5 @@
+// P0482R6
+// { dg-do compile }
+// { dg-options "-std=c++2a -fno-char8_t" }
+
+char8_t c8; // { dg-error "does not name a type" }
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-aliasing-1.C b/gcc/testsuite/g++.dg/ext/char8_t-aliasing-1.C
new file mode 100644
index 00000000000..9252ef9dfa6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-aliasing-1.C
@@ -0,0 +1,8 @@
+// Test that char8_t does not alias with other types when -fchar8_t is enabled.
+// { dg-do compile }
+// { dg-options "-fstrict-aliasing -Wstrict-aliasing=1 -fchar8_t" }
+
+extern long l;
+char8_t* f() {
+  return (char8_t*)&l; // { dg-warning "dereferencing type-punned pointer might break strict-aliasing rules" "char8_t" }
+}
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-char-literal-1.C b/gcc/testsuite/g++.dg/ext/char8_t-char-literal-1.C
new file mode 100644
index 00000000000..8ed85ccfdcd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-char-literal-1.C
@@ -0,0 +1,12 @@
+// Test that UTF-8 character literals have type char if -fchar8_t is not enabled.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fno-char8_t" }
+
+template<typename T1, typename T2>
+  struct is_same
+  { static const bool value = false; };
+template<typename T>
+  struct is_same<T, T>
+  { static const bool value = true; };
+
+static_assert(is_same<decltype(u8'x'), char>::value, "Error");
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-char-literal-2.C b/gcc/testsuite/g++.dg/ext/char8_t-char-literal-2.C
new file mode 100644
index 00000000000..7861736689c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-char-literal-2.C
@@ -0,0 +1,12 @@
+// Test that UTF-8 character literals have type char8_t if -fchar8_t is enabled.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fchar8_t" }
+
+template<typename T1, typename T2>
+  struct is_same
+  { static const bool value = false; };
+template<typename T>
+  struct is_same<T, T>
+  { static const bool value = true; };
+
+static_assert(is_same<decltype(u8'x'), char8_t>::value, "Error");
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-deduction-1.C b/gcc/testsuite/g++.dg/ext/char8_t-deduction-1.C
new file mode 100644
index 00000000000..27f19fe2dc9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-deduction-1.C
@@ -0,0 +1,30 @@
+// Test that char is deduced for UTF-8 character and string literals when
+// -fchar8_t is not in effect.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fno-char8_t" }
+
+template<typename T1, typename T2>
+  struct is_same
+  { static const bool value = false; };
+
+template<typename T>
+  struct is_same<T, T>
+  { static const bool value = true; };
+
+template<typename T1, typename T2, typename T3>
+void ft(T1, T2, T3 &) {
+  static_assert(is_same<T1, char>::value, "Error");
+  static_assert(is_same<T2, const char*>::value, "Error");
+  static_assert(is_same<T3, const char[2]>::value, "Error");
+}
+
+auto x = (ft(u8'x', u8"x", u8"x"),0);
+
+auto c8 = u8'x';
+static_assert(is_same<decltype(c8), char>::value, "Error");
+
+auto c8p = u8"x";
+static_assert(is_same<decltype(c8p), const char*>::value, "Error");
+
+auto &c8a = u8"x";
+static_assert(is_same<decltype(c8a), const char(&)[2]>::value, "Error");
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-deduction-2.C b/gcc/testsuite/g++.dg/ext/char8_t-deduction-2.C
new file mode 100644
index 00000000000..1daf2969d61
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-deduction-2.C
@@ -0,0 +1,30 @@
+// Test that char8_t is deduced for UTF-8 character and string literals when
+// -fchar8_t is in effect.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fchar8_t" }
+
+template<typename T1, typename T2>
+  struct is_same
+  { static const bool value = false; };
+
+template<typename T>
+  struct is_same<T, T>
+  { static const bool value = true; };
+
+template<typename T1, typename T2, typename T3>
+void ft(T1, T2, T3 &) {
+  static_assert(is_same<T1, char8_t>::value, "Error");
+  static_assert(is_same<T2, const char8_t*>::value, "Error");
+  static_assert(is_same<T3, const char8_t[2]>::value, "Error");
+}
+
+auto x = (ft(u8'x', u8"x", u8"x"),0);
+
+auto c8 = u8'x';
+static_assert(is_same<decltype(c8), char8_t>::value, "Error");
+
+auto c8p = u8"x";
+static_assert(is_same<decltype(c8p), const char8_t*>::value, "Error");
+
+auto &c8a = u8"x";
+static_assert(is_same<decltype(c8a), const char8_t(&)[2]>::value, "Error");
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-1.C b/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-1.C
new file mode 100644
index 00000000000..6107cb61ecc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-1.C
@@ -0,0 +1,8 @@
+// Test that predefined feature test macros are not present when -fchar8_t is
+// not enabled.
+// { dg-do compile }
+// { dg-options "-fno-char8_t" }
+
+#if defined(__cpp_char8_t)
+#error __cpp_char8_t is defined!
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C b/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C
new file mode 100644
index 00000000000..df1063f6aa1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C
@@ -0,0 +1,10 @@
+// Test that predefined feature test macros are present when -fchar8_t is
+// enabled.
+// { dg-do compile }
+// { dg-options "-fchar8_t" }
+
+#if !defined(__cpp_char8_t)
+#  error __cpp_char8_t is not defined!
+#elif __cpp_char8_t != 201811
+#  error __cpp_char8_t != 201811
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-init-1.C b/gcc/testsuite/g++.dg/ext/char8_t-init-1.C
new file mode 100644
index 00000000000..e2fd67bac72
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-init-1.C
@@ -0,0 +1,21 @@
+// Test initialization from UTF-8 literals when -fchar8_t is not enabled.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fno-char8_t" }
+
+char c1 = 'x';
+char c2 = u8'x';
+
+const char *pc1 = "x";
+const char *pc2 = u8"x";
+
+const char (&rca1)[2] = "x";
+const char (&rca2)[2] = u8"x";
+
+char ca1[] = "x";
+char ca2[] = u8"x";
+
+signed char sca1[] = "x";
+signed char sca2[] = u8"x";
+
+unsigned char uca1[] = "x";
+unsigned char uca2[] = u8"x";
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-init-2.C b/gcc/testsuite/g++.dg/ext/char8_t-init-2.C
new file mode 100644
index 00000000000..7a7a3a6b208
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-init-2.C
@@ -0,0 +1,33 @@
+// Test initialization from UTF-8 literals when -fchar8_t is enabled.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fchar8_t" }
+
+char c1 = 'x';
+char c2 = u8'x';
+char8_t c3 = 'x';
+char8_t c4 = u8'x';
+char8_t c5 = u'x';
+
+const char *pc1 = "x";
+const char *pc2 = u8"x"; // { dg-error "invalid conversion from .const char8_t.. to .const char.." "char8_t" }
+const char8_t *pc3 = "x"; // { dg-error "invalid conversion from .const char.. to .const char8_t.." "char8_t" }
+const char8_t *pc4 = u8"x";
+const char8_t *pc5 = u"x"; // { dg-error "cannot convert .const char16_t.. to .const char8_t.. in initialization" "char8_t" }
+
+const char (&rca1)[2] = "x";
+const char (&rca2)[2] = u8"x"; // { dg-error "invalid initialization of reference of type .const char ....... from expression of type .const char8_t ...." "char8_t" }
+const char8_t (&rca3)[2] = "x"; // { dg-error "invalid initialization of reference of type .const char8_t ....... from expression of type .const char ...." "char8_t" }
+const char8_t (&rca4)[2] = u8"x";
+const char8_t (&rca5)[2] = u"x"; // { dg-error "invalid initialization of reference of type .const char8_t ....... from expression of type .const char16_t ...." "char8_t" }
+
+char ca1[] = "x";
+char ca2[] = u8"x"; // { dg-error "char-array initialized from UTF-8 string" "char8_t" }
+char8_t ca3[] = "x"; // { dg-error "char8_t-array initialized from ordinary string" "char8_t" }
+char8_t ca4[] = u8"x";
+char8_t ca5[] = u"x"; // { dg-error "char-array initialized from wide string" "char8_t" }
+
+signed char sca1[] = "x";
+signed char sca2[] = u8"x"; // { dg-error "char-array initialized from UTF-8 string" "char8_t" }
+
+unsigned char uca1[] = "x";
+unsigned char uca2[] = u8"x"; // { dg-error "char-array initialized from UTF-8 string" "char8_t" }
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-keyword-1.C b/gcc/testsuite/g++.dg/ext/char8_t-keyword-1.C
new file mode 100644
index 00000000000..f2475094aa5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-keyword-1.C
@@ -0,0 +1,5 @@
+// Test that char8_t is not a keyword if -fchar8_t is not enabled.
+// { dg-do compile }
+// { dg-options "-fno-char8_t" }
+
+int char8_t;
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-keyword-2.C b/gcc/testsuite/g++.dg/ext/char8_t-keyword-2.C
new file mode 100644
index 00000000000..8c84e1e79dd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-keyword-2.C
@@ -0,0 +1,5 @@
+// Test that char8_t is recognized as a keyword if -fchar8_t is enabled.
+// { dg-do compile }
+// { dg-options "-fchar8_t" }
+
+int char8_t; /* { dg-error "multiple types in one declaration|declaration does not declare anything" "char8_t" } */
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-limits-1.C b/gcc/testsuite/g++.dg/ext/char8_t-limits-1.C
new file mode 100644
index 00000000000..0d6df34d23f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-limits-1.C
@@ -0,0 +1,9 @@
+// Test for unsignedness and that the max limit of char8_t is at least 0xFF
+// when -fchar8_t is enabled.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fchar8_t" }
+
+static_assert(u8'\xFF' == 0xFF, "Error");
+static_assert(u8"\xFF"[0] == 0xFF, "Error");
+static_assert(char8_t(-1) >= 0, "Error");
+static_assert(char8_t{-1} >= 0, "Error"); // { dg-error "narrowing conversion of .-1. from .int. to .char8_t." "char8_t" }
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-overload-1.C b/gcc/testsuite/g++.dg/ext/char8_t-overload-1.C
new file mode 100644
index 00000000000..48aa44a6691
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-overload-1.C
@@ -0,0 +1,26 @@
+// Test overloading for UTF-8 literals when -fchar8_t is not in effect.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fno-char8_t" }
+
+template<typename T1, typename T2>
+  struct is_same
+  { static const bool value = false; };
+
+template<typename T>
+  struct is_same<T, T>
+  { static const bool value = true; };
+
+int fc(char);
+long fc(unsigned char);
+static_assert(is_same<decltype(fc('x')), int>::value, "Error");
+static_assert(is_same<decltype(fc(u8'x')), int>::value, "Error");
+
+int fs(const char*);
+long fs(const unsigned char*);
+static_assert(is_same<decltype(fs("x")), int>::value, "Error");
+static_assert(is_same<decltype(fs(u8"x")), int>::value, "Error");
+
+int fr(const char(&)[2]);
+long fr(const unsigned char(&)[2]);
+static_assert(is_same<decltype(fr("x")), int>::value, "Error");
+static_assert(is_same<decltype(fr(u8"x")), int>::value, "Error");
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-overload-2.C b/gcc/testsuite/g++.dg/ext/char8_t-overload-2.C
new file mode 100644
index 00000000000..15e28cd6db2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-overload-2.C
@@ -0,0 +1,26 @@
+// Test overloading for UTF-8 literals when -fchar8_t is in effect.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fchar8_t" }
+
+template<typename T1, typename T2>
+  struct is_same
+  { static const bool value = false; };
+
+template<typename T>
+  struct is_same<T, T>
+  { static const bool value = true; };
+
+int fc(char);
+long fc(char8_t);
+static_assert(is_same<decltype(fc('x')), int>::value, "Error");
+static_assert(is_same<decltype(fc(u8'x')), long>::value, "Error");
+
+int fs(const char*);
+long fs(const char8_t*);
+static_assert(is_same<decltype(fs("x")), int>::value, "Error");
+static_assert(is_same<decltype(fs(u8"x")), long>::value, "Error");
+
+int fr(const char(&)[2]);
+long fr(const char8_t(&)[2]);
+static_assert(is_same<decltype(fr("x")), int>::value, "Error");
+static_assert(is_same<decltype(fr(u8"x")), long>::value, "Error");
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-predefined-macros-1.C b/gcc/testsuite/g++.dg/ext/char8_t-predefined-macros-1.C
new file mode 100644
index 00000000000..36d411b20db
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-predefined-macros-1.C
@@ -0,0 +1,12 @@
+// Test that char8_t related predefined macros are not present when -fchar8_t is
+// not enabled.
+// { dg-do compile }
+// { dg-options "-fno-char8_t" }
+
+#if defined(__CHAR8_TYPE__)
+#error __CHAR8_TYPE__ is defined!
+#endif
+
+#if defined(__GCC_ATOMIC_CHAR8_T_LOCK_FREE)
+#error __GCC_ATOMIC_CHAR8_T_LOCK_FREE is defined!
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-predefined-macros-2.C b/gcc/testsuite/g++.dg/ext/char8_t-predefined-macros-2.C
new file mode 100644
index 00000000000..06d9b246794
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-predefined-macros-2.C
@@ -0,0 +1,12 @@
+// Test that char8_t related predefined macros are present when -fchar8_t is
+// enabled.
+// { dg-do compile }
+// { dg-options "-fchar8_t" }
+
+#if !defined(__CHAR8_TYPE__)
+#error __CHAR8_TYPE__ is not defined!
+#endif
+
+#if !defined(__GCC_ATOMIC_CHAR8_T_LOCK_FREE)
+#error __GCC_ATOMIC_CHAR8_T_LOCK_FREE is not defined!
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-sizeof-1.C b/gcc/testsuite/g++.dg/ext/char8_t-sizeof-1.C
new file mode 100644
index 00000000000..c4bc4cb3872
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-sizeof-1.C
@@ -0,0 +1,7 @@
+// Test sizeof for char8_t.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fchar8_t" }
+
+static_assert(sizeof(u8'x') == 1);
+static_assert(sizeof(char8_t) == 1);
+static_assert(sizeof(__CHAR8_TYPE__) == 1);
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-specialization-1.C b/gcc/testsuite/g++.dg/ext/char8_t-specialization-1.C
new file mode 100644
index 00000000000..1c2fe360abc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-specialization-1.C
@@ -0,0 +1,8 @@
+// Test specialization for UTF-8 literals when -fchar8_t is not enabled.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fno-char8_t" }
+
+template<auto> struct ct { static constexpr int dm = 1; };
+template<> struct ct<'x'> { static constexpr int dm = 2; };
+static_assert(ct<'x'>::dm == 2, "Error");
+static_assert(ct<u8'x'>::dm == 2, "Error");
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-specialization-2.C b/gcc/testsuite/g++.dg/ext/char8_t-specialization-2.C
new file mode 100644
index 00000000000..969e09ecc18
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-specialization-2.C
@@ -0,0 +1,17 @@
+// Test specialization for UTF-8 literals when -fchar8_t is enabled.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fchar8_t" }
+
+template<auto> struct ct { static constexpr int dm = 1; };
+template<> struct ct<'x'> { static constexpr int dm = 2; };
+template<> struct ct<u8'x'> { static constexpr int dm = 3; };
+static_assert(ct<'x'>::dm == 2, "Error");
+static_assert(ct<u8'x'>::dm == 3, "Error");
+
+template<typename T, const T *> struct ct2 { static constexpr int dm = 4; };
+template<const char *P> struct ct2<char,P> { static constexpr int dm = 5; };
+template<const char8_t *P> struct ct2<char8_t,P> { static constexpr int dm = 6; };
+constexpr const char s[] = "x";
+constexpr const char8_t s8[] = u8"x";
+static_assert(ct2<char,s>::dm == 5, "Error");
+static_assert(ct2<char8_t,s8>::dm == 6, "Error");
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-string-literal-1.C b/gcc/testsuite/g++.dg/ext/char8_t-string-literal-1.C
new file mode 100644
index 00000000000..6cfb47be3a9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-string-literal-1.C
@@ -0,0 +1,12 @@
+// Test that UTF-8 string literals have type const char[] if -fchar8_t is not enabled.
+// { dg-do compile { target c++11 } }
+// { dg-options "-fno-char8_t" }
+
+template<typename T1, typename T2>
+  struct is_same
+  { static const bool value = false; };
+template<typename T>
+  struct is_same<T, T>
+  { static const bool value = true; };
+
+static_assert(is_same<decltype(u8""), const char(&)[1]>::value, "Error");
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-string-literal-2.C b/gcc/testsuite/g++.dg/ext/char8_t-string-literal-2.C
new file mode 100644
index 00000000000..f51df72d7ce
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-string-literal-2.C
@@ -0,0 +1,12 @@
+// Test that UTF-8 string literals have type const char8_t[] if -fchar8_t is enabled.
+// { dg-do compile { target c++11 } }
+// { dg-options "-fchar8_t" }
+
+template<typename T1, typename T2>
+  struct is_same
+  { static const bool value = false; };
+template<typename T>
+  struct is_same<T, T>
+  { static const bool value = true; };
+
+static_assert(is_same<decltype(u8""), const char8_t(&)[1]>::value, "Error");
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-type-specifier-1.C b/gcc/testsuite/g++.dg/ext/char8_t-type-specifier-1.C
new file mode 100644
index 00000000000..dac4a47eea3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-type-specifier-1.C
@@ -0,0 +1,5 @@
+// Test that char8_t is not a type specifier if -fchar8_t is not enabled.
+// { dg-do compile }
+// { dg-options "-fno-char8_t" }
+
+char8_t c8; /* { dg-error ".char8_t. does not name a type" "no-char8_t" } */
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-type-specifier-2.C b/gcc/testsuite/g++.dg/ext/char8_t-type-specifier-2.C
new file mode 100644
index 00000000000..ecc5d1c67c0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-type-specifier-2.C
@@ -0,0 +1,16 @@
+// Test that char8_t is recognized as a type specifier if -fchar8_t is enabled.
+// { dg-do compile }
+// { dg-options "-fchar8_t" }
+
+char8_t c8;
+
+signed char8_t         sc8;            /* { dg-error "signed" } */
+unsigned char8_t       uc8;            /* { dg-error "unsigned" } */
+
+short char8_t          shc8;           /* { dg-error "short" } */
+long char8_t           lgc8;           /* { dg-error "long" } */
+
+signed short char8_t   ssc8;           /* { dg-error "signed" } */
+signed long char8_t    slc8;           /* { dg-error "signed" } */
+unsigned short char8_t usc8;           /* { dg-error "unsigned" } */
+unsigned long char8_t  ulc8;           /* { dg-error "unsigned" } */
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-typedef-1.C b/gcc/testsuite/g++.dg/ext/char8_t-typedef-1.C
new file mode 100644
index 00000000000..b77d9a2e6c4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-typedef-1.C
@@ -0,0 +1,6 @@
+// Test that no error is issued for attempted char8_t typedef declarations
+// when -fchar8_t is not enabled.
+// { dg-do compile }
+// { dg-options "-fno-char8_t" }
+
+typedef unsigned char char8_t;
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-typedef-2.C b/gcc/testsuite/g++.dg/ext/char8_t-typedef-2.C
new file mode 100644
index 00000000000..bb20499c26e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-typedef-2.C
@@ -0,0 +1,6 @@
+// Test that an error is issued for attempted char8_t typedef declarations
+// when -fchar8_t is enabled.
+// { dg-do compile }
+// { dg-options "-fchar8_t" }
+
+typedef unsigned char char8_t; // { dg-error "redeclaration" }
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-udl-1.C b/gcc/testsuite/g++.dg/ext/char8_t-udl-1.C
new file mode 100644
index 00000000000..627c263bafe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-udl-1.C
@@ -0,0 +1,19 @@
+// Test overloading for UTF-8 user defined literals when -fchar8_t is not in effect.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fno-char8_t" }
+
+template<typename T1, typename T2>
+  struct is_same
+  { static const bool value = false; };
+
+template<typename T>
+  struct is_same<T, T>
+  { static const bool value = true; };
+
+int operator "" _udcl(char);
+static_assert(is_same<decltype('x'_udcl), int>::value, "Error");
+static_assert(is_same<decltype(u8'x'_udcl), int>::value, "Error");
+
+int operator "" _udsl(const char*, __SIZE_TYPE__);
+static_assert(is_same<decltype("x"_udsl), int>::value, "Error");
+static_assert(is_same<decltype(u8"x"_udsl), int>::value, "Error");
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-udl-2.C b/gcc/testsuite/g++.dg/ext/char8_t-udl-2.C
new file mode 100644
index 00000000000..74cc775e87c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/char8_t-udl-2.C
@@ -0,0 +1,21 @@
+// Test overloading for UTF-8 user defined literals when -fchar8_t is in effect.
+// { dg-do compile }
+// { dg-options "-std=c++17 -fchar8_t" }
+
+template<typename T1, typename T2>
+  struct is_same
+  { static const bool value = false; };
+
+template<typename T>
+  struct is_same<T, T>
+  { static const bool value = true; };
+
+int operator "" _udcl(char);
+long operator "" _udcl(char8_t);
+static_assert(is_same<decltype('x'_udcl), int>::value, "Error");
+static_assert(is_same<decltype(u8'x'_udcl), long>::value, "Error");
+
+int operator "" _udsl(const char*, __SIZE_TYPE__);
+long operator "" _udsl(const char8_t*, __SIZE_TYPE__);
+static_assert(is_same<decltype("x"_udsl), int>::value, "Error");
+static_assert(is_same<decltype(u8"x"_udsl), long>::value, "Error");
diff --git a/gcc/testsuite/g++.dg/ext/utf-cvt-char8_t.C b/gcc/testsuite/g++.dg/ext/utf-cvt-char8_t.C
new file mode 100644
index 00000000000..0170b36da14
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/utf-cvt-char8_t.C
@@ -0,0 +1,39 @@
+/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */
+/* Test the char8_t promotion rules. */
+/* { dg-do compile { target c++11 } } */
+/* { dg-options "-fchar8_t -Wall -Wconversion -Wsign-conversion -Wsign-promo" } */
+
+extern void f_c (char);
+extern void fsc (signed char);
+extern void fuc (unsigned char);
+extern void f_s (short);
+extern void fss (signed short);
+extern void fus (unsigned short);
+extern void f_i (int);
+extern void fsi (signed int);
+extern void fui (unsigned int);
+extern void f_l (long);
+extern void fsl (signed long);
+extern void ful (unsigned long);
+extern void f_ll (long long);
+extern void fsll (signed long long);
+extern void full (unsigned long long);
+
+void m(char8_t c)
+{
+    f_c (c);	/* { dg-warning "change the sign" } */
+    fsc (c);	/* { dg-warning "change the sign" } */
+    fuc (c);
+    f_s (c);
+    fss (c);
+    fus (c);
+    f_i (c);
+    fsi (c);
+    fui (c);
+    f_l (c);
+    fsl (c);
+    ful (c);
+    f_ll (c);
+    fsll (c);
+    full (c);
+}
diff --git a/gcc/testsuite/g++.dg/ext/utf-type-char8_t.C b/gcc/testsuite/g++.dg/ext/utf-type-char8_t.C
new file mode 100644
index 00000000000..a7d8b16a285
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/utf-type-char8_t.C
@@ -0,0 +1,11 @@
+/* Ensure that __CHAR8_TYPE__ exists and matches the underlying type. */
+/* { dg-do run { target c++11 } } */
+/* { dg-options "-fchar8_t -Wall -Werror" } */
+
+extern "C" void abort (void);
+
+int main ()
+{
+    if (sizeof (__CHAR8_TYPE__) != sizeof (char8_t))
+	abort();
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]