[clang] dc7ebd2 - [C++2b] Support size_t literals
Anton Bikineev via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 31 06:39:23 PDT 2021
Author: Anton Bikineev
Date: 2021-03-31T13:36:23Z
New Revision: dc7ebd2cb0cf4a83bb6cd1bfc8853b0a30054777
URL: https://github.com/llvm/llvm-project/commit/dc7ebd2cb0cf4a83bb6cd1bfc8853b0a30054777
DIFF: https://github.com/llvm/llvm-project/commit/dc7ebd2cb0cf4a83bb6cd1bfc8853b0a30054777.diff
LOG: [C++2b] Support size_t literals
This adds support for C++2b's z/uz suffixes for size_t literals (P0330).
Added:
clang/test/Lexer/size_t-literal.cpp
clang/test/SemaCXX/size_t-literal.cpp
Modified:
clang/include/clang/Basic/DiagnosticCommonKinds.td
clang/include/clang/Lex/LiteralSupport.h
clang/lib/Frontend/InitPreprocessor.cpp
clang/lib/Lex/LiteralSupport.cpp
clang/lib/Lex/PPExpressions.cpp
clang/lib/Sema/SemaExpr.cpp
clang/test/Lexer/cxx-features.cpp
clang/test/SemaCXX/cxx1y-user-defined-literals.cpp
clang/www/cxx_status.html
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index a237d492de201..eab8206b104dc 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -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">;
diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h
index 0c4f0fe277b7c..f131f045a73ea 100644
--- a/clang/include/clang/Lex/LiteralSupport.h
+++ b/clang/include/clang/Lex/LiteralSupport.h
@@ -63,6 +63,7 @@ class NumericLiteralParser {
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
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 15f254515822b..3d69c59d166d0 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -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");
diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp
index df98516ee61d1..bfcb3c478b62d 100644
--- a/clang/lib/Lex/LiteralSupport.cpp
+++ b/clang/lib/Lex/LiteralSupport.cpp
@@ -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
diff erent _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;
diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
index 8c120c13d7d26..8537b31b9dc95 100644
--- a/clang/lib/Lex/PPExpressions.cpp
+++ b/clang/lib/Lex/PPExpressions.cpp
@@ -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.
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 6b3da7ca5a4dc..1aff2a9edf0f9 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -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();
}
diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp
index 2f46f354ee83f..22ac5567c1d86 100644
--- a/clang/test/Lexer/cxx-features.cpp
+++ b/clang/test/Lexer/cxx-features.cpp
@@ -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)
diff --git a/clang/test/Lexer/size_t-literal.cpp b/clang/test/Lexer/size_t-literal.cpp
new file mode 100644
index 0000000000000..3e3e8094b070d
--- /dev/null
+++ b/clang/test/Lexer/size_t-literal.cpp
@@ -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}}
+ }
+}
diff --git a/clang/test/SemaCXX/cxx1y-user-defined-literals.cpp b/clang/test/SemaCXX/cxx1y-user-defined-literals.cpp
index fa4ff03fad7fd..d79924c8e2ed1 100644
--- a/clang/test/SemaCXX/cxx1y-user-defined-literals.cpp
+++ b/clang/test/SemaCXX/cxx1y-user-defined-literals.cpp
@@ -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;
diff --git a/clang/test/SemaCXX/size_t-literal.cpp b/clang/test/SemaCXX/size_t-literal.cpp
new file mode 100644
index 0000000000000..180f95979b39e
--- /dev/null
+++ b/clang/test/SemaCXX/size_t-literal.cpp
@@ -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 ptr
diff _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 at -1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
+ // cxx20-warning at -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 at -1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
+ // cxx20-warning at -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 at -1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
+ // cxx20-warning at -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 at -1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
+ // cxx20-warning at -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 at -1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
+ // cxx20-warning at -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 at -1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
+ // cxx20-warning at -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 at -1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
+ // cxx20-warning at -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 at -1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
+ // cxx20-warning at -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 at -1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
+ // cxx20-warning at -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 at -1 {{'size_t' suffix for literals is incompatible with C++ standards before C++2b}}
+ // cxx20-warning at -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
diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index de8a4908f42e0..0660816b83c18 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -1270,7 +1270,7 @@ <h2 id="cxx23">C++2b implementation status</h2>
<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>
More information about the cfe-commits
mailing list