On 2/24/25 4:31 AM, Jakub Jelinek wrote:
Hi!Now that the #embed paper has been voted in, the following patch removes the pedwarn for C++26 on it (and adjusts pedwarn warning for older C++ versions) and predefines __cpp_pp_embed FTM. I believe we otherwise implement everything in the paper already, except I'm really confused by the [Example: #embed <data.dat> limit(__has_include("a.h")) #if __has_embed(<data.dat> limit(__has_include("a.h"))) // ill-formed: __has_include [cpp.cond] cannot appear here #endif — end example] part. My reading of both C23 and C++ with the P1967R14 paper in is that the first case (#embed with __has_include or __has_embed in its clauses) is what is clearly invalid and so the ill-formed note should be for #embed. And the __has_include/__has_embed in __has_embed is actually questionable. Both C and C++ have something like "The identifiers __has_include, __has_embed, and __has_c_attribute shall not appear in any context not mentioned in this subclause." or "The identifiers __has_include and __has_cpp_attribute shall not appear in any context not mentioned in this subclause." (into which P1967R14 adds __has_embed) in the conditional inclusion subclause. #embed is defined in a different one, so using those in there is invalid (unless "using the rules specified for conditional inclusion" wording e.g. in limit clause overrides that). The reason why I think it is fuzzy for __has_embed is that __has_embed is actually defined in the Conditional inclusion subclause (so that would mean one can use __has_include, __has_embed and __has_*attribute in there) but its clauses are described in a different one. GCC currently accepts #embed __FILE__ limit (__has_include (<stdarg.h>)) #if __has_embed (__FILE__ limit (__has_include (<stdarg.h>))) #endif #embed __FILE__ limit (__has_embed ("a.c")) #if __has_embed (__FILE__ limit (__has_embed ("a.c"))) #endif with the exception of __has_embed in #embed which results in a strange message. Note, it isn't just about limit clause, but also about prefix/suffix/if_empty, except that in those cases the "using the rules specified for conditional inclusion" doesn't apply. In any case, I'd hope that can be dealt with incrementally (and should be handled the same for both C and C++).
I agree.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2025-02-24 Jakub Jelinek <ja...@redhat.com> libcpp/ * init.cc (lang_defaults): Set embed for GNUCXX26 and CXX26. * directives.cc (do_embed): Adjust pedwarn wording for embed in C++. gcc/c-family/ * c-cppbuiltin.cc (c_cpp_builtins): Predefine __cpp_pp_embed=202502 for C++26. gcc/testsuite/ * g++.dg/cpp/embed-1.C: Adjust for pedwarn wording change and don't expect any error for C++26. * g++.dg/cpp/embed-2.C: Adjust for pedwarn wording change and don't expect any warning for C++26. * g++.dg/cpp26/feat-cxx26.C: Test __cpp_pp_embed value. --- libcpp/init.cc.jj 2025-02-13 19:59:56.204572159 +0100 +++ libcpp/init.cc 2025-02-20 21:28:07.340156536 +0100 @@ -149,8 +149,8 @@ static const struct lang_flags lang_defa /* CXX20 */ { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,0,1,0,0,1 }, /* GNUCXX23 */ { 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,0,0,1 }, /* CXX23 */ { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,0,0,1 }, - /* GNUCXX26 */ { 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,0,0,1 }, - /* CXX26 */ { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,0,0,1 }, + /* GNUCXX26 */ { 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,1,0,1 }, + /* CXX26 */ { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,1,0,1 }, /* ASM */ { 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } };--- libcpp/directives.cc.jj 2025-02-13 19:59:56.202572170 +0100+++ libcpp/directives.cc 2025-02-20 21:40:56.379899457 +0100 @@ -1367,7 +1367,7 @@ do_embed (cpp_reader *pfile) { if (CPP_OPTION (pfile, cplusplus)) cpp_error (pfile, CPP_DL_PEDWARN, - "%<#%s%> is a GCC extension", "embed"); + "%<#%s%> before C++26 is a GCC extension", "embed");
Please change this to cpp_pedwarning/CPP_W_CXX26_EXTENSIONS.
else cpp_error (pfile, CPP_DL_PEDWARN, "%<#%s%> before C23 is a GCC extension", "embed"); --- gcc/c-family/c-cppbuiltin.cc.jj 2025-02-13 19:59:55.144578075 +0100 +++ gcc/c-family/c-cppbuiltin.cc 2025-02-20 21:34:18.626480792 +0100 @@ -1093,6 +1093,7 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__cpp_deleted_function=202403L"); cpp_define (pfile, "__cpp_variadic_friend=202403L"); cpp_define (pfile, "__cpp_pack_indexing=202311L"); + cpp_define (pfile, "__cpp_pp_embed=202502L"); } if (flag_concepts && cxx_dialect > cxx14) cpp_define (pfile, "__cpp_concepts=202002L"); --- gcc/testsuite/g++.dg/cpp/embed-1.C.jj 2024-10-13 18:47:45.508432900 +0200 +++ gcc/testsuite/g++.dg/cpp/embed-1.C 2025-02-20 21:38:23.306353505 +0100 @@ -6,9 +6,9 @@ #endifint a =-#embed __FILE__ limit (1) // { dg-error "'#embed' is a GCC extension" } +#embed __FILE__ limit (1) // { dg-error "'#embed' before C\\\+\\\+26 is a GCC extension" "" { target c++23_down } } ; int b = (__extension__ -#embed __FILE__ limit (1) // { dg-error "'#embed' is a GCC extension" } +#embed __FILE__ limit (1) // { dg-error "'#embed' before C\\\+\\\+26 is a GCC extension" "" { target c++23_down } } ); --- gcc/testsuite/g++.dg/cpp/embed-2.C.jj 2024-10-13 18:47:45.508432900 +0200 +++ gcc/testsuite/g++.dg/cpp/embed-2.C 2025-02-20 21:38:46.833437411 +0100 @@ -6,9 +6,9 @@ #endifint a =-#embed __FILE__ limit (1) // { dg-warning "'#embed' is a GCC extension" } +#embed __FILE__ limit (1) // { dg-warning "'#embed' before C\\\+\\\+26 is a GCC extension" "" { target c++23_down } } ; int b = (__extension__ -#embed __FILE__ limit (1) // { dg-warning "'#embed' is a GCC extension" } +#embed __FILE__ limit (1) // { dg-warning "'#embed' before C\\\+\\\+26 is a GCC extension" "" { target c++23_down } } ); --- gcc/testsuite/g++.dg/cpp26/feat-cxx26.C.jj 2025-02-13 19:59:55.862574068 +0100 +++ gcc/testsuite/g++.dg/cpp26/feat-cxx26.C 2025-02-20 21:39:37.061616546 +0100 @@ -628,3 +628,9 @@ #elif __cpp_pack_indexing != 202311 # error "__cpp_pack_indexing != 202311" #endif + +#ifndef __cpp_pp_embed +# error "__cpp_pp_embed" +#elif __cpp_pp_embed != 202502 +# error "__cpp_pp_embed != 202502" +#endif