From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id BFAC83858D20 for ; Wed, 12 Jul 2023 22:33:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BFAC83858D20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1689201189; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=H++Q9TL1o3LeDSFcEvX80lokH8WeJZE2ZrMJoAQDueA=; b=JaOROlXR6OWFxPKSC6u+JV8r5BW8ccbGlBO3WzTWlO73/qVQXDvQIkAqpDpBrah+fdopPK QSphKnnUJ3zSO2j7AYXuZMVz1U8b+1+n9iXEvDErgDOO87inXvPu64brLA5Z+8Gf/0Kna2 2KDY+bWi0NVDYdLykcsjCxfbXxklWgA= Received: from mail-oi1-f197.google.com (mail-oi1-f197.google.com [209.85.167.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-10-BAb7rNEfMTWSnUlM-8hMvg-1; Wed, 12 Jul 2023 18:32:58 -0400 X-MC-Unique: BAb7rNEfMTWSnUlM-8hMvg-1 Received: by mail-oi1-f197.google.com with SMTP id 5614622812f47-3a36b311b5cso121287b6e.3 for ; Wed, 12 Jul 2023 15:32:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689201178; x=1691793178; h=user-agent:in-reply-to:content-disposition:mime-version:references :message-id:subject:cc:to:from:date:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=H++Q9TL1o3LeDSFcEvX80lokH8WeJZE2ZrMJoAQDueA=; b=QZHCumwZsJfdEqQOCrmYJ6uXFchzOz/cdbB+h96XNOxJkRYhGCUioXpPEb7EkDnroo 6iF5+r/D+5ikVxK151lqnJCk3V0IcqCQ8LQN0HkHutj13JPgg2m7e2ptq6Yn6ml84lJu 0W47QrhwYFb8LZ/UhwHENTXKbJLGoid01ZX6FA3kkYhm0YwKoHJNHHdEcjlsGiWQT4c1 SGQ/PSRJfoBJid8FaKmqExN4PxEH86+dCRbikdfVKb2hh3NkHId+vuWTWzy9domq2JBw anKa+11UzRH/fxmdMgaLyAktSTFBpEFg2gyZO+ei3WYLPN/oB48IhbR5mNV3nmrItkbi TUMQ== X-Gm-Message-State: ABy/qLbYR2zkFDAszFXo8qnHGx4lcI6fg9yl0dUFoFIoEDLqUhhIdrS3 +IT6fdoKI0WKoIhgwQq6UlL4cm1cq9XDqgvj+eID25RmRwxKYuUdJ6uWFnpqSlwmLCNQlBOuugJ TKNIHpGveOGy7GwDu3g== X-Received: by 2002:a05:6808:1491:b0:3a4:316b:4695 with SMTP id e17-20020a056808149100b003a4316b4695mr643450oiw.46.1689201178033; Wed, 12 Jul 2023 15:32:58 -0700 (PDT) X-Google-Smtp-Source: APBJJlG8h2FiN4E9R+xDwTAPeU0pdBLRneccBbf1091lJuUGI3zPFgZXRE6qg8/TPECxuz3WVWUN5A== X-Received: by 2002:a05:6808:1491:b0:3a4:316b:4695 with SMTP id e17-20020a056808149100b003a4316b4695mr643428oiw.46.1689201177554; Wed, 12 Jul 2023 15:32:57 -0700 (PDT) Received: from redhat.com (2603-7000-9500-34a5-0000-0000-0000-1db4.res6.spectrum.com. [2603:7000:9500:34a5::1db4]) by smtp.gmail.com with ESMTPSA id h24-20020ac846d8000000b0040331a24f16sm2608590qto.3.2023.07.12.15.32.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jul 2023 15:32:57 -0700 (PDT) Date: Wed, 12 Jul 2023 18:32:54 -0400 From: Marek Polacek To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: Re: [pushed] c++: C++26 constexpr cast from void* [PR110344] Message-ID: References: <20230628032934.2615167-1-jason@redhat.com> MIME-Version: 1.0 In-Reply-To: <20230628032934.2615167-1-jason@redhat.com> User-Agent: Mutt/2.2.9 (2022-11-12) X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Tue, Jun 27, 2023 at 11:29:34PM -0400, Jason Merrill via Gcc-patches wrote: > Tested x86_64-pc-linux-gnu, applying to trunk. > > -- 8< -- > > P2768 allows static_cast from void* to ob* in constant evaluation if the > pointer does in fact point to an object of the appropriate type. > cxx_fold_indirect_ref already does the work of finding such an object if it > happens to be a subobject rather than the outermost object at that address, > as in constexpr-voidptr2.C. This patch seems to have broken a lot of tests when running with GXX_TESTSUITE_STDS=98,11,14,17,20,23,26. cpp0x/constexpr-cast2.C probably just needs not to expect certain errors in C++26, and cpp2a/constexpr-new*.C may need code to handle &heap (?). > P2768 > PR c++/110344 > > gcc/c-family/ChangeLog: > > * c-cppbuiltin.cc (c_cpp_builtins): Update __cpp_constexpr. > > gcc/cp/ChangeLog: > > * constexpr.cc (cxx_eval_constant_expression): In C++26, allow cast > from void* to the type of a pointed-to object. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp26/constexpr-voidptr1.C: New test. > * g++.dg/cpp26/constexpr-voidptr2.C: New test. > * g++.dg/cpp26/feat-cxx26.C: New test. > --- > gcc/c-family/c-cppbuiltin.cc | 8 +- > gcc/cp/constexpr.cc | 11 + > .../g++.dg/cpp26/constexpr-voidptr1.C | 35 + > .../g++.dg/cpp26/constexpr-voidptr2.C | 15 + > gcc/testsuite/g++.dg/cpp26/feat-cxx26.C | 597 ++++++++++++++++++ > 5 files changed, 665 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp26/constexpr-voidptr1.C > create mode 100644 gcc/testsuite/g++.dg/cpp26/constexpr-voidptr2.C > create mode 100644 gcc/testsuite/g++.dg/cpp26/feat-cxx26.C > > diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc > index 5d64625fcd7..6bd4c1261a7 100644 > --- a/gcc/c-family/c-cppbuiltin.cc > +++ b/gcc/c-family/c-cppbuiltin.cc > @@ -1075,12 +1075,18 @@ c_cpp_builtins (cpp_reader *pfile) > cpp_define (pfile, "__cpp_size_t_suffix=202011L"); > cpp_define (pfile, "__cpp_if_consteval=202106L"); > cpp_define (pfile, "__cpp_auto_cast=202110L"); > - cpp_define (pfile, "__cpp_constexpr=202211L"); > + if (cxx_dialect <= cxx23) > + cpp_define (pfile, "__cpp_constexpr=202211L"); > cpp_define (pfile, "__cpp_multidimensional_subscript=202211L"); > cpp_define (pfile, "__cpp_named_character_escapes=202207L"); > cpp_define (pfile, "__cpp_static_call_operator=202207L"); > cpp_define (pfile, "__cpp_implicit_move=202207L"); > } > + if (cxx_dialect > cxx23) > + { > + /* Set feature test macros for C++26. */ > + cpp_define (pfile, "__cpp_constexpr=202306L"); > + } > if (flag_concepts) > { > if (cxx_dialect >= cxx20) > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > index 432b3a275e8..cca0435bafc 100644 > --- a/gcc/cp/constexpr.cc > +++ b/gcc/cp/constexpr.cc > @@ -7681,6 +7681,17 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, > && !is_std_construct_at (ctx->call) > && !is_std_allocator_allocate (ctx->call)) > { > + /* P2738 (C++26): a conversion from a prvalue P of type "pointer to > + cv void" to a pointer-to-object type T unless P points to an > + object whose type is similar to T. */ > + if (cxx_dialect > cxx23) > + if (tree ob > + = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), op)) > + { > + r = build1 (ADDR_EXPR, type, ob); > + break; > + } > + > /* Likewise, don't error when casting from void* when OP is > &heap uninit and similar. */ > tree sop = tree_strip_nop_conversions (op); > diff --git a/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr1.C b/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr1.C > new file mode 100644 > index 00000000000..ce0ccbef5f9 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr1.C > @@ -0,0 +1,35 @@ > +// PR c++/110344 > +// { dg-do compile { target c++26 } } > + > +#include > +struct Sheep { > + constexpr std::string_view speak() const noexcept { return "Baaaaaa"; } > +}; > +struct Cow { > + constexpr std::string_view speak() const noexcept { return "Mooo"; } > +}; > +class Animal_View { > +private: > + const void *animal; > + std::string_view (*speak_function)(const void *); > +public: > + template > + constexpr Animal_View(const Animal &a) > + : animal{&a}, speak_function{[](const void *object) { > + return static_cast(object)->speak(); > + }} {} > + constexpr std::string_view speak() const noexcept { > + return speak_function(animal); > + } > +}; > +// This is the key bit here. This is a single concrete function > +// that can take anything that happens to have the "Animal_View" > +// interface > +constexpr std::string_view do_speak(Animal_View av) { return av.speak(); } > +int main() { > + // A Cow is a cow. The only think that makes it special > + // is that it has a "std::string_view speak() const" member > + constexpr Cow cow; > + constexpr auto result = do_speak(cow); > + return static_cast(result.size()); > +} > diff --git a/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr2.C b/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr2.C > new file mode 100644 > index 00000000000..e746301e9f9 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr2.C > @@ -0,0 +1,15 @@ > +// PR c++/110344 > +// { dg-do compile { target c++26 } } > + > +struct A { int i; }; > +struct B { A a; }; > + > +constexpr int f() > +{ > + B b { 42 }; > + void *p = &b; > + A* ap = static_cast(p); > + return ap->i; > +} > + > +static_assert (f() == 42); > diff --git a/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C > new file mode 100644 > index 00000000000..0977d964fe0 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C > @@ -0,0 +1,597 @@ > +// { dg-options "-std=c++26 -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 != 202306L > +# error "__cpp_constexpr != 202306L" > +#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 () > +#else > +# error "" > +#endif > + > +// Define and use a macro to invoke the operator. > +#define sluggo(TXT) __has_include(TXT) > + > +#if sluggo() > +#else > +# error "" > +#endif > + > +#if ! sluggo() > +# error "" > +#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() > +# error "" > +#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() > +# define STD_ARRAY 1 > +# include > + template > + using array = std::array<_Tp, _Num>; > +#elif __has_include() > +# define TR1_ARRAY 1 > +# include > + template > + 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 > + > +#ifndef __cpp_char8_t > +# error "__cpp_char8_t" > +#elif __cpp_char8_t != 202207 > +# error "__cpp_char8_t != 202207" > +#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 > + > +#ifndef __cpp_consteval > +# error "__cpp_consteval" > +#elif __cpp_consteval != 201811 > +# error "__cpp_consteval != 201811" > +#endif > + > +#ifndef __cpp_concepts > +# error "__cpp_concepts" > +#elif __cpp_concepts != 202002 > +# error "__cpp_concepts != 202002" > +#endif > + > +#ifndef __cpp_using_enum > +# error "__cpp_using_enum" > +#elif __cpp_using_enum != 201907 > +# error "__cpp_using_enum != 201907" > +#endif > + > +// C++20 attributes: > + > +#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 > + > +// C++23 features: > + > +#ifndef __cpp_size_t_suffix > +# error "__cpp_size_t_suffix" > +#elif __cpp_size_t_suffix != 202011 > +# error "__cpp_size_t_suffix != 202011" > +#endif > + > +#ifndef __cpp_if_consteval > +# error "__cpp_if_consteval" > +#elif __cpp_if_consteval != 202106 > +# error "__cpp_if_consteval != 202106" > +#endif > + > +#ifndef __cpp_multidimensional_subscript > +# error "__cpp_multidimensional_subscript" > +#elif __cpp_multidimensional_subscript != 202211 > +# error "__cpp_multidimensional_subscript != 202211" > +#endif > + > +#ifndef __cpp_named_character_escapes > +# error "__cpp_named_character_escapes" > +#elif __cpp_named_character_escapes != 202207 > +# error "__cpp_named_character_escapes != 202207" > +#endif > + > +#ifndef __cpp_static_call_operator > +# error "__cpp_static_call_operator" > +#elif __cpp_static_call_operator != 202207 > +# error "__cpp_static_call_operator != 202207" > +#endif > + > +#ifndef __cpp_implicit_move > +# error "__cpp_implicit_move" > +#elif __cpp_implicit_move != 202207 > +# error "__cpp_implicit_move != 202207" > +#endif > + > +#ifndef __cpp_auto_cast > +# error "__cpp_auto_cast" > +#elif __cpp_auto_cast != 202110 > +# error "__cpp_auto_cast != 202110" > +#endif > + > +// C++23 attributes: > + > +#ifdef __has_cpp_attribute > +# if ! __has_cpp_attribute(assume) > +# error "__has_cpp_attribute(assume)" > +# elif __has_cpp_attribute(assume) != 202207 > +# error "__has_cpp_attribute(assume) != 202207" > +# endif > +#else > +# error "__has_cpp_attribute" > +#endif > > base-commit: ebe7c586f62b1c5218b19c3c6853163287b3c887 > prerequisite-patch-id: 8aff665478d425e404ede05fed4c0e4106a063f2 > -- > 2.39.3 > Marek