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@-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 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> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits