[[C++ PATCH]] Implement C++2a P0330R2 - Literal Suffixes for ptrdiff_t and size_t

Ed Smith-Rowland 3dw4rd@verizon.net
Tue Feb 2 06:19:24 GMT 2021


On 2/2/21 12:12 AM, Jason Merrill wrote:
> On 2/1/21 9:15 PM, Ed Smith-Rowland wrote:
>> On 2/1/21 2:23 PM, Jakub Jelinek wrote:
>>> On Mon, Feb 01, 2021 at 01:46:13PM -0500, Ed Smith-Rowland wrote:
>>>> @@ -0,0 +1,8 @@
>>>> +// { dg-do compile { target c++23 } }
>>>> +
>>>> +#include <cstddef>
>>>> +#include <type_traits>
>>>> +
>>>> +static_assert(std::is_same_v<decltype(123zu), std::size_t>);
>>>> +static_assert(std::is_same_v<decltype(456z), std::ptrdiff_t>);
>>> Shouldn't this be std::make_signed<std::size_t>::type instead of 
>>> std::ptrdiff_t
>> Yes it should. The paper goes on about ptrdiff_t but at the very end 
>> they punt on that in favor of what you have.
>>>
>>>> +std::ptrdiff_t pd1 = 1234z; // { dg-warning "use of C\+\+23 
>>>> ptrdiff_t integer constant" "" { target c++20_down } }
>>>> +std::ptrdiff_t PD1 = 5678Z; // { dg-warning "use of C\+\+23 
>>>> ptrdiff_t integer constant" "" { target c++20_down } }
>>> Ditto here.
>> Agree.
>>>
>>>> +      const char *message = (result & CPP_N_UNSIGNED) == 
>>>> CPP_N_UNSIGNED
>>>> +                ? N_("use of C++23 size_t integer constant")
>>>> +                : N_("use of C++23 ptrdiff_t integer constant");
>>> And here too (perhaps %<make_signed<size_t>::type%> )?
>>> And maybe %<size_t%> too.
>> Agree.
>>>
>>>> --- a/libcpp/include/cpplib.h
>>>> +++ b/libcpp/include/cpplib.h
>>>> @@ -500,6 +500,9 @@ struct cpp_options
>>>>     /* Nonzero means tokenize C++20 module directives.  */
>>>>     unsigned char module_directives;
>>>> +  /* Nonzero for C++23 ptrdiff_t and size_t literals.  */
>>> And drop "ptrdiff_t and " here?
>>>
>>>> +#define CPP_N_SIZE_T    0x2000000 /* C++23 size_t or ptrdiff_t 
>>>> literal  */
>>> And " or ptrdiff_t" here?
>>>
>>> While ptrdiff_t will usually be the same type, seems there is e.g.:
>>> config/darwin.h:#define SIZE_TYPE "long unsigned int"
>>> config/darwin.h:#define PTRDIFF_TYPE "int"
>>> config/i386/djgpp.h:#define SIZE_TYPE "long unsigned int"
>>> config/i386/djgpp.h:#define PTRDIFF_TYPE "int"
>>> config/m32c/m32c.h:#define PTRDIFF_TYPE (TARGET_A16 ? "int" : "long 
>>> int")
>>> config/m32c/m32c.h:#define SIZE_TYPE "unsigned int"
>>> config/rs6000/rs6000.h:#define PTRDIFF_TYPE "int"
>>> config/rs6000/rs6000.h:#define SIZE_TYPE "long unsigned int"
>>> config/s390/linux.h:#define SIZE_TYPE "long unsigned int"
>>> config/s390/linux.h:#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" 
>>> : "int")
>>> config/visium/visium.h:#define SIZE_TYPE "unsigned int"
>>> config/visium/visium.h:#define PTRDIFF_TYPE "long int"
>>> config/vms/vms.h:#define SIZE_TYPE  "unsigned int"
>>> config/vms/vms.h:#define PTRDIFF_TYPE (flag_vms_pointer_size == 
>>> VMS_POINTER_SIZE_NONE ? \
>>> config/vms/vms.h-                      "int" : "long long int")
>>> so quite a few differences.
>>>
>>>     Jakub
>>
>> Here is my last patch with all the concerns addressed.
>>
>> I am not smart enough to get the dg-warning regex in 
>> Wsize_t-literals.C to work. If someone could carry this over the 
>> finish line that would be great. Or give me pointers. I can't any more.
>
> Your regex will work fine if you wrap it in {} instead of "", e.g.
>
> { dg-warning {use of C\+\+23 .size_t. integer constant} }
>
> Jason
>
Thank you Jason,

So here is the latest in testing.

Ed


-------------- next part --------------
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index dca6815a876..48dec21d4b4 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -1025,6 +1025,11 @@ c_cpp_builtins (cpp_reader *pfile)
 	  cpp_define (pfile, "__cpp_aggregate_paren_init=201902L");
 	  cpp_define (pfile, "__cpp_using_enum=201907L");
 	}
