[PATCH] D99456: [C++2b] Support size_t literals

Richard Smith - zygoloid via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 29 14:34:33 PDT 2021


rsmith added inline comments.


================
Comment at: clang/include/clang/Basic/DiagnosticCommonKinds.td:190
   InGroup<CXX98CompatPedantic>, DefaultIgnore;
+def ext_cxx2b_size_t_suffix : Extension<
+  "'size_t' suffix for literals is a C++2b extension">,
----------------
Should this be an `ExtWarn`? I think we should warn on this by default.


================
Comment at: clang/lib/Lex/LiteralSupport.cpp:594-595
 
   // Loop over all of the characters of the suffix.  If we see something bad,
   // we break out of the loop.
   for (; s != ThisTokEnd; ++s) {
----------------
General comment: I think the checks here have become too complex and error-prone. I suggest we add another flag, `hasSize`, that's set when we parse any size modifier (`F`, `L`, `LL`, `H`, `F128`, `I64`, and now `Z`), and when parsing any size modifier, replace the existing ad-hoc set of checks with a check for `hasSize`.


================
Comment at: clang/lib/Lex/PPExpressions.cpp:325
+    // 'z/uz' literals are a C++2b feature.
+    if (!PP.getLangOpts().CPlusPlus2b && Literal.isSizeT)
+      PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus
----------------
We should issue a compat warning when these literals are used in C++2b or later. (That is, always issue a diagnostic for a `size_t` literal: in C, it's an error, in C++20 and before, it's an extension warning, and in C++2b and later, it's a backwards-compatibility warning.) There are a bunch of examples of this elsewhere in the codebase -- look for the emission of `warn_cxx.*_compat`.


================
Comment at: clang/lib/Sema/SemaExpr.cpp:3871
+    // 'z/uz' literals are a C++2b feature.
+    if (!getLangOpts().CPlusPlus2b && Literal.isSizeT)
+      Diag(Tok.getLocation(), getLangOpts().CPlusPlus
----------------
Also need the C++20-and-before compat warning here for C++2b-onwards mode.


================
Comment at: clang/lib/Sema/SemaExpr.cpp:3928
+
       if (Ty.isNull() && !Literal.isLong && !Literal.isLongLong) {
         // Are int/unsigned possibilities?
----------------
This should exclude the `isSizeT` case in addition to `isLong` and `isLongLong`. (It probably doesn't matter, because `int` is not larger than `size_t` on any platform we support, but nonetheless we should check.)


================
Comment at: clang/lib/Sema/SemaExpr.cpp:3944
       // Are long/unsigned long possibilities?
       if (Ty.isNull() && !Literal.isLongLong) {
         unsigned LongSize = Context.getTargetInfo().getLongWidth();
----------------
Likewise here.


================
Comment at: clang/lib/Sema/SemaExpr.cpp:3975
       // Check long long if needed.
       if (Ty.isNull()) {
         unsigned LongLongSize = Context.getTargetInfo().getLongLongWidth();
----------------
Likewise here -- and this one actually does matter, because we have targets with a 32-bit `size_t` but a 64-bit `long long`.


================
Comment at: clang/test/Lexer/size_t-literal.cpp:6-8
+#if 1uz != 1
+#error "size_t suffix must be recognized by preprocessor"
+#endif
----------------
Please also check `-1z < 0` and `-1zu < 0` to ensure that the preprocessor gets the signedness correct.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D99456/new/

https://reviews.llvm.org/D99456



More information about the cfe-commits mailing list