forked from OSchip/llvm-project
[C++2b] Support size_t literals
This adds support for C++2b's z/uz suffixes for size_t literals (P0330).
This commit is contained in:
parent
9f4022ffeb
commit
dc7ebd2cb0
|
@ -187,6 +187,17 @@ def ext_cxx11_longlong : Extension<
|
|||
def warn_cxx98_compat_longlong : Warning<
|
||||
"'long long' is incompatible with C++98">,
|
||||
InGroup<CXX98CompatPedantic>, DefaultIgnore;
|
||||
def ext_cxx2b_size_t_suffix : ExtWarn<
|
||||
"'size_t' suffix for literals is a C++2b extension">,
|
||||
InGroup<CXX2b>;
|
||||
def warn_cxx20_compat_size_t_suffix : Warning<
|
||||
"'size_t' suffix for literals is incompatible with C++ standards before "
|
||||
"C++2b">, InGroup<CXXPre2bCompat>, DefaultIgnore;
|
||||
def err_cxx2b_size_t_suffix: Error<
|
||||
"'size_t' suffix for literals is a C++2b feature">;
|
||||
def err_size_t_literal_too_large: Error<
|
||||
"%select{signed |}0'size_t' literal is out of range of possible "
|
||||
"%select{signed |}0'size_t' values">;
|
||||
def err_integer_literal_too_large : Error<
|
||||
"integer literal is too large to be represented in any %select{signed |}0"
|
||||
"integer type">;
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
bool isUnsigned : 1;
|
||||
bool isLong : 1; // This is *not* set for long long.
|
||||
bool isLongLong : 1;
|
||||
bool isSizeT : 1; // 1z, 1uz (C++2b)
|
||||
bool isHalf : 1; // 1.0h
|
||||
bool isFloat : 1; // 1.0f
|
||||
bool isImaginary : 1; // 1.0i
|
||||
|
|
|
@ -589,6 +589,9 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
|
|||
//Builder.defineMacro("__cpp_modules", "201907L");
|
||||
//Builder.defineMacro("__cpp_using_enum", "201907L");
|
||||
}
|
||||
// C++2b features.
|
||||
if (LangOpts.CPlusPlus2b)
|
||||
Builder.defineMacro("__cpp_size_t_suffix", "202011L");
|
||||
if (LangOpts.Char8)
|
||||
Builder.defineMacro("__cpp_char8_t", "201811L");
|
||||
Builder.defineMacro("__cpp_impl_destroying_delete", "201806L");
|
||||
|
|
|
@ -546,6 +546,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
|
|||
isLong = false;
|
||||
isUnsigned = false;
|
||||
isLongLong = false;
|
||||
isSizeT = false;
|
||||
isHalf = false;
|
||||
isFloat = false;
|
||||
isImaginary = false;
|
||||
|
@ -589,6 +590,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
|
|||
// integer constant.
|
||||
bool isFixedPointConstant = isFixedPointLiteral();
|
||||
bool isFPConstant = isFloatingLiteral();
|
||||
bool HasSize = false;
|
||||
|
||||
// Loop over all of the characters of the suffix. If we see something bad,
|
||||
// we break out of the loop.
|
||||
|
@ -616,14 +618,17 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
|
|||
if (!(LangOpts.Half || LangOpts.FixedPoint))
|
||||
break;
|
||||
if (isIntegerLiteral()) break; // Error for integer constant.
|
||||
if (isHalf || isFloat || isLong) break; // HH, FH, LH invalid.
|
||||
if (HasSize)
|
||||
break;
|
||||
HasSize = true;
|
||||
isHalf = true;
|
||||
continue; // Success.
|
||||
case 'f': // FP Suffix for "float"
|
||||
case 'F':
|
||||
if (!isFPConstant) break; // Error for integer constant.
|
||||
if (isHalf || isFloat || isLong || isFloat128)
|
||||
break; // HF, FF, LF, QF invalid.
|
||||
if (HasSize)
|
||||
break;
|
||||
HasSize = true;
|
||||
|
||||
// CUDA host and device may have different _Float16 support, therefore
|
||||
// allows f16 literals to avoid false alarm.
|
||||
|
@ -640,8 +645,9 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
|
|||
case 'q': // FP Suffix for "__float128"
|
||||
case 'Q':
|
||||
if (!isFPConstant) break; // Error for integer constant.
|
||||
if (isHalf || isFloat || isLong || isFloat128)
|
||||
break; // HQ, FQ, LQ, QQ invalid.
|
||||
if (HasSize)
|
||||
break;
|
||||
HasSize = true;
|
||||
isFloat128 = true;
|
||||
continue; // Success.
|
||||
case 'u':
|
||||
|
@ -652,8 +658,9 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
|
|||
continue; // Success.
|
||||
case 'l':
|
||||
case 'L':
|
||||
if (isLong || isLongLong) break; // Cannot be repeated.
|
||||
if (isHalf || isFloat || isFloat128) break; // LH, LF, LQ invalid.
|
||||
if (HasSize)
|
||||
break;
|
||||
HasSize = true;
|
||||
|
||||
// Check for long long. The L's need to be adjacent and the same case.
|
||||
if (s[1] == s[0]) {
|
||||
|
@ -665,42 +672,54 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
|
|||
isLong = true;
|
||||
}
|
||||
continue; // Success.
|
||||
case 'z':
|
||||
case 'Z':
|
||||
if (isFPConstant)
|
||||
break; // Invalid for floats.
|
||||
if (HasSize)
|
||||
break;
|
||||
HasSize = true;
|
||||
isSizeT = true;
|
||||
continue;
|
||||
case 'i':
|
||||
case 'I':
|
||||
if (LangOpts.MicrosoftExt) {
|
||||
if (isLong || isLongLong || MicrosoftInteger)
|
||||
if (LangOpts.MicrosoftExt && !isFPConstant) {
|
||||
// Allow i8, i16, i32, and i64. First, look ahead and check if
|
||||
// suffixes are Microsoft integers and not the imaginary unit.
|
||||
uint8_t Bits = 0;
|
||||
size_t ToSkip = 0;
|
||||
switch (s[1]) {
|
||||
case '8': // i8 suffix
|
||||
Bits = 8;
|
||||
ToSkip = 2;
|
||||
break;
|
||||
|
||||
if (!isFPConstant) {
|
||||
// Allow i8, i16, i32, and i64.
|
||||
switch (s[1]) {
|
||||
case '8':
|
||||
s += 2; // i8 suffix
|
||||
MicrosoftInteger = 8;
|
||||
break;
|
||||
case '1':
|
||||
if (s[2] == '6') {
|
||||
s += 3; // i16 suffix
|
||||
MicrosoftInteger = 16;
|
||||
}
|
||||
break;
|
||||
case '3':
|
||||
if (s[2] == '2') {
|
||||
s += 3; // i32 suffix
|
||||
MicrosoftInteger = 32;
|
||||
}
|
||||
break;
|
||||
case '6':
|
||||
if (s[2] == '4') {
|
||||
s += 3; // i64 suffix
|
||||
MicrosoftInteger = 64;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case '1':
|
||||
if (s[2] == '6') { // i16 suffix
|
||||
Bits = 16;
|
||||
ToSkip = 3;
|
||||
}
|
||||
break;
|
||||
case '3':
|
||||
if (s[2] == '2') { // i32 suffix
|
||||
Bits = 32;
|
||||
ToSkip = 3;
|
||||
}
|
||||
break;
|
||||
case '6':
|
||||
if (s[2] == '4') { // i64 suffix
|
||||
Bits = 64;
|
||||
ToSkip = 3;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (MicrosoftInteger) {
|
||||
if (Bits) {
|
||||
if (HasSize)
|
||||
break;
|
||||
HasSize = true;
|
||||
MicrosoftInteger = Bits;
|
||||
s += ToSkip;
|
||||
assert(s <= ThisTokEnd && "didn't maximally munch?");
|
||||
break;
|
||||
}
|
||||
|
@ -727,6 +746,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
|
|||
isLong = false;
|
||||
isUnsigned = false;
|
||||
isLongLong = false;
|
||||
isSizeT = false;
|
||||
isFloat = false;
|
||||
isFloat16 = false;
|
||||
isHalf = false;
|
||||
|
|
|
@ -321,6 +321,14 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
|
|||
PP.Diag(PeekTok, diag::ext_c99_longlong);
|
||||
}
|
||||
|
||||
// 'z/uz' literals are a C++2b feature.
|
||||
if (Literal.isSizeT)
|
||||
PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus
|
||||
? PP.getLangOpts().CPlusPlus2b
|
||||
? diag::warn_cxx20_compat_size_t_suffix
|
||||
: diag::ext_cxx2b_size_t_suffix
|
||||
: diag::err_cxx2b_size_t_suffix);
|
||||
|
||||
// Parse the integer literal into Result.
|
||||
if (Literal.GetIntegerValue(Result.Val)) {
|
||||
// Overflow parsing integer literal.
|
||||
|
|
|
@ -3867,6 +3867,14 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
|
|||
Diag(Tok.getLocation(), diag::ext_c99_longlong);
|
||||
}
|
||||
|
||||
// 'z/uz' literals are a C++2b feature.
|
||||
if (Literal.isSizeT)
|
||||
Diag(Tok.getLocation(), getLangOpts().CPlusPlus
|
||||
? getLangOpts().CPlusPlus2b
|
||||
? diag::warn_cxx20_compat_size_t_suffix
|
||||
: diag::ext_cxx2b_size_t_suffix
|
||||
: diag::err_cxx2b_size_t_suffix);
|
||||
|
||||
// Get the value in the widest-possible width.
|
||||
unsigned MaxWidth = Context.getTargetInfo().getIntMaxTWidth();
|
||||
llvm::APInt ResultVal(MaxWidth, 0);
|
||||
|
@ -3901,7 +3909,26 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
|
|||
}
|
||||
}
|
||||
|
||||
if (Ty.isNull() && !Literal.isLong && !Literal.isLongLong) {
|
||||
// Check C++2b size_t literals.
|
||||
if (Literal.isSizeT) {
|
||||
assert(!Literal.MicrosoftInteger &&
|
||||
"size_t literals can't be Microsoft literals");
|
||||
unsigned SizeTSize = Context.getTargetInfo().getTypeWidth(
|
||||
Context.getTargetInfo().getSizeType());
|
||||
|
||||
// Does it fit in size_t?
|
||||
if (ResultVal.isIntN(SizeTSize)) {
|
||||
// Does it fit in ssize_t?
|
||||
if (!Literal.isUnsigned && ResultVal[SizeTSize - 1] == 0)
|
||||
Ty = Context.getSignedSizeType();
|
||||
else if (AllowUnsigned)
|
||||
Ty = Context.getSizeType();
|
||||
Width = SizeTSize;
|
||||
}
|
||||
}
|
||||
|
||||
if (Ty.isNull() && !Literal.isLong && !Literal.isLongLong &&
|
||||
!Literal.isSizeT) {
|
||||
// Are int/unsigned possibilities?
|
||||
unsigned IntSize = Context.getTargetInfo().getIntWidth();
|
||||
|
||||
|
@ -3917,7 +3944,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
|
|||
}
|
||||
|
||||
// Are long/unsigned long possibilities?
|
||||
if (Ty.isNull() && !Literal.isLongLong) {
|
||||
if (Ty.isNull() && !Literal.isLongLong && !Literal.isSizeT) {
|
||||
unsigned LongSize = Context.getTargetInfo().getLongWidth();
|
||||
|
||||
// Does it fit in a unsigned long?
|
||||
|
@ -3948,7 +3975,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
|
|||
}
|
||||
|
||||
// Check long long if needed.
|
||||
if (Ty.isNull()) {
|
||||
if (Ty.isNull() && !Literal.isSizeT) {
|
||||
unsigned LongLongSize = Context.getTargetInfo().getLongLongWidth();
|
||||
|
||||
// Does it fit in a unsigned long long?
|
||||
|
@ -3965,10 +3992,16 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
|
|||
}
|
||||
}
|
||||
|
||||
// If we still couldn't decide a type, we probably have something that
|
||||
// does not fit in a signed long long, but has no U suffix.
|
||||
// If we still couldn't decide a type, we either have 'size_t' literal
|
||||
// that is out of range, or a decimal literal that does not fit in a
|
||||
// signed long long and has no U suffix.
|
||||
if (Ty.isNull()) {
|
||||
Diag(Tok.getLocation(), diag::ext_integer_literal_too_large_for_signed);
|
||||
if (Literal.isSizeT)
|
||||
Diag(Tok.getLocation(), diag::err_size_t_literal_too_large)
|
||||
<< Literal.isUnsigned;
|
||||
else
|
||||
Diag(Tok.getLocation(),
|
||||
diag::ext_integer_literal_too_large_for_signed);
|
||||
Ty = Context.UnsignedLongLongTy;
|
||||
Width = Context.getTargetInfo().getLongLongWidth();
|
||||
}
|
||||
|
|
|
@ -29,6 +29,12 @@
|
|||
#define check(macro, cxx98, cxx11, cxx14, cxx17, cxx20, cxx23) (cxx23 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx23)
|
||||
#endif
|
||||
|
||||
// --- C++2b features ---
|
||||
|
||||
#if check(size_t_suffix, 0, 0, 0, 0, 0, 202011)
|
||||
#error "wrong value for __cpp_size_t_suffix"
|
||||
#endif
|
||||
|
||||
// --- C++20 features ---
|
||||
|
||||
#if check(aggregate_paren_init, 0, 0, 0, 0, 0, 0)
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
// RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify %s
|
||||
|
||||
#if 1z != 1
|
||||
#error "z suffix must be recognized by preprocessor"
|
||||
#endif
|
||||
#if 1uz != 1
|
||||
#error "uz suffix must be recognized by preprocessor"
|
||||
#endif
|
||||
#if !(-1z < 0)
|
||||
#error "z suffix must be interpreted as signed"
|
||||
#endif
|
||||
#if !(-1uz > 0)
|
||||
#error "uz suffix must be interpreted as unsigned"
|
||||
#endif
|
||||
|
||||
void ValidSuffix() {
|
||||
// Decimal literals.
|
||||
{
|
||||
auto a1 = 1z;
|
||||
auto a2 = 1Z;
|
||||
|
||||
auto a3 = 1uz;
|
||||
auto a4 = 1uZ;
|
||||
auto a5 = 1Uz;
|
||||
auto a6 = 1UZ;
|
||||
|
||||
auto a7 = 1zu;
|
||||
auto a8 = 1Zu;
|
||||
auto a9 = 1zU;
|
||||
auto a10 = 1ZU;
|
||||
|
||||
auto a11 = 1'2z;
|
||||
auto a12 = 1'2Z;
|
||||
}
|
||||
// Hexadecimal literals.
|
||||
{
|
||||
auto a1 = 0x1z;
|
||||
auto a2 = 0x1Z;
|
||||
|
||||
auto a3 = 0x1uz;
|
||||
auto a4 = 0x1uZ;
|
||||
auto a5 = 0x1Uz;
|
||||
auto a6 = 0x1UZ;
|
||||
|
||||
auto a7 = 0x1zu;
|
||||
auto a8 = 0x1Zu;
|
||||
auto a9 = 0x1zU;
|
||||
auto a10 = 0x1ZU;
|
||||
|
||||
auto a11 = 0x1'2z;
|
||||
auto a12 = 0x1'2Z;
|
||||
}
|
||||
// Binary literals.
|
||||
{
|
||||
auto a1 = 0b1z;
|
||||
auto a2 = 0b1Z;
|
||||
|
||||
auto a3 = 0b1uz;
|
||||
auto a4 = 0b1uZ;
|
||||
auto a5 = 0b1Uz;
|
||||
auto a6 = 0b1UZ;
|
||||
|
||||
auto a7 = 0b1zu;
|
||||
auto a8 = 0b1Zu;
|
||||
auto a9 = 0b1zU;
|
||||
auto a10 = 0b1ZU;
|
||||
|
||||
auto a11 = 0b1'1z;
|
||||
auto a12 = 0b1'1Z;
|
||||
}
|
||||
// Octal literals.
|
||||
{
|
||||
auto a1 = 01z;
|
||||
auto a2 = 01Z;
|
||||
|
||||
auto a3 = 01uz;
|
||||
auto a4 = 01uZ;
|
||||
auto a5 = 01Uz;
|
||||
auto a6 = 01UZ;
|
||||
|
||||
auto a7 = 01zu;
|
||||
auto a8 = 01Zu;
|
||||
auto a9 = 01zU;
|
||||
auto a10 = 01ZU;
|
||||
|
||||
auto a11 = 0'1z;
|
||||
auto a12 = 0'1Z;
|
||||
}
|
||||
}
|
||||
|
||||
void InvalidSuffix() {
|
||||
// Long.
|
||||
{
|
||||
auto a1 = 1lz; // expected-error {{invalid suffix}}
|
||||
auto a2 = 1lZ; // expected-error {{invalid suffix}}
|
||||
auto a3 = 1Lz; // expected-error {{invalid suffix}}
|
||||
auto a4 = 1LZ; // expected-error {{invalid suffix}}
|
||||
|
||||
auto a5 = 1zl; // expected-error {{invalid suffix}}
|
||||
auto a6 = 1Zl; // expected-error {{invalid suffix}}
|
||||
auto a7 = 1zL; // expected-error {{invalid suffix}}
|
||||
auto a8 = 1ZL; // expected-error {{invalid suffix}}
|
||||
|
||||
auto a9 = 1ulz; // expected-error {{invalid suffix}}
|
||||
auto a10 = 1ulZ; // expected-error {{invalid suffix}}
|
||||
auto a11 = 1uLz; // expected-error {{invalid suffix}}
|
||||
auto a12 = 1uLZ; // expected-error {{invalid suffix}}
|
||||
|
||||
auto a13 = 1uzl; // expected-error {{invalid suffix}}
|
||||
auto a14 = 1uZl; // expected-error {{invalid suffix}}
|
||||
auto a15 = 1uzL; // expected-error {{invalid suffix}}
|
||||
auto a16 = 1uZL; // expected-error {{invalid suffix}}
|
||||
}
|
||||
// Long long.
|
||||
{
|
||||
auto a1 = 1llz; // expected-error {{invalid suffix}}
|
||||
auto a2 = 1llZ; // expected-error {{invalid suffix}}
|
||||
auto a3 = 1LLz; // expected-error {{invalid suffix}}
|
||||
auto a4 = 1LLZ; // expected-error {{invalid suffix}}
|
||||
|
||||
auto a5 = 1zll; // expected-error {{invalid suffix}}
|
||||
auto a6 = 1Zll; // expected-error {{invalid suffix}}
|
||||
auto a7 = 1zLL; // expected-error {{invalid suffix}}
|
||||
auto a8 = 1ZLL; // expected-error {{invalid suffix}}
|
||||
|
||||
auto a9 = 1ullz; // expected-error {{invalid suffix}}
|
||||
auto a10 = 1ullZ; // expected-error {{invalid suffix}}
|
||||
auto a11 = 1uLLz; // expected-error {{invalid suffix}}
|
||||
auto a12 = 1uLLZ; // expected-error {{invalid suffix}}
|
||||
|
||||
auto a13 = 1uzll; // expected-error {{invalid suffix}}
|
||||
auto a14 = 1uZll; // expected-error {{invalid suffix}}
|
||||
auto a15 = 1uzLL; // expected-error {{invalid suffix}}
|
||||
auto a16 = 1uZLL; // expected-error {{invalid suffix}}
|
||||
}
|
||||
// Floating point.
|
||||
{
|
||||
auto a1 = 0.1z; // expected-error {{invalid suffix}}
|
||||
auto a2 = 0.1Z; // expected-error {{invalid suffix}}
|
||||
auto a3 = 0.1uz; // expected-error {{invalid suffix}}
|
||||
auto a4 = 0.1uZ; // expected-error {{invalid suffix}}
|
||||
auto a5 = 0.1Uz; // expected-error {{invalid suffix}}
|
||||
auto a6 = 0.1UZ; // expected-error {{invalid suffix}}
|
||||
auto a7 = 0.1zu; // expected-error {{invalid suffix}}
|
||||
auto a8 = 0.1Zu; // expected-error {{invalid suffix}}
|
||||
auto a9 = 0.1zU; // expected-error {{invalid suffix}}
|
||||
auto a10 = 0.1ZU; // expected-error {{invalid suffix}}
|
||||
|
||||
auto a11 = 0.1fz; // expected-error {{invalid suffix}}
|
||||
auto a12 = 0.1fZ; // expected-error {{invalid suffix}}
|
||||
auto a13 = 0.1fuz; // expected-error {{invalid suffix}}
|
||||
auto a14 = 0.1fuZ; // expected-error {{invalid suffix}}
|
||||
auto a15 = 0.1fUz; // expected-error {{invalid suffix}}
|
||||
auto a16 = 0.1fUZ; // expected-error {{invalid suffix}}
|
||||
auto a17 = 0.1fzu; // expected-error {{invalid suffix}}
|
||||
auto a18 = 0.1fZu; // expected-error {{invalid suffix}}
|
||||
auto a19 = 0.1fzU; // expected-error {{invalid suffix}}
|
||||
auto a110 = 0.1fZU; // expected-error {{invalid suffix}}
|
||||
}
|
||||
// Repetitive suffix.
|
||||
{
|
||||
auto a1 = 1zz; // expected-error {{invalid suffix}}
|
||||
auto a2 = 1zZ; // expected-error {{invalid suffix}}
|
||||
auto a3 = 1Zz; // expected-error {{invalid suffix}}
|
||||
auto a4 = 1ZZ; // expected-error {{invalid suffix}}
|
||||
}
|
||||
}
|
|
@ -34,7 +34,7 @@ duration a = 1ns, b = 1us, c = 1ms, d = 1s, e = 1min, f = 1h;
|
|||
string s = "foo"s;
|
||||
char error = 'x's; // expected-error {{invalid suffix}} expected-error {{expected ';'}}
|
||||
|
||||
int _1z = 1z; // expected-error {{invalid suffix}}
|
||||
int _1y = 1y; // expected-error {{invalid suffix}}
|
||||
int _1b = 1b; // expected-error {{invalid digit}}
|
||||
|
||||
complex<float> cf1 = 1if, cf2 = 2.if, cf3 = 0x3if;
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
// RUN: %clang_cc1 -std=c++2b -triple x86_64-linux -Wpre-c++2b-compat -fsyntax-only -verify=cxx2b %s
|
||||
// RUN: %clang_cc1 -std=c++20 -triple x86_64-linux -fsyntax-only -verify=cxx20 %s
|
||||
// RUN: %clang_cc1 -std=c++2b -triple i686-linux -fsyntax-only -verify=cxx2b-32 %s
|
||||
// RUN: %clang_cc1 -x c -std=c11 -fsyntax-only -verify=c11 %s
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
// Assume ptrdiff_t is the signed integer type corresponding to size_t.
|
||||
typedef __PTRDIFF_TYPE__ ssize_t;
|
||||
|
||||
template <typename, typename>
|
||||
struct is_same { static constexpr bool value = false; };
|
||||
|
||||
template <typename T>
|
||||
struct is_same<T, T> { static constexpr bool value = true; };
|
||||
|
||||
void SSizeT() {
|
||||
auto a1 = 1z;
|
||||
// cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
|
||||
// cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}}
|
||||
static_assert(is_same<decltype(a1), ssize_t>::value);
|
||||
|
||||
auto a2 = 1Z;
|
||||
// cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
|
||||
// cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}}
|
||||
static_assert(is_same<decltype(a2), ssize_t>::value);
|
||||
}
|
||||
|
||||
void SizeT() {
|
||||
auto a1 = 1uz;
|
||||
// cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
|
||||
// cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}}
|
||||
static_assert(is_same<decltype(a1), size_t>::value);
|
||||
|
||||
auto a2 = 1uZ;
|
||||
// cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
|
||||
// cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}}
|
||||
static_assert(is_same<decltype(a2), size_t>::value);
|
||||
|
||||
auto a3 = 1Uz;
|
||||
// cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
|
||||
// cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}}
|
||||
static_assert(is_same<decltype(a3), size_t>::value);
|
||||
|
||||
auto a4 = 1UZ;
|
||||
// cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
|
||||
// cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}}
|
||||
static_assert(is_same<decltype(a4), size_t>::value);
|
||||
|
||||
auto a5 = 1zu;
|
||||
// cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
|
||||
// cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}}
|
||||
static_assert(is_same<decltype(a5), size_t>::value);
|
||||
|
||||
auto a6 = 1Zu;
|
||||
// cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
|
||||
// cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}}
|
||||
static_assert(is_same<decltype(a6), size_t>::value);
|
||||
|
||||
auto a7 = 1zU;
|
||||
// cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
|
||||
// cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}}
|
||||
static_assert(is_same<decltype(a7), size_t>::value);
|
||||
|
||||
auto a8 = 1ZU;
|
||||
// cxx2b-warning@-1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
|
||||
// cxx20-warning@-2 {{'size_t' suffix for literals is a C++2b extension}}
|
||||
static_assert(is_same<decltype(a8), size_t>::value);
|
||||
}
|
||||
|
||||
void oor() {
|
||||
#if __i386__
|
||||
(void)3'000'000'000z; // cxx2b-32-error {{signed 'size_t' literal is out of range of possible signed 'size_t' values}}
|
||||
(void)3'000'000'000uz;
|
||||
(void)5'000'000'000uz; // cxx2b-32-error {{'size_t' literal is out of range of possible 'size_t' values}}
|
||||
|
||||
(void)0x80000000z;
|
||||
(void)0x80000000uz;
|
||||
(void)0x180000000uz; //cxx2b-32-error {{'size_t' literal is out of range of possible 'size_t' values}}
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void f() {
|
||||
(void)1z; // c11-error {{'size_t' suffix for literals is a C++2b feature}}
|
||||
(void)1Z; // c11-error {{'size_t' suffix for literals is a C++2b feature}}
|
||||
(void)1uz; // c11-error {{'size_t' suffix for literals is a C++2b feature}}
|
||||
(void)1uZ; // c11-error {{'size_t' suffix for literals is a C++2b feature}}
|
||||
(void)1Uz; // c11-error {{'size_t' suffix for literals is a C++2b feature}}
|
||||
(void)1UZ; // c11-error {{'size_t' suffix for literals is a C++2b feature}}
|
||||
(void)1zu; // c11-error {{'size_t' suffix for literals is a C++2b feature}}
|
||||
(void)1Zu; // c11-error {{'size_t' suffix for literals is a C++2b feature}}
|
||||
(void)1zU; // c11-error {{'size_t' suffix for literals is a C++2b feature}}
|
||||
(void)1ZU; // c11-error {{'size_t' suffix for literals is a C++2b feature}}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1270,7 +1270,7 @@ C++20, informally referred to as C++2b.
|
|||
<tr>
|
||||
<td>Literal suffix <tt>uz</tt>, <tt>z</tt> for <tt>size_t</tt>, <tt>ssize_t</tt></td>
|
||||
<td><a href="https://wg21.link/p0330r8">P0330R8</a></td>
|
||||
<td class="none" align="center">No</td>
|
||||
<td class="unreleased" align="center">Clang 13</td>
|
||||
</tr>
|
||||
<!-- Spring 2021 papers -->
|
||||
<tr>
|
||||
|
|
Loading…
Reference in New Issue