+      if (cxx_dialect > cxx20)
+	{
+	  /* Set feature test macros for C++23.  */
+	  cpp_define (pfile, "__cpp_size_t_suffix=202006L");
+	}
       if (flag_concepts)
         {
 	  if (cxx_dialect >= cxx20)
diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
index fe40a0f728b..6374b72ed2d 100644
--- a/gcc/c-family/c-lex.c
+++ b/gcc/c-family/c-lex.c
@@ -834,6 +834,14 @@ interpret_integer (const cpp_token *token, unsigned int flags,
     type = ((flags & CPP_N_UNSIGNED)
 	    ? widest_unsigned_literal_type_node
 	    : widest_integer_literal_type_node);
+  else if (flags & CPP_N_SIZE_T)
+    {
+      /* itk refers to fundamental types not aliased size types.  */
+      if (flags & CPP_N_UNSIGNED)
+	type = size_type_node;
+      else
+	type = signed_size_type_node;
+    }
   else
     {
       type = integer_types[itk];
diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-shadow-neg.C b/gcc/testsuite/g++.dg/cpp0x/udlit-shadow-neg.C
index fdddd8d84ed..a30ec0f4f7e 100644
--- a/gcc/testsuite/g++.dg/cpp0x/udlit-shadow-neg.C
+++ b/gcc/testsuite/g++.dg/cpp0x/udlit-shadow-neg.C
@@ -17,6 +17,30 @@ unsigned long long int
 operator"" ull(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
 { return k; }
 
+unsigned long long int
+operator"" z(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
+{ return k; }
+
+unsigned long long int
+operator"" uz(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
+{ return k; }
+
+unsigned long long int
+operator"" zu(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
+{ return k; }
+
+unsigned long long int
+operator"" Z(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
+{ return k; }
+
+unsigned long long int
+operator"" UZ(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
+{ return k; }
+
+unsigned long long int
+operator"" ZU(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
+{ return k; }
+
 //  Namespaces are no hiding place.
 namespace Long
 {
@@ -37,13 +61,50 @@ unsigned long long int
 operator"" ull(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
 { return k; }
 
+unsigned long long int
+operator"" z(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
+{ return k; }
+
+unsigned long long int
+operator"" uz(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
+{ return k; }
+
+unsigned long long int
+operator"" zu(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
+{ return k; }
+
+unsigned long long int
+operator"" Z(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
+{ return k; }
+
+unsigned long long int
+operator"" UZ(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
+{ return k; }
+
+unsigned long long int
+operator"" ZU(unsigned long long int k)  // { dg-warning "integer suffix|shadowed by implementation" }
+{ return k; }
+
 }
 
 // { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 5 }
 // { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 9 }
 // { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 13 }
 // { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 17 }
+// { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 21 }
 // { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 25 }
 // { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 29 }
 // { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 33 }
 // { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 37 }
+// { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 41 }
+
+// { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 49 }
+// { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 53 }
+// { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 57 }
+// { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 61 }
+// { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 65 }
+// { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 69 }
+// { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 73 }
+// { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 77 }
+// { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 81 }
+// { dg-warning "literal operator suffixes not preceded by|are reserved for future standardization" "reserved" { target *-*-* } 85 }
diff --git a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
new file mode 100644
index 00000000000..94e08a4896c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
@@ -0,0 +1,549 @@
+// { dg-options "-std=c++2b -I${srcdir}/g++.dg/cpp1y -I${srcdir}/g++.dg/cpp1y/testinc" }
+
+//  C++98 features:
+
+#ifndef __cpp_rtti
+#  error "__cpp_rtti"
+#elif  __cpp_rtti != 199711
+#  error "__cpp_rtti != 199711"
+#endif
+
+#ifndef __cpp_exceptions
+#  error "__cpp_exceptions"
+#elif  __cpp_exceptions != 199711
+#  error "__cpp_exceptions != 199711"
+#endif
+
+//  C++11 features:
+
+#ifndef __cpp_raw_strings
+#  error "__cpp_raw_strings"
+#elif __cpp_raw_strings != 200710
+#  error "__cpp_raw_strings != 200710"
+#endif
+
+#ifndef __cpp_unicode_literals
+#  error "__cpp_unicode_literals"
+#elif __cpp_unicode_literals != 200710
+#  error "__cpp_unicode_literals != 200710"
+#endif
+
+#ifndef __cpp_user_defined_literals
+#  error "__cpp_user_defined_literals"
+#elif __cpp_user_defined_literals != 200809
+#  error "__cpp_user_defined_literals != 200809"
+#endif
+
+#ifndef __cpp_lambdas
+#  error "__cpp_lambdas"
+#elif __cpp_lambdas != 200907
+#  error "__cpp_lambdas != 200907"
+#endif
+
+#ifndef __cpp_range_based_for
+#  error "__cpp_range_based_for"
+#elif __cpp_range_based_for != 201603
+#  error "__cpp_range_based_for != 201603"
+#endif
+
+#ifndef __cpp_decltype
+#  error "__cpp_decltype"
+#elif __cpp_decltype != 200707
+#  error "__cpp_decltype != 200707"
+#endif
+
+#ifndef __cpp_attributes
+#  error "__cpp_attributes"
+#elif __cpp_attributes != 200809
+#  error "__cpp_attributes != 200809"
+#endif
+
+#ifndef __cpp_rvalue_references
+#  error "__cpp_rvalue_references"
+#elif __cpp_rvalue_references != 200610
+#  error "__cpp_rvalue_references != 200610"
+#endif
+
+#ifndef __cpp_variadic_templates
+#  error "__cpp_variadic_templates"
+#elif __cpp_variadic_templates != 200704
+#  error "__cpp_variadic_templates != 200704"
+#endif
+
+#ifndef __cpp_initializer_lists
+#  error "__cpp_initializer_lists"
+#elif __cpp_initializer_lists != 200806
+#  error "__cpp_initializer_lists != 200806"
+#endif
+
+#ifndef __cpp_delegating_constructors
+#  error "__cpp_delegating_constructors"
+#elif __cpp_delegating_constructors != 200604
+#  error "__cpp_delegating_constructors != 200604"
+#endif
+
+#ifndef __cpp_nsdmi
+#  error "__cpp_nsdmi"
+#elif __cpp_nsdmi != 200809
+#  error "__cpp_nsdmi != 200809"
+#endif
+
+#ifndef __cpp_inheriting_constructors
+#  error "__cpp_inheriting_constructors"
+#elif  __cpp_inheriting_constructors!= 201511
+#  error "__cpp_inheriting_constructors != 201511"
+#endif
+
+#ifndef __cpp_ref_qualifiers
+#  error "__cpp_ref_qualifiers"
+#elif __cpp_ref_qualifiers != 200710
+#  error "__cpp_ref_qualifiers != 200710"
+#endif
+
+#ifndef __cpp_alias_templates
+#  error "__cpp_alias_templates"
+#elif __cpp_alias_templates != 200704
+#  error "__cpp_alias_templates != 200704"
+#endif
+
+#ifndef __cpp_threadsafe_static_init
+#  error "__cpp_threadsafe_static_init"
+#elif __cpp_threadsafe_static_init != 200806
+#  error "__cpp_threadsafe_static_init != 200806"
+#endif
+
+//  C++14 features:
+
+#ifndef __cpp_binary_literals
+#  error "__cpp_binary_literals"
+#elif __cpp_binary_literals != 201304
+#  error "__cpp_binary_literals != 201304"
+#endif
+
+#ifndef __cpp_init_captures
+#  error "__cpp_init_captures"
+#elif __cpp_init_captures != 201803
+#  error "__cpp_init_captures != 201803"
+#endif
+
+#ifndef __cpp_generic_lambdas
+#  error "__cpp_generic_lambdas"
+#elif __cpp_generic_lambdas != 201707
+#  error "__cpp_generic_lambdas != 201707"
+#endif
+
+#ifndef __cpp_constexpr
+#  error "__cpp_constexpr"
+#elif __cpp_constexpr != 201907
+#  error "__cpp_constexpr != 201907"
+#endif
+
+#ifndef __cpp_decltype_auto
+#  error "__cpp_decltype_auto"
+#elif __cpp_decltype_auto != 201304
+#  error "__cpp_decltype_auto != 201304"
+#endif
+
+#ifndef __cpp_return_type_deduction
+#  error "__cpp_return_type_deduction"
+#elif __cpp_return_type_deduction != 201304
+#  error "__cpp_return_type_deduction != 201304"
+#endif
+
+#ifndef __cpp_aggregate_nsdmi
+#  error "__cpp_aggregate_nsdmi"
+#elif __cpp_aggregate_nsdmi != 201304
+#  error "__cpp_aggregate_nsdmi != 201304"
+#endif
+
+#ifndef __cpp_variable_templates
+#  error "__cpp_variable_templates"
+#elif __cpp_variable_templates != 201304
+#  error "__cpp_variable_templates != 201304"
+#endif
+
+#ifndef __cpp_digit_separators
+#  error "__cpp_digit_separators"
+#elif __cpp_digit_separators != 201309
+#  error "__cpp_digit_separators != 201309"
+#endif
+
+#ifndef __cpp_sized_deallocation
+#  error "__cpp_sized_deallocation"
+#elif __cpp_sized_deallocation != 201309
+#  error "__cpp_sized_deallocation != 201309"
+#endif
+
+//  GNU VLA support:
+
+#ifndef __cpp_runtime_arrays
+#  error "__cpp_runtime_arrays"
+#elif __cpp_runtime_arrays != 198712
+#  error "__cpp_runtime_arrays != 198712"
+#endif
+
+//  C++11 attributes:
+
+#ifdef __has_cpp_attribute
+#  if ! __has_cpp_attribute(noreturn)
+#    error "__has_cpp_attribute(noreturn)"
+#  elif __has_cpp_attribute(noreturn) != 200809
+#    error "__has_cpp_attribute(noreturn) != 200809"
+#  endif
+#else
+#  error "__has_cpp_attribute"
+#endif
+
+//  Attribute carries_dependency not in yet.
+//#ifdef __has_cpp_attribute
+//#  if ! __has_cpp_attribute(carries_dependency)
+//#    error "__has_cpp_attribute(carries_dependency)"
+//#  elif __has_cpp_attribute(carries_dependency) != 200809
+//#    error "__has_cpp_attribute(carries_dependency) != 200809"
+//#  endif
+//#else
+//#  error "__has_cpp_attribute"
+//#endif
+
+//  C++14 attributes:
+
+#ifdef __has_cpp_attribute
+#  if ! __has_cpp_attribute(deprecated)
+#    error "__has_cpp_attribute(deprecated)"
+#  elif __has_cpp_attribute(deprecated) != 201309
+#    error "__has_cpp_attribute(deprecated) != 201309"
+#  endif
+#else
+#  error "__has_cpp_attribute"
+#endif
+
+//  Include checks:
+
+//  Check for __has_include macro.
+#ifndef __has_include
+#  error "__has_include"
+#endif
+
+//  Try known bracket header (use operator).
+#if __has_include (<complex>)
+#else
+#  error "<complex>"
+#endif
+
+//  Define and use a macro to invoke the operator.
+#define sluggo(TXT) __has_include(TXT)
+
+#if sluggo(<complex>)
+#else
+#  error "<complex>"
+#endif
+
+#if ! sluggo(<complex>)
+#  error "<complex>"
+#else
+#endif
+
+//  Quoted complex.h should find at least the bracket version.
+#if __has_include("complex.h")
+#else
+#  error "complex.h"
+#endif
+
+//  Try known local quote header.
+#if __has_include("complex_literals.h")
+#else
+#  error "\"complex_literals.h\""
+#endif
+
+//  Try nonexistent bracket header.
+#if __has_include(<stuff>)
+#  error "<stuff>"
+#else
+#endif
+
+//  Try nonexistent quote header.
+#if __has_include("phlegm")
+#  error "\"phlegm\""
+#else
+#endif
+
+//  Test __has_include_next.
+#if __has_include("phoobhar.h")
+#  include "phoobhar.h"
+#else
+#  error "__has_include(\"phoobhar.h\")"
+#endif
+
+//  Try a macro.
+#define COMPLEX_INC "complex.h"
+#if __has_include(COMPLEX_INC)
+#else
+#  error COMPLEX_INC
+#endif
+
+//  Realistic use of __has_include.
+#if __has_include(<array>)
+#  define STD_ARRAY 1
+#  include <array>
+  template<typename _Tp, std::size_t _Num>
+    using array = std::array<_Tp, _Num>;
+#elif __has_include(<tr1/array>)
+#  define TR1_ARRAY 1
+#  include <tr1/array>
+  template<typename _Tp, std::size_t _Num>
+    typedef std::tr1::array<_Tp, _Num> array;
+#endif
+
+// C++17 features:
+
+#ifndef __cpp_unicode_characters
+#  error "__cpp_unicode_characters"
+#elif __cpp_unicode_characters != 201411
+#  error "__cpp_unicode_characters != 201411"
+#endif
+
+#ifndef __cpp_static_assert
+#  error "__cpp_static_assert"
+#elif __cpp_static_assert != 201411
+#  error "__cpp_static_assert != 201411"
+#endif
+
+#ifndef __cpp_namespace_attributes
+#  error "__cpp_namespace_attributes"
+#elif __cpp_namespace_attributes != 201411
+#  error "__cpp_namespace_attributes != 201411"
+#endif
+
+#ifndef __cpp_enumerator_attributes
+#  error "__cpp_enumerator_attributes"
+#elif __cpp_enumerator_attributes != 201411
+#  error "__cpp_enumerator_attributes != 201411"
+#endif
+
+#ifndef __cpp_nested_namespace_definitions
+#  error "__cpp_nested_namespace_definitions"
+#elif __cpp_nested_namespace_definitions != 201411
+#  error "__cpp_nested_namespace_definitions != 201411"
+#endif
+
+#ifndef __cpp_fold_expressions
+#  error "__cpp_fold_expressions"
+#elif __cpp_fold_expressions != 201603
+#  error "__cpp_fold_expressions != 201603"
+#endif
+
+#ifndef __cpp_nontype_template_args
+#  error "__cpp_nontype_template_args"
+#elif __cpp_nontype_template_args != 201911
+#  error "__cpp_nontype_template_args != 201911"
+#endif
+
+#ifndef __cpp_hex_float
+#  error "__cpp_hex_float"
+#elif __cpp_hex_float != 201603
+#  error "__cpp_hex_float != 201603"
+#endif
+
+#ifndef __cpp_aggregate_bases
+#  error "__cpp_aggregate_bases"
+#elif __cpp_aggregate_bases != 201603
+#  error "__cpp_aggregate_bases != 201603"
+#endif
+
+#ifndef __cpp_deduction_guides
+#  error "__cpp_deduction_guides"
+#elif __cpp_deduction_guides != 201907
+#  error "__cpp_deduction_guides != 201907"
+#endif
+
+#ifndef __cpp_if_constexpr
+#  error "__cpp_if_constexpr"
+#elif __cpp_if_constexpr != 201606
+#  error "__cpp_if_constexpr != 201606"
+#endif
+
+#ifndef __cpp_aligned_new
+#  error "__cpp_aligned_new"
+#elif __cpp_aligned_new != 201606
+#  error "__cpp_aligned_new != 201606"
+#endif
+
+#ifndef __cpp_template_auto
+#  error "__cpp_template_auto"
+#elif __cpp_template_auto != 201606
+#  error "__cpp_template_auto != 201606"
+#endif
+
+#ifndef __cpp_inline_variables
+#  error "__cpp_inline_variables"
+#elif __cpp_inline_variables != 201606
+#  error "__cpp_inline_variables != 201606"
+#endif
+
+#ifndef __cpp_capture_star_this
+#  error "__cpp_capture_star_this"
+#elif __cpp_capture_star_this != 201603
+#  error "__cpp_capture_star_this != 201603"
+#endif
+
+#ifndef __cpp_noexcept_function_type
+#  error "__cpp_noexcept_function_type"
+#elif __cpp_noexcept_function_type != 201510
+#  error "__cpp_noexcept_function_type != 201510"
+#endif
+
+#ifndef __cpp_structured_bindings
+#  error "__cpp_structured_bindings"
+#elif __cpp_structured_bindings != 201606
+#  error "__cpp_structured_bindings != 201606"
+#endif
+
+#ifndef __cpp_template_template_args
+#  error "__cpp_template_template_args"
+#elif __cpp_template_template_args != 201611
+#  error "__cpp_template_template_args != 201611"
+#endif
+
+#ifndef __cpp_variadic_using
+#  error "__cpp_variadic_using"
+#elif __cpp_variadic_using != 201611
+#  error "__cpp_variadic_using != 201611"
+#endif
+
+#ifndef __cpp_guaranteed_copy_elision
+#  error "__cpp_guaranteed_copy_elision"
+#elif __cpp_guaranteed_copy_elision != 201606
+#  error "__cpp_guaranteed_copy_elision != 201606"
+#endif
+
+#ifndef __cpp_nontype_template_parameter_auto
+#  error "__cpp_nontype_template_parameter_auto"
+#elif __cpp_nontype_template_parameter_auto != 201606
+#  error "__cpp_nontype_template_parameter_auto != 201606"
+#endif
+
+// C++20 features
+
+#ifndef __cpp_conditional_explicit
+#  error "__cpp_conditional_explicit"
+#elif __cpp_conditional_explicit != 201806
+#  error "__cpp_conditional_explicit != 201806"
+#endif
+
+#ifndef __cpp_nontype_template_parameter_class
+#  error "__cpp_nontype_template_parameter_class"
+#elif __cpp_nontype_template_parameter_class != 201806
+#  error "__cpp_nontype_template_parameter_class != 201806"
+#endif
+
+#ifndef __cpp_impl_destroying_delete
+#  error "__cpp_impl_destroying_delete"
+#elif __cpp_impl_destroying_delete != 201806
+#  error "__cpp_impl_destroying_delete != 201806"
+#endif
+
+#ifndef __cpp_constinit
+#  error "__cpp_constinit"
+#elif __cpp_constinit != 201907
+#  error "__cpp_constinit != 201907"
+#endif
+
+#ifndef __cpp_constexpr_dynamic_alloc
+#  error "__cpp_constexpr_dynamic_alloc"
+#elif __cpp_constexpr_dynamic_alloc != 201907
+#  error "__cpp_constexpr_dynamic_alloc != 201907"
+#endif
+
+#ifndef __cpp_aggregate_paren_init
+#  error "__cpp_aggregate_paren_init"
+#elif __cpp_aggregate_paren_init != 201902
+#  error "__cpp_aggregate_paren_init != 201902"
+#endif
+
+#ifdef __has_cpp_attribute
+
+#  if ! __has_cpp_attribute(maybe_unused)
+#    error "__has_cpp_attribute(maybe_unused)"
+#  elif __has_cpp_attribute(maybe_unused) != 201603
+#    error "__has_cpp_attribute(maybe_unused) != 201603"
+#  endif
+
+#  if ! __has_cpp_attribute(nodiscard)
+#    error "__has_cpp_attribute(nodiscard)"
+#  elif __has_cpp_attribute(nodiscard) != 201907
+#    error "__has_cpp_attribute(nodiscard) != 201907"
+#  endif
+
+#  if ! __has_cpp_attribute(fallthrough)
+#    error "__has_cpp_attribute(fallthrough)"
+#  elif __has_cpp_attribute(fallthrough) != 201603
+#    error "__has_cpp_attribute(fallthrough) != 201603"
+#  endif
+
+#  if ! __has_cpp_attribute(no_unique_address)
+#    error "__has_cpp_attribute(no_unique_address)"
+#  elif __has_cpp_attribute(no_unique_address) != 201803
+#    error "__has_cpp_attribute(no_unique_address) != 201803"
+#  endif
+
+#  if ! __has_cpp_attribute(likely)
+#    error "__has_cpp_attribute(likely)"
+#  elif __has_cpp_attribute(likely) != 201803
+#    error "__has_cpp_attribute(likely) != 201803"
+#  endif
+
+#  if ! __has_cpp_attribute(unlikely)
+#    error "__has_cpp_attribute(unlikely)"
+#  elif __has_cpp_attribute(unlikely) != 201803
+#    error "__has_cpp_attribute(unlikely) != 201803"
+#  endif
+
+#else
+#  error "__has_cpp_attribute"
+#endif
+
+#ifndef __cpp_char8_t
+#  error "__cpp_char8_t"
+#elif __cpp_char8_t != 201811
+#  error "__cpp_char8_t != 201811"
+#endif
+
+#ifndef __cpp_designated_initializers
+#  error "__cpp_designated_initializers"
+#elif __cpp_designated_initializers != 201707
+#  error "__cpp_designated_initializers != 201707"
+#endif
+
+#ifndef __cpp_constexpr_in_decltype
+#  error "__cpp_constexpr_in_decltype"
+#elif __cpp_constexpr_in_decltype != 201711
+#  error "__cpp_constexpr_in_decltype != 201711"
+#endif
+
+/* Not supported fully yet:
+#ifndef __cpp_consteval
+#  error "__cpp_consteval"
+#elif __cpp_consteval != 201811
+#  error "__cpp_consteval != 201811"
+#endif
+*/
+
+#ifndef __cpp_concepts
+#  error "__cpp_concepts"
+#elif __cpp_concepts != 201907
+#  error "__cpp_concepts != 201907"
+#endif
+
+#ifndef __cpp_using_enum
+#  error "__cpp_using_enum"
+#elif __cpp_using_enum != 201907
+#  error "__cpp_using_enum != 201907"
+#endif
+
+// C++23 features:
+
+#ifndef __cpp_size_t_suffix
+#  error "__cpp_size_t_suffix"
+#elif __cpp_size_t_suffix != 202006
+#  error "__cpp_size_t_suffix != 202006"
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp23/size_t-literals.C b/gcc/testsuite/g++.dg/cpp23/size_t-literals.C
new file mode 100644
index 00000000000..3488032de3f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/size_t-literals.C
@@ -0,0 +1,8 @@
+// { dg-do compile { target c++23 } }
+
+#include <cstddef>
+#include <type_traits>
+
+static_assert(std::is_same_v<decltype(123zu), std::size_t>);
+static_assert(std::is_same_v<decltype(456z), std::make_signed_t<std::size_t>>);
+
diff --git a/gcc/testsuite/g++.dg/warn/Wsize_t-literals.C b/gcc/testsuite/g++.dg/warn/Wsize_t-literals.C
new file mode 100644
index 00000000000..1766d910454
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wsize_t-literals.C
@@ -0,0 +1,16 @@
+// { dg-do compile { target c++20_down } }
+
+#if __cplusplus >= 201103L
+
+#include <cstddef>
+#include <type_traits>
+
+std::size_t s1 = 1234zu; // { dg-warning {use of C\+\+23 .size_t. integer constant} "" { target { ! c++98_only } } }
+std::size_t S1 = 5678ZU; // { dg-warning {use of C\+\+23 .size_t. integer constant} "" { target { ! c++98_only } } }
+std::size_t s2 = 1234uz; // { dg-warning {use of C\+\+23 .size_t. integer constant} "" { target { ! c++98_only } } }
+std::size_t S2 = 5678UZ; // { dg-warning {use of C\+\+23 .size_t. integer constant} "" { target { ! c++98_only } } }
+
+std::make_signed<std::size_t>::type pd1 = 1234z; // { dg-warning {use of C\+\+23 .make_signed<size_t>::type. integer constant} "" { target { ! c++98_only } } }
+std::make_signed<std::size_t>::type PD1 = 5678Z; // { dg-warning {use of C\+\+23 .make_signed<size_t>::type. integer constant} "" { target { ! c++98_only } } }
+
+#endif
diff --git a/libcpp/expr.c b/libcpp/expr.c
index 474ea4d6b6f..42007f98b93 100644
--- a/libcpp/expr.c
+++ b/libcpp/expr.c
@@ -313,13 +313,14 @@ static unsigned int
 interpret_int_suffix (cpp_reader *pfile, const uchar *s, size_t len)
 {
   size_t orig_len = len;
-  size_t u, l, i;
+  size_t u, l, i, z;
 
-  u = l = i = 0;
+  u = l = i = z = 0;
 
   while (len--)
     switch (s[len])
       {
+      case 'z': case 'Z':	z++; break;
       case 'u': case 'U':	u++; break;
       case 'i': case 'I':
       case 'j': case 'J':	i++; break;
@@ -332,9 +333,17 @@ interpret_int_suffix (cpp_reader *pfile, const uchar *s, size_t len)
 	return 0;
       }
 
-  if (l > 2 || u > 1 || i > 1)
+  if (l > 2 || u > 1 || i > 1 || z > 1)
     return 0;
 
+  if (z)
+    {
+      if (l > 0 || i > 0)
+	return 0;
+      if (!CPP_OPTION (pfile, cplusplus))
+	return 0;
+    }
+
   if (i)
     {
       if (!CPP_OPTION (pfile, ext_numeric_literals))
@@ -352,7 +361,8 @@ interpret_int_suffix (cpp_reader *pfile, const uchar *s, size_t len)
   return ((i ? CPP_N_IMAGINARY : 0)
 	  | (u ? CPP_N_UNSIGNED : 0)
 	  | ((l == 0) ? CPP_N_SMALL
-	     : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE));
+	     : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE)
+	  | (z ? CPP_N_SIZE_T : 0));
 }
 
 /* Return the classification flags for an int suffix.  */
@@ -805,6 +815,16 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token,
 				      virtual_location, 0, message);
         }
 
+      if ((result & CPP_N_SIZE_T) == CPP_N_SIZE_T
+	  && !CPP_OPTION (pfile, size_t_literals))
+       {
+	  const char *message = (result & CPP_N_UNSIGNED) == CPP_N_UNSIGNED
+				? N_("use of C++23 %<size_t%> integer constant")
+				: N_("use of C++23 %<make_signed<size_t>::type%> integer constant");
+	  cpp_warning_with_line (pfile, CPP_W_SIZE_T_LITERALS,
+				 virtual_location, 0, message);
+       }
+
       result |= CPP_N_INTEGER;
     }
 
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 4467c73284d..17feb648ebe 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -500,6 +500,9 @@ struct cpp_options
   /* Nonzero means tokenize C++20 module directives.  */
   unsigned char module_directives;
 
+  /* Nonzero for C++23 size_t literals.  */
+  unsigned char size_t_literals;
+
   /* Holds the name of the target (execution) character set.  */
   const char *narrow_charset;
 
@@ -626,6 +629,7 @@ enum cpp_warning_reason {
   CPP_W_INVALID_PCH,
   CPP_W_WARNING_DIRECTIVE,
   CPP_W_LITERAL_SUFFIX,
+  CPP_W_SIZE_T_LITERALS,
   CPP_W_DATE_TIME,
   CPP_W_PEDANTIC,
   CPP_W_C90_C99_COMPAT,
@@ -1211,7 +1215,9 @@ struct cpp_num
 #define CPP_N_FLOATN	0x400000 /* _FloatN types.  */
 #define CPP_N_FLOATNX	0x800000 /* _FloatNx types.  */
 
-#define CPP_N_USERDEF	0x1000000 /* C++0x user-defined literal.  */
+#define CPP_N_USERDEF	0x1000000 /* C++11 user-defined literal.  */
+
+#define CPP_N_SIZE_T	0x2000000 /* C++23 size_t literal.  */
 
 #define CPP_N_WIDTH_FLOATN_NX	0xF0000000 /* _FloatN / _FloatNx value
 					      of N, divided by 16.  */
diff --git a/libcpp/init.c b/libcpp/init.c
index ecd3d5be7fd..17b0d251cda 100644
--- a/libcpp/init.c
+++ b/libcpp/init.c
@@ -94,34 +94,35 @@ struct lang_flags
   char va_opt;
   char scope;
   char dfp_constants;
+  char size_t_literals;
 };
 
 static const struct lang_flags lang_defaults[] =
-{ /*              c99 c++ xnum xid c11 std digr ulit rlit udlit bincst digsep trig u8chlit vaopt scope dfp */
-  /* GNUC89   */  { 0,  0,  1,  0,  0,  0,  1,   0,   0,   0,    0,     0,     0,   0,      1,   1,     0 },
-  /* GNUC99   */  { 1,  0,  1,  1,  0,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1,   1,     0 },
-  /* GNUC11   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1,   1,     0 },
-  /* GNUC17   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1,   1,     0 },
-  /* GNUC2X   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    1,     0,     0,   1,      1,   1,     1 },
-  /* STDC89   */  { 0,  0,  0,  0,  0,  1,  0,   0,   0,   0,    0,     0,     1,   0,      0,   0,     0 },
-  /* STDC94   */  { 0,  0,  0,  0,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   0,     0 },
-  /* STDC99   */  { 1,  0,  1,  1,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   0,     0 },
-  /* STDC11   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0,   0,     0 },
-  /* STDC17   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0,   0,     0 },
-  /* STDC2X   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    1,     0,     1,   1,      0,   1,     1 },
-  /* GNUCXX   */  { 0,  1,  1,  1,  0,  0,  1,   0,   0,   0,    0,     0,     0,   0,      1,   1,     0 },
-  /* CXX98    */  { 0,  1,  0,  1,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   1,     0 },
-  /* GNUCXX11 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    0,     0,     0,   0,      1,   1,     0 },
-  /* CXX11    */  { 1,  1,  0,  1,  1,  1,  1,   1,   1,   1,    0,     0,     1,   0,      0,   1,     0 },
-  /* GNUCXX14 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   0,      1,   1,     0 },
-  /* CXX14    */  { 1,  1,  0,  1,  1,  1,  1,   1,   1,   1,    1,     1,     1,   0,      0,   1,     0 },
-  /* GNUCXX17 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1,     0 },
-  /* CXX17    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      0,   1,     0 },
-  /* GNUCXX20 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1,     0 },
-  /* CXX20    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1,     0 },
-  /* GNUCXX23 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1,     0 },
-  /* CXX23    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1,     0 },
-  /* ASM      */  { 0,  0,  1,  0,  0,  0,  0,   0,   0,   0,    0,     0,     0,   0,      0,   0,     0 }
+{ /*              c99 c++ xnum xid c11 std digr ulit rlit udlit bincst digsep trig u8chlit vaopt scope dfp szlit */
+  /* GNUC89   */  { 0,  0,  1,  0,  0,  0,  1,   0,   0,   0,    0,     0,     0,   0,      1,   1,     0,   0 },
+  /* GNUC99   */  { 1,  0,  1,  1,  0,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1,   1,     0,   0 },
+  /* GNUC11   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1,   1,     0,   0 },
+  /* GNUC17   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1,   1,     0,   0 },
+  /* GNUC2X   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    1,     0,     0,   1,      1,   1,     1,   0 },
+  /* STDC89   */  { 0,  0,  0,  0,  0,  1,  0,   0,   0,   0,    0,     0,     1,   0,      0,   0,     0,   0 },
+  /* STDC94   */  { 0,  0,  0,  0,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   0,     0,   0 },
+  /* STDC99   */  { 1,  0,  1,  1,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   0,     0,   0 },
+  /* STDC11   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0,   0,     0,   0 },
+  /* STDC17   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0,   0,     0,   0 },
+  /* STDC2X   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    1,     0,     1,   1,      0,   1,     1,   0 },
+  /* GNUCXX   */  { 0,  1,  1,  1,  0,  0,  1,   0,   0,   0,    0,     0,     0,   0,      1,   1,     0,   0 },
+  /* CXX98    */  { 0,  1,  0,  1,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   1,     0,   0 },
+  /* GNUCXX11 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    0,     0,     0,   0,      1,   1,     0,   0 },
+  /* CXX11    */  { 1,  1,  0,  1,  1,  1,  1,   1,   1,   1,    0,     0,     1,   0,      0,   1,     0,   0 },
+  /* GNUCXX14 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   0,      1,   1,     0,   0 },
+  /* CXX14    */  { 1,  1,  0,  1,  1,  1,  1,   1,   1,   1,    1,     1,     1,   0,      0,   1,     0,   0 },
+  /* GNUCXX17 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1,     0,   0 },
+  /* CXX17    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      0,   1,     0,   0 },
+  /* GNUCXX20 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1,     0,   0 },
+  /* CXX20    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1,     0,   0 },
+  /* GNUCXX23 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1,     0,   1 },
+  /* CXX23    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1,     0,   1 },
+  /* ASM      */  { 0,  0,  1,  0,  0,  0,  0,   0,   0,   0,    0,     0,     0,   0,      0,   0,     0,   0 }
 };
 
 /* Sets internal flags correctly for a given language.  */
@@ -149,6 +150,7 @@ cpp_set_lang (cpp_reader *pfile, enum c_lang lang)
   CPP_OPTION (pfile, va_opt)			 = l->va_opt;
   CPP_OPTION (pfile, scope)			 = l->scope;
   CPP_OPTION (pfile, dfp_constants)		 = l->dfp_constants;
+  CPP_OPTION (pfile, size_t_literals)		 = l->size_t_literals;
 }
 
 /* Initialize library global state.  */


More information about the Gcc-patches mailing list