Skip to content

Commit

Permalink
c++: Adjust #embed support for P1967R14
Browse files Browse the repository at this point in the history
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.

Also, the patch changes cpp_error to cpp_pedwarning with for C++
-Wc++26-extensions guarding, and for C add -Wc11-c23-compat warning
about #embed.

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 (__FILE__))
 #if __has_embed (__FILE__ limit (__has_embed (__FILE__)))
 #endif
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++).

2025-02-28  Jakub Jelinek  <jakub@redhat.com>

libcpp/
	* include/cpplib.h (enum cpp_warning_reason): Add
	CPP_W_CXX26_EXTENSIONS enumerator.
	* init.cc (lang_defaults): Set embed for GNUCXX26 and CXX26.
	* directives.cc (do_embed): Adjust pedwarn wording for embed in C++,
	use cpp_pedwarning instead of cpp_error and add CPP_W_C11_C23_COMPAT
	warning of cpp_pedwarning hasn't diagnosed anything.
gcc/c-family/
	* c.opt (Wc++26-extensions): Add CppReason(CPP_W_CXX26_EXTENSIONS).
	* 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.
	* gcc.dg/cpp/embed-17.c: New test.
  • Loading branch information
jakubjelinek committed Feb 28, 2025
1 parent bc34db5 commit b510c53
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 12 deletions.
1 change: 1 addition & 0 deletions gcc/c-family/c-cppbuiltin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
2 changes: 1 addition & 1 deletion gcc/c-family/c.opt
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ C++ ObjC++ Var(warn_cxx23_extensions) Warning Init(1) CppReason(CPP_W_CXX23_EXTE
Warn about C++23 constructs in code compiled with an older standard.

Wc++26-extensions
C++ ObjC++ Var(warn_cxx26_extensions) Warning Init(1)
C++ ObjC++ Var(warn_cxx26_extensions) Warning Init(1) CppReason(CPP_W_CXX26_EXTENSIONS)
Warn about C++26 constructs in code compiled with an older standard.

Wcalloc-transposed-args
Expand Down
4 changes: 2 additions & 2 deletions gcc/testsuite/g++.dg/cpp/embed-1.C
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
#endif

int 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 } }
);
4 changes: 2 additions & 2 deletions gcc/testsuite/g++.dg/cpp/embed-2.C
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
#endif

int 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 } }
);
6 changes: 6 additions & 0 deletions gcc/testsuite/g++.dg/cpp26/feat-cxx26.C
Original file line number Diff line number Diff line change
Expand Up @@ -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
14 changes: 14 additions & 0 deletions gcc/testsuite/gcc.dg/cpp/embed-17.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* { dg-do compile } */
/* { dg-options "-std=c23 -Wc11-c23-compat" } */

#if __has_embed (__FILE__ limit (1)) != 1
#error "__has_embed failed"
#endif

int a =
#embed __FILE__ limit (1) /* { dg-warning "'#embed' is a C23 feature" } */
;
int b =
(__extension__
#embed __FILE__ limit (1)
);
15 changes: 10 additions & 5 deletions libcpp/directives.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1349,7 +1349,7 @@ do_embed (cpp_reader *pfile)
{
int angle_brackets;
struct cpp_embed_params params = {};
bool ok;
bool ok, warned = false;
const char *fname = NULL;

/* Tell the lexer this is an embed directive. */
Expand All @@ -1366,12 +1366,17 @@ do_embed (cpp_reader *pfile)
if (CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, embed))
{
if (CPP_OPTION (pfile, cplusplus))
cpp_error (pfile, CPP_DL_PEDWARN,
"%<#%s%> is a GCC extension", "embed");
warned = cpp_pedwarning (pfile, CPP_W_CXX26_EXTENSIONS,
"%<#%s%> before C++26 is a GCC extension",
"embed");
else
cpp_error (pfile, CPP_DL_PEDWARN,
"%<#%s%> before C23 is a GCC extension", "embed");
warned = cpp_pedwarning (pfile, CPP_W_PEDANTIC,
"%<#%s%> before C23 is a GCC extension",
"embed");
}
if (!warned && CPP_OPTION (pfile, cpp_warn_c11_c23_compat) > 0)
cpp_warning (pfile, CPP_W_C11_C23_COMPAT,
"%<#%s%> is a C23 feature", "embed");

fname = parse_include (pfile, &angle_brackets, NULL, &params.loc);
if (!fname)
Expand Down
1 change: 1 addition & 0 deletions libcpp/include/cpplib.h
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,7 @@ enum cpp_warning_reason {
CPP_W_CXX17_EXTENSIONS,
CPP_W_CXX20_EXTENSIONS,
CPP_W_CXX23_EXTENSIONS,
CPP_W_CXX26_EXTENSIONS,
CPP_W_EXPANSION_TO_DEFINED,
CPP_W_BIDIRECTIONAL,
CPP_W_INVALID_UTF8,
Expand Down
4 changes: 2 additions & 2 deletions libcpp/init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ static const struct lang_flags lang_defaults[] = {
/* 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 }
};

Expand Down

0 comments on commit b510c53

Please sign in to comment.