152 lines · cpp
1// RUN: %clang_cc1 -verify -fsyntax-only -std=c++20 -Wconversion %s2 3void c8(char8_t);4void c16(char16_t);5void c32(char32_t);6 7void test(char8_t u8, char16_t u16, char32_t u32) {8 c8(u8);9 c8(u16); // expected-warning {{implicit conversion from 'char16_t' to 'char8_t' may lose precision and change the meaning of the represented code unit}}10 c8(u32); // expected-warning {{implicit conversion from 'char32_t' to 'char8_t' may lose precision and change the meaning of the represented code unit}}11 12 c16(u8); // expected-warning {{implicit conversion from 'char8_t' to 'char16_t' may change the meaning of the represented code unit}}13 c16(u16);14 c16(u32); // expected-warning {{implicit conversion from 'char32_t' to 'char16_t' may lose precision and change the meaning of the represented code unit}}15 16 c32(u8); // expected-warning {{implicit conversion from 'char8_t' to 'char32_t' may change the meaning of the represented code unit}}17 c32(u16);18 c32(u32);19 20 21 c8(char32_t(0x7f));22 c8(char32_t(0x80)); // expected-warning {{implicit conversion from 'char32_t' to 'char8_t' changes the meaning of the code point '<U+0080>'}}23 24 c8(char16_t(0x7f));25 c8(char16_t(0x80)); // expected-warning {{implicit conversion from 'char16_t' to 'char8_t' changes the meaning of the code point '<U+0080>'}}26 c8(char16_t(0xD800)); // expected-warning {{implicit conversion from 'char16_t' to 'char8_t' changes the meaning of the code unit '<0xD800>'}}27 c8(char16_t(0xE000)); // expected-warning {{implicit conversion from 'char16_t' to 'char8_t' changes the meaning of the code point '<U+E000>'}}28 29 30 c16(char32_t(0x7f));31 c16(char32_t(0x80));32 c16(char32_t(0xD7FF));33 c16(char32_t(0xD800));34 c16(char32_t(0xE000));35 c16(char32_t(U'🐉')); // expected-warning {{implicit conversion from 'char32_t' to 'char16_t' changes the meaning of the code point '🐉'}}36 37 38 c32(char8_t(0x7f));39 c32(char8_t(0x80)); // expected-warning {{implicit conversion from 'char8_t' to 'char32_t' changes the meaning of the code unit '<0x80>'}}40 c32(char8_t(0xFF)); // expected-warning {{implicit conversion from 'char8_t' to 'char32_t' changes the meaning of the code unit '<0xFF>'}}41 42 43 c32(char16_t(0x7f));44 c32(char16_t(0x80));45 46 c32(char16_t(0xD7FF));47 c32(char16_t(0xD800));48 c32(char16_t(0xDFFF));49 c32(char16_t(0xE000));50 c32(char16_t(u'☕'));51 52 (void)static_cast<char32_t>(char8_t(0x80)); //no warnings for explicit conversions.53 54 using Char8 = char8_t;55 Char8 c81 = u16; // expected-warning {{implicit conversion from 'char16_t' to 'Char8' (aka 'char8_t') may lose precision and change the meaning of the represented code unit}}56 57 [[maybe_unused]] char c = u16; // expected-warning {{implicit conversion loses integer precision: 'char16_t' to 'char'}}58 59 // FIXME: We should apply the same logic to wchar60 [[maybe_unused]] wchar_t wc = u16;61 [[maybe_unused]] wchar_t wc2 = u8;62}63 64void test_comp(char8_t u8, char16_t u16, char32_t u32) {65 (void)(u8 == u8' ');66 (void)(u8 == u' ');67 (void)(u8 == U' ');68 69 (void)(u16 == u8' ');70 (void)(u16 == U' ');71 72 (void)(u32 == u8' ');73 (void)(u32 == u' ');74 (void)(u32 == U' ');75 76 (void)(u8 == u'\u00FF'); // expected-warning{{comparing values of different Unicode code unit types 'char8_t' and 'char16_t' may compare different code points}}77 (void)(u8 == U'\u00FF'); // expected-warning{{comparing values of different Unicode code unit types 'char8_t' and 'char32_t' may compare different code points}}78 79 (void)(u16 == u8'\xFF'); // expected-warning{{comparing values of different Unicode code unit types 'char16_t' and 'char8_t' may compare different code points}}80 (void)(u16 == u'\u00FF');81 (void)(u16 == U'\u00FF');82 (void)(u16 == U'\xD800'); // expected-warning{{comparing values of different Unicode code unit types 'char16_t' and 'char32_t' may compare different code points}}83 84 (void)(u32 == u8'\xFF'); // expected-warning{{comparing values of different Unicode code unit types 'char32_t' and 'char8_t' may compare different code points}}85 (void)(u32 == u'\u00FF');86 (void)(u32 == u'\xD800'); // expected-warning{{comparing values of different Unicode code unit types 'char32_t' and 'char16_t' may compare different code points}}87 88 (void)(char8_t(0x7f) == char8_t(0x7f));89 (void)(char8_t(0x7f) == char16_t(0x7f));90 (void)(char8_t(0x7f) == char32_t(0x7f));91 92 (void)(char8_t(0x80) == char8_t(0x80));93 (void)(char8_t(0x80) == char16_t(0x80)); // expected-warning{{comparing values of different Unicode code unit types 'char8_t' and 'char16_t' compares unrelated code units '<0x80>' and '<U+0080>}}94 (void)(char8_t(0x80) == char32_t(0x80)); // expected-warning{{comparing values of different Unicode code unit types 'char8_t' and 'char32_t' compares unrelated code units '<0x80>' and '<U+0080>}}95 96 (void)(char8_t(0x80) == char8_t(0x7f));97 (void)(char8_t(0x80) == char16_t(0x7f)); // expected-warning{{comparing values of different Unicode code unit types 'char8_t' and 'char16_t' compares unrelated code units '<0x80>' and '<U+007F>'}}98 (void)(char8_t(0x80) == char32_t(0x7f)); // expected-warning{{comparing values of different Unicode code unit types 'char8_t' and 'char32_t' compares unrelated code units '<0x80>' and '<U+007F>'}}99 100 101 (void)(char16_t(0x7f) < char8_t(0x7f));102 (void)(char16_t(0x7f) < char16_t(0x7f));103 (void)(char16_t(0x7f) < char32_t(0x7f));104 105 (void)(char16_t(0x80) < char8_t(0x80)); // expected-warning{{comparing values of different Unicode code unit types 'char16_t' and 'char8_t' compares unrelated code units '<U+0080>' and '<0x80>'}}106 (void)(char16_t(0x80) < char16_t(0x80));107 (void)(char16_t(0x80) < char32_t(0x80));108 109 (void)(char16_t(0x80) == char8_t(0x7f));110 (void)(char16_t(0x80) < char16_t(0x7f));111 (void)(char16_t(0x80) < char32_t(0x7f));112 113 114 (void)(char32_t(0x7f) < char8_t(0x7f));115 (void)(char32_t(0x7f) < char16_t(0x7f));116 (void)(char32_t(0x7f) < char32_t(0x7f));117 118 (void)(char32_t(0x80) < char8_t(0x80)); // expected-warning{{comparing values of different Unicode code unit types 'char32_t' and 'char8_t' compares unrelated code units '<U+0080>' and '<0x80>'}}119 (void)(char32_t(0x80) < char16_t(0x80));120 (void)(char32_t(0x80) < char32_t(0x80));121 122 (void)(char32_t(0x80) == char8_t(0x7f));123 (void)(char32_t(0x80) < char16_t(0x7f));124 (void)(char32_t(0x80) < char32_t(0x7f));125 126 127 (void)(char32_t(U'🐉') <= char16_t(0xD800)); // expected-warning{{comparing values of different Unicode code unit types 'char32_t' and 'char16_t' compares unrelated code units '🐉' and '<0xD800>'}}128 (void)(char32_t(U'🐉') <= char16_t(0xD7FF));129 130 (void)(char16_t(0xD800) >= char32_t(U'🐉')); // expected-warning{{comparing values of different Unicode code unit types 'char16_t' and 'char32_t' compares unrelated code units '<0xD800>' and '🐉'}}131 (void)(char16_t(0xD7FF) >= char32_t(U'🐉'));132}133 134void check_arithmetic(char8_t u8, char16_t u16, char32_t u32) {135 136 (void)(u8 + u8);137 (void)(u16 += u16);138 (void)(u32 & u32);139 (void)(1 ? u16 : u16);140 141 (void)(u8 + u16); // expected-warning {{arithmetic between different Unicode character types 'char8_t' and 'char16_t'}}142 (void)(u8 += u16); // expected-warning {{compound assignment of different Unicode character types 'char8_t' and 'char16_t'}}143 (void)(u8 & u16); // expected-warning {{bitwise operation between different Unicode character types 'char8_t' and 'char16_t'}}144 (void)(1 ? u8 : u16); // expected-warning {{conditional expression between different Unicode character types 'char8_t' and 'char16_t'}}145 146 147 (void)(u16 * u32); // expected-warning {{arithmetic between different Unicode character types 'char16_t' and 'char32_t'}}148 (void)(u16 -= u32); // expected-warning {{compound assignment of different Unicode character types 'char16_t' and 'char32_t'}}149 (void)(u16 | u32); // expected-warning {{bitwise operation between different Unicode character types 'char16_t' and 'char32_t'}}150 (void)(1 ? u32 : u16); // expected-warning {{conditional expression between different Unicode character types 'char32_t' and 'char16_t'}}151}152