Message ID | 7fe5ef20-0fd5-605a-408f-8894d2fa7a73@verizon.net |
---|---|
State | New |
Headers | show |
Series | [[C++] ] Implement C++2a P0330R2 - Literal Suffixes for ptrdiff_t and size_t | expand |
On 10/21/18 4:39 PM, Ed Smith-Rowland wrote: > All, > > This patch implements C++2a proposal P0330R2 Literal Suffixes for > ptrdiff_t and size_t*. It's not official yet but looks very likely to > pass. It is incomplete because I'm looking for some opinions. (We also > might wait 'till it actually passes). I don't mind putting it in before it passes so long as you keep track of the proposal's progress -- I just discovered that the string UDL template proposal we implemented for C++14 wasn't actually accepted, so we need to pedwarn about it. > This paper takes the direction of a language change rather than a > library change through C++11 literal operators. This was after feedback > on that paper after a few iterations. > > As coded in this patch, integer suffixes involving 'z' are errors in C > and warnings for C++ <= 17 (in addition to the usual warning about > implementation suffixes shadowing user-defined ones). > > OTOH, the 'z' suffix is not currently legal - it can't break > currently-correct code in any C/C++ dialect. furthermore, I suspect the > language direction was chosen to accommodate a similar addition to C20. > > I'm thinking of making this feature available as an extension to all of > C/C++ perhaps with appropriate pedwarn. > > Opinions? That seems reasonable to me, but Joseph will need to weigh in about C. Jason
On Mon, 22 Oct 2018, Jason Merrill wrote: > > I'm thinking of making this feature available as an extension to all of > > C/C++ perhaps with appropriate pedwarn. > > > > Opinions? > > That seems reasonable to me, but Joseph will need to weigh in about C. A C extension would seem reasonable, if documented as such in the manual (and with pedwarns tested in the testsuite, etc.). (The patch is also missing invoke.texi updates for the new command-line option, in any case.)
* Ed Smith-Rowland: > This patch implements C++2a proposal P0330R2 Literal Suffixes for > ptrdiff_t and size_t*. It's not official yet but looks very likely to > pass. It is incomplete because I'm looking for some opinions. 9We > also might wait 'till it actually passes). > > This paper takes the direction of a language change rather than a > library change through C++11 literal operators. This was after > feedback on that paper after a few iterations. > > As coded in this patch, integer suffixes involving 'z' are errors in C > and warnings for C++ <= 17 (in addition to the usual warning about > implementation suffixes shadowing user-defined ones). So a plain z would denote ptrdiff_t, and size_t would be zu? That is very confusing. Why is this not consistent with %td, %zd and %zu? I would have expected t for ptrdiff_t, zu for size_t, and z for ssize_t. Thanks, Florian
On Sun, Oct 21, 2018 at 04:39:30PM -0400, Ed Smith-Rowland wrote: > This patch implements C++2a proposal P0330R2 Literal Suffixes for ptrdiff_t > and size_t*. It's not official yet but looks very likely to pass. It is > incomplete because I'm looking for some opinions. 9We also might wait 'till > it actually passes). > > This paper takes the direction of a language change rather than a library > change through C++11 literal operators. This was after feedback on that > paper after a few iterations. > > As coded in this patch, integer suffixes involving 'z' are errors in C and > warnings for C++ <= 17 (in addition to the usual warning about > implementation suffixes shadowing user-defined ones). > > OTOH, the 'z' suffix is not currently legal - it can't break > currently-correct code in any C/C++ dialect. furthermore, I suspect the > language direction was chosen to accommodate a similar addition to C20. > > I'm thinking of making this feature available as an extension to all of > C/C++ perhaps with appropriate pedwarn. GCC now supports -std=c++2b and -std=gnu++2b, are you going to update your patch against it (and change for z/Z standing for ssize_t rather than ptrdiff_t), plus incorporate the feedback from Joseph and Jason? Jakub
On 1/27/21 3:32 PM, Jakub Jelinek wrote: > On Sun, Oct 21, 2018 at 04:39:30PM -0400, Ed Smith-Rowland wrote: >> This patch implements C++2a proposal P0330R2 Literal Suffixes for ptrdiff_t >> and size_t*. It's not official yet but looks very likely to pass. It is >> incomplete because I'm looking for some opinions. 9We also might wait 'till >> it actually passes). >> >> This paper takes the direction of a language change rather than a library >> change through C++11 literal operators. This was after feedback on that >> paper after a few iterations. >> >> As coded in this patch, integer suffixes involving 'z' are errors in C and >> warnings for C++ <= 17 (in addition to the usual warning about >> implementation suffixes shadowing user-defined ones). >> >> OTOH, the 'z' suffix is not currently legal - it can't break >> currently-correct code in any C/C++ dialect. furthermore, I suspect the >> language direction was chosen to accommodate a similar addition to C20. >> >> I'm thinking of making this feature available as an extension to all of >> C/C++ perhaps with appropriate pedwarn. > GCC now supports -std=c++2b and -std=gnu++2b, are you going to update your > patch against it (and change for z/Z standing for ssize_t rather than > ptrdiff_t), plus incorporate the feedback from Joseph and Jason? > > Jakub > I'm actually working on it now!
On 1/27/21 3:32 PM, Jakub Jelinek wrote: > On Sun, Oct 21, 2018 at 04:39:30PM -0400, Ed Smith-Rowland wrote: >> This patch implements C++2a proposal P0330R2 Literal Suffixes for ptrdiff_t >> and size_t*. It's not official yet but looks very likely to pass. It is >> incomplete because I'm looking for some opinions. 9We also might wait 'till >> it actually passes). >> >> This paper takes the direction of a language change rather than a library >> change through C++11 literal operators. This was after feedback on that >> paper after a few iterations. >> >> As coded in this patch, integer suffixes involving 'z' are errors in C and >> warnings for C++ <= 17 (in addition to the usual warning about >> implementation suffixes shadowing user-defined ones). >> >> OTOH, the 'z' suffix is not currently legal - it can't break >> currently-correct code in any C/C++ dialect. furthermore, I suspect the >> language direction was chosen to accommodate a similar addition to C20. >> >> I'm thinking of making this feature available as an extension to all of >> C/C++ perhaps with appropriate pedwarn. > GCC now supports -std=c++2b and -std=gnu++2b, are you going to update your > patch against it (and change for z/Z standing for ssize_t rather than > ptrdiff_t), plus incorporate the feedback from Joseph and Jason? > > Jakub > Here is a rebased patch that is a bit leaner than the original. Since I chose to be conservative in applying this just to C++23 I'm not adding this to C or t earlier versions of C++ as extensions. We can add that if people really want, maybe in stage 1. The compat warning for C++ < 23 is not optional. since the suffixes are not preceded by '-' I don't hav much sympathy if people tried to make a literal 'z' operator. Which is the only reason I can see for a warning suppression. Built and tested on x86_64. Ok? 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..02e397bb0c0 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 = ptrdiff_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..8c5b0b99287 --- /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::ptrdiff_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..1f2f719af39 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wsize_t-literals.C @@ -0,0 +1,11 @@ +// { dg-do compile { target c++20_down } } + +#include <cstddef> + +std::size_t s1 = 1234zu; // { dg-warning "use of C\+\+23 size_t integer constant" "" { target c++20_down } } +std::size_t S1 = 5678ZU; // { dg-warning "use of C\+\+23 size_t integer constant" "" { target c++20_down } } +std::size_t s2 = 1234uz; // { dg-warning "use of C\+\+23 size_t integer constant" "" { target c++20_down } } +std::size_t S2 = 5678UZ; // { dg-warning "use of C\+\+23 size_t integer constant" "" { target c++20_down } } + +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 } } diff --git a/libcpp/expr.c b/libcpp/expr.c index 474ea4d6b6f..42cd68a3380 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 | CPP_N_LARGE) : 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 ptrdiff_t 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..f3e7213ede5 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 ptrdiff_t and 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 or ptrdiff_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. */
On 1/30/21 6:22 PM, Ed Smith-Rowland wrote: > On 1/27/21 3:32 PM, Jakub Jelinek wrote: >> On Sun, Oct 21, 2018 at 04:39:30PM -0400, Ed Smith-Rowland wrote: >>> This patch implements C++2a proposal P0330R2 Literal Suffixes for >>> ptrdiff_t >>> and size_t*. It's not official yet but looks very likely to pass. >>> It is >>> incomplete because I'm looking for some opinions. 9We also might wait >>> 'till >>> it actually passes). >>> >>> This paper takes the direction of a language change rather than a >>> library >>> change through C++11 literal operators. This was after feedback on that >>> paper after a few iterations. >>> >>> As coded in this patch, integer suffixes involving 'z' are errors in >>> C and >>> warnings for C++ <= 17 (in addition to the usual warning about >>> implementation suffixes shadowing user-defined ones). >>> >>> OTOH, the 'z' suffix is not currently legal - it can't break >>> currently-correct code in any C/C++ dialect. furthermore, I suspect the >>> language direction was chosen to accommodate a similar addition to C20. >>> >>> I'm thinking of making this feature available as an extension to all of >>> C/C++ perhaps with appropriate pedwarn. >> GCC now supports -std=c++2b and -std=gnu++2b, are you going to update >> your >> patch against it (and change for z/Z standing for ssize_t rather than >> ptrdiff_t), plus incorporate the feedback from Joseph and Jason? >> >> Jakub >> > Here is a rebased patch that is a bit leaner than the original. > > Since I chose to be conservative in applying this just to C++23 I'm not > adding this to C or t earlier versions of C++ as extensions. We can add > that if people really want, maybe in stage 1. > > The compat warning for C++ < 23 is not optional. since the suffixes are > not preceded by '-' I don't hav much sympathy if people tried to make a > literal 'z' operator. Which is the only reason I can see for a warning > suppression. > + /* itk refers to fundamental types not aliased size types. */ > + if (flags & CPP_N_UNSIGNED) > + type = size_type_node; > + else > + type = ptrdiff_type_node; This is wrong if ptrdiff_t is a different size from size_t; it should be c_common_signed_type (size_type_node). > + | (z ? (CPP_N_SIZE_T | CPP_N_LARGE) : 0)); Why CPP_N_LARGE here? That would seem to suggest that size_t is always the same size as unsigned long long. Jason
On 2/1/21 10:33 AM, Jason Merrill wrote: > On 1/30/21 6:22 PM, Ed Smith-Rowland wrote: >> On 1/27/21 3:32 PM, Jakub Jelinek wrote: >>> On Sun, Oct 21, 2018 at 04:39:30PM -0400, Ed Smith-Rowland wrote: >>>> This patch implements C++2a proposal P0330R2 Literal Suffixes for >>>> ptrdiff_t >>>> and size_t*. It's not official yet but looks very likely to pass. >>>> It is >>>> incomplete because I'm looking for some opinions. 9We also might >>>> wait 'till >>>> it actually passes). >>>> >>>> This paper takes the direction of a language change rather than a >>>> library >>>> change through C++11 literal operators. This was after feedback on >>>> that >>>> paper after a few iterations. >>>> >>>> As coded in this patch, integer suffixes involving 'z' are errors >>>> in C and >>>> warnings for C++ <= 17 (in addition to the usual warning about >>>> implementation suffixes shadowing user-defined ones). >>>> >>>> OTOH, the 'z' suffix is not currently legal - it can't break >>>> currently-correct code in any C/C++ dialect. furthermore, I >>>> suspect the >>>> language direction was chosen to accommodate a similar addition to >>>> C20. >>>> >>>> I'm thinking of making this feature available as an extension to >>>> all of >>>> C/C++ perhaps with appropriate pedwarn. >>> GCC now supports -std=c++2b and -std=gnu++2b, are you going to >>> update your >>> patch against it (and change for z/Z standing for ssize_t rather than >>> ptrdiff_t), plus incorporate the feedback from Joseph and Jason? >>> >>> Jakub >>> >> Here is a rebased patch that is a bit leaner than the original. >> >> Since I chose to be conservative in applying this just to C++23 I'm >> not adding this to C or t earlier versions of C++ as extensions. We >> can add that if people really want, maybe in stage 1. >> >> The compat warning for C++ < 23 is not optional. since the suffixes >> are not preceded by '-' I don't hav much sympathy if people tried to >> make a literal 'z' operator. Which is the only reason I can see for a >> warning suppression. > >> + /* itk refers to fundamental types not aliased size types. */ >> + if (flags & CPP_N_UNSIGNED) >> + type = size_type_node; >> + else >> + type = ptrdiff_type_node; > I thought size_type_node and ptrdiff_type_node were sort of fundamental the the others derived: ssize_t: signed_size_type_node = c_common_signed_type (size_type_node); ???: unsigned_ptrdiff_type_node = c_common_unsigned_type (ptrdiff_type_node); But I see in tree.c that things can be... interesting. Fixed... > This is wrong if ptrdiff_t is a different size from size_t; it should > be c_common_signed_type (size_type_node). > >> + | (z ? (CPP_N_SIZE_T | CPP_N_LARGE) : 0)); > > Why CPP_N_LARGE here? That would seem to suggest that size_t is > always the same size as unsigned long long. > This doesn't need to be there. I don't use it anywhere. > Jason > Is this Ok if it passes testing on x86_64-linux? Ed 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..bc4f6f9dfa7 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 = c_common_signed_type (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..8c5b0b99287 --- /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::ptrdiff_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..1f2f719af39 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wsize_t-literals.C @@ -0,0 +1,11 @@ +// { dg-do compile { target c++20_down } } + +#include <cstddef> + +std::size_t s1 = 1234zu; // { dg-warning "use of C\+\+23 size_t integer constant" "" { target c++20_down } } +std::size_t S1 = 5678ZU; // { dg-warning "use of C\+\+23 size_t integer constant" "" { target c++20_down } } +std::size_t s2 = 1234uz; // { dg-warning "use of C\+\+23 size_t integer constant" "" { target c++20_down } } +std::size_t S2 = 5678UZ; // { dg-warning "use of C\+\+23 size_t integer constant" "" { target c++20_down } } + +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 } } diff --git a/libcpp/expr.c b/libcpp/expr.c index 474ea4d6b6f..46937c33ebf 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 ptrdiff_t 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..f3e7213ede5 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 ptrdiff_t and 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 or ptrdiff_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. */
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 > +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. > + 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. > --- 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
On 2/1/21 1:46 PM, Ed Smith-Rowland wrote: > On 2/1/21 10:33 AM, Jason Merrill wrote: >> On 1/30/21 6:22 PM, Ed Smith-Rowland wrote: >>> On 1/27/21 3:32 PM, Jakub Jelinek wrote: >>>> On Sun, Oct 21, 2018 at 04:39:30PM -0400, Ed Smith-Rowland wrote: >>>>> This patch implements C++2a proposal P0330R2 Literal Suffixes for >>>>> ptrdiff_t >>>>> and size_t*. It's not official yet but looks very likely to pass. >>>>> It is >>>>> incomplete because I'm looking for some opinions. 9We also might >>>>> wait 'till >>>>> it actually passes). >>>>> >>>>> This paper takes the direction of a language change rather than a >>>>> library >>>>> change through C++11 literal operators. This was after feedback on >>>>> that >>>>> paper after a few iterations. >>>>> >>>>> As coded in this patch, integer suffixes involving 'z' are errors >>>>> in C and >>>>> warnings for C++ <= 17 (in addition to the usual warning about >>>>> implementation suffixes shadowing user-defined ones). >>>>> >>>>> OTOH, the 'z' suffix is not currently legal - it can't break >>>>> currently-correct code in any C/C++ dialect. furthermore, I >>>>> suspect the >>>>> language direction was chosen to accommodate a similar addition to >>>>> C20. >>>>> >>>>> I'm thinking of making this feature available as an extension to >>>>> all of >>>>> C/C++ perhaps with appropriate pedwarn. >>>> GCC now supports -std=c++2b and -std=gnu++2b, are you going to >>>> update your >>>> patch against it (and change for z/Z standing for ssize_t rather than >>>> ptrdiff_t), plus incorporate the feedback from Joseph and Jason? >>>> >>>> Jakub >>>> >>> Here is a rebased patch that is a bit leaner than the original. >>> >>> Since I chose to be conservative in applying this just to C++23 I'm >>> not adding this to C or t earlier versions of C++ as extensions. We >>> can add that if people really want, maybe in stage 1. >>> >>> The compat warning for C++ < 23 is not optional. since the suffixes >>> are not preceded by '-' I don't hav much sympathy if people tried to >>> make a literal 'z' operator. Which is the only reason I can see for a >>> warning suppression. >> >>> + /* itk refers to fundamental types not aliased size types. */ >>> + if (flags & CPP_N_UNSIGNED) >>> + type = size_type_node; >>> + else >>> + type = ptrdiff_type_node; >> > I thought size_type_node and ptrdiff_type_node were sort of fundamental > the the others derived: Yes, but the final proposal specifies a suffix for signed size_t, not ptrdiff_t. > ssize_t: > signed_size_type_node = c_common_signed_type (size_type_node); Ah, I wasn't aware of signed_size_type_node, that's better than my suggestion of calling c_common_signed_type again. Jason
On Mon, Feb 01, 2021 at 08:23:18PM +0100, Jakub Jelinek via Gcc-patches 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 Or better std::make_signed_t<std::size_t> etc. Jakub
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. Ed 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..8e077965bb1 --- /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++20_down } } +std::size_t S1 = 5678ZU; // { dg-warning "use of C\+\+23 .size_t. integer constant" "" { target c++20_down } } +std::size_t s2 = 1234uz; // { dg-warning "use of C\+\+23 .size_t. integer constant" "" { target c++20_down } } +std::size_t S2 = 5678UZ; // { dg-warning "use of C\+\+23 .size_t. integer constant" "" { target c++20_down } } + +std::make_signed<std::size_t>::type pd1 = 1234z; // { dg-warning "use of C\+\+23 .make_signed<size_t>::type. integer constant" "" { target c++20_down } } +std::make_signed<std::size_t>::type PD1 = 5678Z; // { dg-warning "use of C\+\+23 .make_signed<size_t>::type. integer constant" "" { target c++20_down } } + +#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. */
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
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 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. */
On 2/2/21 1:19 AM, Ed Smith-Rowland wrote: > 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. > +++ 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 I'd suggest switching the target constraints around: use target c++11 in the dg-do line, drop the #if, and use target c++20_down in the diagnostics. OK with that change. Jason
`__cpp_size_t_suffix` is defined as 202006L, but the draft standard says 202011L: http://eel.is/c++draft/cpp.predefined#tab:cpp.predefined.ft-row-48
On 2/4/21 6:31 AM, Tam S. B. wrote:
> `__cpp_size_t_suffix` is defined as 202006L, but the draft standard says 202011L: http://eel.is/c++draft/cpp.predefined#tab:cpp.predefined.ft-row-48
I looks like you're right. Both the latest draft and
https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
agree. Not sure what's up with all the dates in the latest draft of P0330...
Jason, is this OK?
Ed
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index 48dec21d4b4..9f993c4aff2 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -1028,7 +1028,7 @@ c_cpp_builtins (cpp_reader *pfile)
if (cxx_dialect > cxx20)
{
/* Set feature test macros for C++23. */
- cpp_define (pfile, "__cpp_size_t_suffix=202006L");
+ cpp_define (pfile, "__cpp_size_t_suffix=202011L");
}
if (flag_concepts)
{
diff --git a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
index 94e08a4896c..4a342e967f8 100644
--- a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
+++ b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
@@ -544,6 +544,6 @@
#ifndef __cpp_size_t_suffix
# error "__cpp_size_t_suffix"
-#elif __cpp_size_t_suffix != 202006
-# error "__cpp_size_t_suffix != 202006"
+#elif __cpp_size_t_suffix != 202011
+# error "__cpp_size_t_suffix != 202011"
#endif
On 2/4/21 11:27 AM, Ed Smith-Rowland wrote: > On 2/4/21 6:31 AM, Tam S. B. wrote: >> `__cpp_size_t_suffix` is defined as 202006L, but the draft standard >> says 202011L: >> http://eel.is/c++draft/cpp.predefined#tab:cpp.predefined.ft-row-48 > > I looks like you're right. Both the latest draft and > https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations > agree. Not sure what's up with all the dates in the latest draft of > P0330... It seems reasonable for the date in the standard to be later than the date in the proposal paper. > Jason, is this OK? OK. Jason
Index: gcc/c-family/c-cppbuiltin.c =================================================================== --- gcc/c-family/c-cppbuiltin.c (revision 265343) +++ gcc/c-family/c-cppbuiltin.c (working copy) @@ -975,6 +975,11 @@ cpp_define (pfile, "__cpp_structured_bindings=201606"); cpp_define (pfile, "__cpp_variadic_using=201611"); } + if (cxx_dialect > cxx17) + { + /* Set feature test macros for C++2a. */ + cpp_define (pfile, "__cpp_ptrdiff_t_suffix=201811"); + } if (flag_concepts) cpp_define (pfile, "__cpp_concepts=201507"); if (flag_tm) Index: gcc/c-family/c-lex.c =================================================================== --- gcc/c-family/c-lex.c (revision 265343) +++ gcc/c-family/c-lex.c (working copy) @@ -766,6 +766,14 @@ type = ((flags & CPP_N_UNSIGNED) ? widest_unsigned_literal_type_node : widest_integer_literal_type_node); + else if (flags & CPP_N_PTRDIFF_T) + { + /* itk refers to fundamental types not aliased size types. */ + if (flags & CPP_N_UNSIGNED) + type = size_type_node; + else + type = ptrdiff_type_node; + } else { type = integer_types[itk]; Index: gcc/c-family/c.opt =================================================================== --- gcc/c-family/c.opt (revision 265343) +++ gcc/c-family/c.opt (working copy) @@ -699,6 +699,10 @@ C ObjC C++ ObjC++ CPP(cpp_warn_long_long) CppReason(CPP_W_LONG_LONG) Var(warn_long_long) Init(-1) Warning LangEnabledBy(C ObjC,Wc90-c99-compat) Do not warn about using \"long long\" when -pedantic. +Wptrdiff_t-literals +C ObjC C++ ObjC++ CPP(ptrdiff_t_literals) CppReason(CPP_W_PTRDIFF_T_LITERALS) Var(warn_ptrdiff_t_literals) Init(1) Warning LangEnabledBy(C ObjC C++ ObjC++) +Warn when \"z\" or \"Z\" is used as a numeric literal suffix for C or C++yy, yy <= 17. + Wmain C ObjC C++ ObjC++ Var(warn_main) Init(-1) Warning LangEnabledBy(C ObjC,Wall, 2, 0) Warn about suspicious declarations of \"main\". Index: gcc/testsuite/g++.dg/cpp0x/udlit-shadow-neg.C =================================================================== --- gcc/testsuite/g++.dg/cpp0x/udlit-shadow-neg.C (revision 265343) +++ gcc/testsuite/g++.dg/cpp0x/udlit-shadow-neg.C (working copy) @@ -17,6 +17,30 @@ 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,6 +61,30 @@ 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 } @@ -43,7 +91,20 @@ // { 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 } Index: gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C =================================================================== --- gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C (revision 265343) +++ gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C (working copy) @@ -445,3 +445,11 @@ #else # error "__has_cpp_attribute" #endif + +// C++2a features: + +#ifndef __cpp_ptrdiff_t_suffix +# error "__cpp_ptrdiff_t_suffix" +#elif __cpp_ptrdiff_t_suffix != 201811 +# error "__cpp_ptrdiff_t_suffix != 201811" +#endif Index: libcpp/expr.c =================================================================== --- libcpp/expr.c (revision 265343) +++ libcpp/expr.c (working copy) @@ -315,13 +315,18 @@ 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; + /* So far, "ull" is the longest suffix. */ + if (len > 3) + return 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; @@ -334,9 +339,17 @@ 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)) @@ -354,7 +367,8 @@ 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_PTRDIFF_T | CPP_N_LARGE) : 0)); } /* Return the classification flags for an int suffix. */ @@ -800,6 +814,16 @@ virtual_location, 0, message); } + if ((result & CPP_N_PTRDIFF_T) == CPP_N_PTRDIFF_T + && !CPP_OPTION (pfile, ptrdiff_t_literals)) + { + const char *message = (result & CPP_N_UNSIGNED) == CPP_N_UNSIGNED + ? N_("use of C++2a size_t integer constant") + : N_("use of C++2a ptrdiff_t integer constant"); + cpp_warning_with_line (pfile, CPP_W_PTRDIFF_T_LITERALS, + virtual_location, 0, message); + } + result |= CPP_N_INTEGER; } Index: libcpp/include/cpplib.h =================================================================== --- libcpp/include/cpplib.h (revision 265343) +++ libcpp/include/cpplib.h (working copy) @@ -481,6 +481,9 @@ /* Nonzero for C++2a __VA_OPT__ feature. */ unsigned char va_opt; + /* Nonzero for C++2a ptrdiff_t and size_t literals. */ + unsigned char ptrdiff_t_literals; + /* Holds the name of the target (execution) character set. */ const char *narrow_charset; @@ -596,6 +599,7 @@ CPP_W_INVALID_PCH, CPP_W_WARNING_DIRECTIVE, CPP_W_LITERAL_SUFFIX, + CPP_W_PTRDIFF_T_LITERALS, CPP_W_DATE_TIME, CPP_W_PEDANTIC, CPP_W_C90_C99_COMPAT, @@ -1115,6 +1119,8 @@ #define CPP_N_USERDEF 0x1000000 /* C++0x user-defined literal. */ +#define CPP_N_PTRDIFF_T 0x2000000 /* C++2a size_t or ptrdiff_t */ + #define CPP_N_WIDTH_FLOATN_NX 0xF0000000 /* _FloatN / _FloatNx value of N, divided by 16. */ #define CPP_FLOATN_SHIFT 24 Index: libcpp/init.c =================================================================== --- libcpp/init.c (revision 265343) +++ libcpp/init.c (working copy) @@ -92,32 +92,33 @@ char trigraphs; char utf8_char_literals; char va_opt; + char ptrdiff_t_literals; }; static const struct lang_flags lang_defaults[] = -{ /* c99 c++ xnum xid c11 std digr ulit rlit udlit bincst digsep trig u8chlit vaopt */ - /* GNUC89 */ { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1 }, - /* GNUC99 */ { 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1 }, - /* GNUC11 */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1 }, - /* GNUC17 */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1 }, - /* GNUC2X */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1 }, - /* STDC89 */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - /* STDC94 */ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0 }, - /* STDC99 */ { 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0 }, - /* STDC11 */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0 }, - /* STDC17 */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0 }, - /* STDC2X */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0 }, - /* GNUCXX */ { 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1 }, - /* CXX98 */ { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0 }, - /* GNUCXX11 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1 }, - /* CXX11 */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0 }, - /* GNUCXX14 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1 }, - /* CXX14 */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, - /* GNUCXX17 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1 }, - /* CXX17 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0 }, - /* GNUCXX2A */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1 }, - /* CXX2A */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 }, - /* ASM */ { 0, 0, 1, 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 pdtlit */ + /* GNUC89 */ { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0 }, + /* GNUC99 */ { 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0 }, + /* GNUC11 */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0 }, + /* GNUC17 */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0 }, + /* GNUC2X */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0 }, + /* STDC89 */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, + /* STDC94 */ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, + /* STDC99 */ { 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, + /* STDC11 */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0 }, + /* STDC17 */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0 }, + /* STDC2X */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0 }, + /* GNUCXX */ { 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0 }, + /* CXX98 */ { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, + /* GNUCXX11 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0 }, + /* CXX11 */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 }, + /* GNUCXX14 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0 }, + /* CXX14 */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, + /* GNUCXX17 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0 }, + /* CXX17 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0 }, + /* GNUCXX2A */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 }, + /* CXX2A */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 }, + /* ASM */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; /* Sets internal flags correctly for a given language. */ @@ -143,6 +144,7 @@ CPP_OPTION (pfile, trigraphs) = l->trigraphs; CPP_OPTION (pfile, utf8_char_literals) = l->utf8_char_literals; CPP_OPTION (pfile, va_opt) = l->va_opt; + CPP_OPTION (pfile, ptrdiff_t_literals) = l->ptrdiff_t_literals; } /* Initialize library global state. */ Index: libstdc++-v3/include/bits/parse_numbers.h =================================================================== --- libstdc++-v3/include/bits/parse_numbers.h (revision 265343) +++ libstdc++-v3/include/bits/parse_numbers.h (working copy) @@ -193,7 +193,8 @@ __valid_digit::value ? _Pow / _Base : _Pow, _Digs...>; using type = __ull_constant<_Pow * __digit::value + __next::type::value>; - static_assert((type::value / _Pow) == __digit::value, + static_assert(!__valid_digit::value + || (type::value / _Pow) == __digit::value, "integer literal does not fit in unsigned long long"); }; Index: libstdc++-v3/testsuite/20_util/duration/literals/69905.cc =================================================================== --- libstdc++-v3/testsuite/20_util/duration/literals/69905.cc (nonexistent) +++ libstdc++-v3/testsuite/20_util/duration/literals/69905.cc (working copy) @@ -0,0 +1,25 @@ +// Copyright (C) 2016 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-do compile { target c++14 } } + +// PR libstdc++/69905 + +#include <chrono> + +using namespace std::chrono_literals; +auto time = 01'23s;