https://github.com/nfedotenko updated https://github.com/llvm/llvm-project/pull/233285
>From b28d733c9104f5f4c9ac43634426146b827e42bc Mon Sep 17 00:00:00 2001 From: Nikolay Fedotenko <[email protected]> Date: Sun, 18 Oct 2026 23:38:19 +0400 Subject: [PATCH 1/2] [clang] Finalize #embed support for C++26 (P1967R14) extension" in every C++ mode and did not define the feature-test macro. - Move the #embed extension/compatibility diagnostics to the C23Compat/CXX26Compat framework: no diagnostic in C++26 mode, "#embed is a C++2c extension" (-Wc++26-extensions) in earlier C++ modes, and a -Wpre-c++26-compat compatibility warning in C++26 mode. C mode diagnostics are unchanged. - Define __cpp_pp_embed to 202502L in all C++ modes, like the other C++26 features that Clang supports as extensions in earlier modes. - Update the status page to Partial: the remaining known issues are the braced-list initialization bugs around multi-byte #embed (#222796 and friends), which are being fixed separately (#218262, #231938). Part of #127610. --- clang/docs/ReleaseNotes.md | 7 +++++++ clang/include/clang/Basic/DiagnosticLexKinds.td | 8 ++------ clang/lib/Frontend/InitPreprocessor.cpp | 1 + clang/lib/Lex/PPDirectives.cpp | 8 +++----- clang/test/Lexer/cxx-features.cpp | 4 ++++ clang/test/Preprocessor/cxx_oper_comma.cpp | 4 ++-- clang/test/Preprocessor/embed_constexpr.cpp | 6 +++--- clang/test/Preprocessor/embed_ext_compat_diags.c | 8 +++++--- clang/test/Preprocessor/embed_feature_test.cpp | 10 ++++++++++ clang/test/Preprocessor/embed_weird.cpp | 4 ++-- clang/test/Sema/embed_compound_literal.c | 2 +- clang/test/Sema/excess-embed-data.c | 2 +- clang/test/SemaCXX/GH128985.cpp | 2 +- clang/test/SemaCXX/embed-init-list.cpp | 2 +- clang/www/cxx_status.html | 10 +++++++++- 15 files changed, 52 insertions(+), 26 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 44f30666457f94..743d5f56dd8246 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -230,6 +230,13 @@ documentation](CIR/index.md) for more information regarding ClangIR's status and #### C++2c Feature Support +- `#embed` ([P1967R14](https://wg21.link/P1967R14)) is no longer diagnosed as + an extension in C++26 mode, and the `__cpp_pp_embed` feature-test macro is + now defined. In earlier C++ language modes, the directive is now diagnosed + as a C++26 extension under `-Wc++26-extensions` (previously it was diagnosed + as a Clang extension under `-Wc23-extensions`), and a new + `-Wpre-c++26-compat` warning is available in C++26 mode. + - Added `__builtin_type_order` for compatibility with GCC as part of the implementation of [P2830R10](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2830r10.html) (Constexpr Type Ordering). diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 85f4dc6eab88a5..ee3fb0e74d2209 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -14,6 +14,7 @@ let Component = "Lex", CategoryName = "Lexical or Preprocessor Issue" in { // C23 compatibility with C17 and earlier. defm c23_pp_directive : C23Compat< "use of a '#%select{<BUG IF SEEN>|elifdef|elifndef}0' directive is", /*ext_warn*/true>; +defm c23_pp_embed_directive : C23Compat<"#embed is", /*ext_warn*/true>; // C++11 compatibility with C++98. defm empty_fnmacro_arg : CXX11Compat< @@ -30,6 +31,7 @@ defm cxx23_pp_directive : CXX23Compat< // C++26 compatibility with C++23 and earlier. defm raw_string_literal_character_set : CXX26Compat< "'%0' in a raw string literal delimiter is", /*ext_warn*/false>; +defm cxx26_pp_embed_directive : CXX26Compat<"#embed is">; def null_in_char_or_string : Warning< "null character(s) preserved in %select{char|string}0 literal">, @@ -485,12 +487,6 @@ def warn_cxx23_compat_warning_directive : Warning< def warn_c23_compat_warning_directive : Warning< "#warning is incompatible with C standards before C23">, InGroup<CPre23Compat>, DefaultIgnore; -def ext_pp_embed_directive : ExtWarn< - "#embed is a %select{C23|Clang}0 extension">, - InGroup<C23>; -def warn_compat_pp_embed_directive : Warning< - "#embed is incompatible with C standards before C23">, - InGroup<CPre23Compat>, DefaultIgnore; def err_pp_embed_dup_params : Error< "cannot specify parameter '%0' twice in the same '#embed' directive">; def err_pp_embed_device_file : Error< diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 784ff9951a25ad..4f2a2a1bd28b79 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -765,6 +765,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, Builder.defineMacro("__cpp_deleted_function", "202403L"); Builder.defineMacro("__cpp_variadic_friend", "202403L"); Builder.defineMacro("__cpp_trivial_relocatability", "202502L"); + Builder.defineMacro("__cpp_pp_embed", "202502L"); if (LangOpts.Char8) Builder.defineMacro("__cpp_char8_t", "202207L"); diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 3d991c411378e0..5d8adf36e755cf 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -4086,11 +4086,9 @@ void Preprocessor::HandleEmbedDirectiveImpl( void Preprocessor::HandleEmbedDirective(SourceLocation HashLoc, Token &EmbedTok) { // Give the usual extension/compatibility warnings. - if (LangOpts.C23) - Diag(EmbedTok, diag::warn_compat_pp_embed_directive); - else - Diag(EmbedTok, diag::ext_pp_embed_directive) - << (LangOpts.CPlusPlus ? /*Clang*/ 1 : /*C23*/ 0); + DiagCompat(EmbedTok, LangOpts.CPlusPlus + ? diag_compat::cxx26_pp_embed_directive + : diag_compat::c23_pp_embed_directive); // Parse the filename header Token FilenameTok; diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp index b505f18dff14fe..f920ad64ba056b 100644 --- a/clang/test/Lexer/cxx-features.cpp +++ b/clang/test/Lexer/cxx-features.cpp @@ -54,6 +54,10 @@ #error "wrong value for __cpp_placeholder_variables" #endif +#if check(pp_embed, 202502, 202502, 202502, 202502, 202502, 202502, 202502) +#error "wrong value for __cpp_pp_embed" +#endif + #if check(trivial_relocatability, 202502, 202502, 202502, 202502, 202502, 202502, 202502) #error "wrong value for __cpp_trivial_relocatability" #endif diff --git a/clang/test/Preprocessor/cxx_oper_comma.cpp b/clang/test/Preprocessor/cxx_oper_comma.cpp index 5db803ae41f328..cef2a0d905b20d 100644 --- a/clang/test/Preprocessor/cxx_oper_comma.cpp +++ b/clang/test/Preprocessor/cxx_oper_comma.cpp @@ -3,8 +3,8 @@ // RUN: %clang_cc1 -E -pedantic-errors %s -verify -std=c++14 // RUN: %clang_cc1 -E -pedantic-errors %s -verify -std=c++17 // RUN: %clang_cc1 -E -pedantic-errors %s -verify -std=c++20 -// RUN: %clang_cc1 -E -pedantic-errors %s -verify=expected,since-cxx23 -std=c++23 -Wno-c23-extensions -// RUN: %clang_cc1 -E -pedantic-errors %s -verify=expected,since-cxx23 -std=c++2c -Wno-c23-extensions +// RUN: %clang_cc1 -E -pedantic-errors %s -verify=expected,since-cxx23 -std=c++23 -Wno-c++26-extensions +// RUN: %clang_cc1 -E -pedantic-errors %s -verify=expected,since-cxx23 -std=c++2c -Wno-c++26-extensions // Test 1: Top-level comma // expected-error@+1 {{expected end of line in preprocessor expression}} diff --git a/clang/test/Preprocessor/embed_constexpr.cpp b/clang/test/Preprocessor/embed_constexpr.cpp index 63369599cfbb8e..f93c9b33b9a840 100644 --- a/clang/test/Preprocessor/embed_constexpr.cpp +++ b/clang/test/Preprocessor/embed_constexpr.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%S/Inputs -verify -Wno-c23-extensions -// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%S/Inputs -verify -fexperimental-new-constant-interpreter -Wno-c23-extensions -// RUN: %clang_cc1 %s -ast-dump -ast-dump-filter=ctor_list --embed-dir=%S/Inputs -Wno-c23-extensions | FileCheck %s +// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%S/Inputs -verify -Wno-c++26-extensions +// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%S/Inputs -verify -fexperimental-new-constant-interpreter -Wno-c++26-extensions +// RUN: %clang_cc1 %s -ast-dump -ast-dump-filter=ctor_list --embed-dir=%S/Inputs -Wno-c++26-extensions | FileCheck %s // expected-no-diagnostics constexpr int value(int a, int b) { diff --git a/clang/test/Preprocessor/embed_ext_compat_diags.c b/clang/test/Preprocessor/embed_ext_compat_diags.c index 74f24176d9ccab..4195014ea39b34 100644 --- a/clang/test/Preprocessor/embed_ext_compat_diags.c +++ b/clang/test/Preprocessor/embed_ext_compat_diags.c @@ -1,7 +1,9 @@ // RUN: %clang_cc1 -std=c23 %s -fsyntax-only --embed-dir=%S/Inputs -verify=none -pedantic // RUN: %clang_cc1 -std=c23 %s -fsyntax-only --embed-dir=%S/Inputs -verify=compat -Wpre-c23-compat // RUN: %clang_cc1 -std=c17 %s -fsyntax-only --embed-dir=%S/Inputs -verify=ext -pedantic -// RUN: %clang_cc1 -x c++ %s -fsyntax-only --embed-dir=%S/Inputs -verify=cxx -pedantic +// RUN: %clang_cc1 -x c++ -std=c++26 %s -fsyntax-only --embed-dir=%S/Inputs -verify=none -pedantic +// RUN: %clang_cc1 -x c++ -std=c++26 %s -fsyntax-only --embed-dir=%S/Inputs -verify=cxx-compat -Wpre-c++26-compat +// RUN: %clang_cc1 -x c++ -std=c++23 %s -fsyntax-only --embed-dir=%S/Inputs -verify=cxx-ext -pedantic // none-no-diagnostics #if __has_embed("jk.txt") @@ -9,8 +11,8 @@ const char buffer[] = { #embed "jk.txt" /* compat-warning {{#embed is incompatible with C standards before C23}} ext-warning {{#embed is a C23 extension}} - cxx-warning {{#embed is a Clang extension}} + cxx-compat-warning {{#embed is incompatible with C++ standards before C++2c}} + cxx-ext-warning {{#embed is a C++2c extension}} */ }; #endif - diff --git a/clang/test/Preprocessor/embed_feature_test.cpp b/clang/test/Preprocessor/embed_feature_test.cpp index 2648804132599b..2b44586012a168 100644 --- a/clang/test/Preprocessor/embed_feature_test.cpp +++ b/clang/test/Preprocessor/embed_feature_test.cpp @@ -5,3 +5,13 @@ #if !defined(__has_embed) #error 1 #endif + +#ifdef __cplusplus +#if __cpp_pp_embed != 202502L +#error 2 +#endif +#else +#ifdef __cpp_pp_embed +#error 3 +#endif +#endif diff --git a/clang/test/Preprocessor/embed_weird.cpp b/clang/test/Preprocessor/embed_weird.cpp index e44aff55c59e22..fd7cc921891a9a 100644 --- a/clang/test/Preprocessor/embed_weird.cpp +++ b/clang/test/Preprocessor/embed_weird.cpp @@ -2,9 +2,9 @@ // RUN: cp %S/Inputs/single_byte.txt %S/Inputs/jk.txt %S/Inputs/numbers.txt %t/ // RUN: cp %S/Inputs/media/empty %t/media/ // RUN: printf "\0" > %t/null_byte.bin -// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%t -verify=expected,cxx -Wno-c23-extensions +// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%t -verify=expected,cxx -Wno-c++26-extensions // RUN: %clang_cc1 -x c -std=c23 %s -fsyntax-only --embed-dir=%t -verify=expected,c -// RUN: %clang_cc1 %s -fsyntax-only -fexperimental-new-constant-interpreter --embed-dir=%t -verify=expected,cxx -Wno-c23-extensions +// RUN: %clang_cc1 %s -fsyntax-only -fexperimental-new-constant-interpreter --embed-dir=%t -verify=expected,cxx -Wno-c++26-extensions // RUN: %clang_cc1 -x c -std=c23 %s -fsyntax-only -fexperimental-new-constant-interpreter --embed-dir=%t -verify=expected,c #embed <media/empty> ; diff --git a/clang/test/Sema/embed_compound_literal.c b/clang/test/Sema/embed_compound_literal.c index 7ba6fd8e649683..895ef8869b21d0 100644 --- a/clang/test/Sema/embed_compound_literal.c +++ b/clang/test/Sema/embed_compound_literal.c @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -std=c23 -fsyntax-only -verify %s -// RUN: %clang_cc1 -fsyntax-only -verify -x c++ -Wno-c23-extensions %s +// RUN: %clang_cc1 -fsyntax-only -verify -x c++ -Wno-c++26-extensions %s // expected-no-diagnostics char *p1 = (char[]){ diff --git a/clang/test/Sema/excess-embed-data.c b/clang/test/Sema/excess-embed-data.c index f6d06bff6a7ca5..4728e64cf858c4 100644 --- a/clang/test/Sema/excess-embed-data.c +++ b/clang/test/Sema/excess-embed-data.c @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -std=c23 -fsyntax-only -verify=c %s -// RUN: %clang_cc1 -fsyntax-only -verify=cpp -x c++ -Wno-c23-extensions %s +// RUN: %clang_cc1 -fsyntax-only -verify=cpp -x c++ -Wno-c++26-extensions %s struct S { diff --git a/clang/test/SemaCXX/GH128985.cpp b/clang/test/SemaCXX/GH128985.cpp index 0d51e3e53582f6..9a6d24d773f458 100644 --- a/clang/test/SemaCXX/GH128985.cpp +++ b/clang/test/SemaCXX/GH128985.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c23-extensions %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++26-extensions %s struct S { int a, b; diff --git a/clang/test/SemaCXX/embed-init-list.cpp b/clang/test/SemaCXX/embed-init-list.cpp index d949afccb219f3..5f2a15efa1c5b2 100644 --- a/clang/test/SemaCXX/embed-init-list.cpp +++ b/clang/test/SemaCXX/embed-init-list.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c23-extensions %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++26-extensions %s namespace std { typedef decltype(sizeof(int)) size_t; diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index 3f105f831f9b76..780009948672f5 100755 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -400,7 +400,15 @@ <h2 id="cxx26">C++2c implementation status</h2> <tr> <td><pre>#embed</pre></td> <td><a href="https://wg21.link/P1967">P1967R14</a></td> - <td class="none" align="center">No</td> + <td class="partial" align="center"> + <details> + <summary>Clang 24 (Partial)</summary> + The directive and its parameters are supported since Clang 19, and the + <tt>__cpp_pp_embed</tt> feature-test macro since Clang 24. A multi-byte + <tt>#embed</tt> in a braced initializer list that initializes a + non-aggregate object is not yet handled correctly in some contexts. + </details> + </td> </tr> <!-- Bulgaria, Spring 2025 --> <tr> >From 779b66a80877ad66625ef093413168de86efac61 Mon Sep 17 00:00:00 2001 From: Nikolay Fedotenko <[email protected]> Date: Tue, 20 Oct 2026 22:14:45 +0400 Subject: [PATCH 2/2] Drop the feature-test macro per the InternalsManual criteria __cpp_pp_embed will be proposed separately once the known braced-list miscompile (#222796) is fixed by #231938. --- clang/docs/ReleaseNotes.md | 11 ++++++----- clang/lib/Frontend/InitPreprocessor.cpp | 1 - clang/test/Lexer/cxx-features.cpp | 4 ---- clang/test/Preprocessor/embed_feature_test.cpp | 10 ---------- clang/www/cxx_status.html | 8 ++++---- 5 files changed, 10 insertions(+), 24 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 743d5f56dd8246..200c41fb9e4a29 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -231,11 +231,12 @@ documentation](CIR/index.md) for more information regarding ClangIR's status and #### C++2c Feature Support - `#embed` ([P1967R14](https://wg21.link/P1967R14)) is no longer diagnosed as - an extension in C++26 mode, and the `__cpp_pp_embed` feature-test macro is - now defined. In earlier C++ language modes, the directive is now diagnosed - as a C++26 extension under `-Wc++26-extensions` (previously it was diagnosed - as a Clang extension under `-Wc23-extensions`), and a new - `-Wpre-c++26-compat` warning is available in C++26 mode. + an extension in C++26 mode. In earlier C++ language modes, the directive is + now diagnosed as a C++26 extension under `-Wc++26-extensions` (previously it + was diagnosed as a Clang extension under `-Wc23-extensions`), and a new + `-Wpre-c++26-compat` warning is available in C++26 mode. The + `__cpp_pp_embed` feature-test macro is not yet defined because of known + issues in the implementation. - Added `__builtin_type_order` for compatibility with GCC as part of the implementation of [P2830R10](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2830r10.html) (Constexpr Type Ordering). diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 4f2a2a1bd28b79..784ff9951a25ad 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -765,7 +765,6 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, Builder.defineMacro("__cpp_deleted_function", "202403L"); Builder.defineMacro("__cpp_variadic_friend", "202403L"); Builder.defineMacro("__cpp_trivial_relocatability", "202502L"); - Builder.defineMacro("__cpp_pp_embed", "202502L"); if (LangOpts.Char8) Builder.defineMacro("__cpp_char8_t", "202207L"); diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp index f920ad64ba056b..b505f18dff14fe 100644 --- a/clang/test/Lexer/cxx-features.cpp +++ b/clang/test/Lexer/cxx-features.cpp @@ -54,10 +54,6 @@ #error "wrong value for __cpp_placeholder_variables" #endif -#if check(pp_embed, 202502, 202502, 202502, 202502, 202502, 202502, 202502) -#error "wrong value for __cpp_pp_embed" -#endif - #if check(trivial_relocatability, 202502, 202502, 202502, 202502, 202502, 202502, 202502) #error "wrong value for __cpp_trivial_relocatability" #endif diff --git a/clang/test/Preprocessor/embed_feature_test.cpp b/clang/test/Preprocessor/embed_feature_test.cpp index 2b44586012a168..2648804132599b 100644 --- a/clang/test/Preprocessor/embed_feature_test.cpp +++ b/clang/test/Preprocessor/embed_feature_test.cpp @@ -5,13 +5,3 @@ #if !defined(__has_embed) #error 1 #endif - -#ifdef __cplusplus -#if __cpp_pp_embed != 202502L -#error 2 -#endif -#else -#ifdef __cpp_pp_embed -#error 3 -#endif -#endif diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index 780009948672f5..67a73771b05a6c 100755 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -403,10 +403,10 @@ <h2 id="cxx26">C++2c implementation status</h2> <td class="partial" align="center"> <details> <summary>Clang 24 (Partial)</summary> - The directive and its parameters are supported since Clang 19, and the - <tt>__cpp_pp_embed</tt> feature-test macro since Clang 24. A multi-byte - <tt>#embed</tt> in a braced initializer list that initializes a - non-aggregate object is not yet handled correctly in some contexts. + The directive and its parameters are supported since Clang 19. A + multi-byte <tt>#embed</tt> in a braced initializer list that initializes + a non-aggregate object is not yet handled correctly in some contexts, so + the <tt>__cpp_pp_embed</tt> feature-test macro is not defined yet. </details> </td> </tr> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
