[RFC PATCH] testsuite: Add plugin to verify bits/std.cc exports
Jonathan Wakely
jwakely@redhat.com
Thu Mar 19 15:03:38 GMT 2026
On Thu, 19 Mar 2026 at 14:14, Jakub Jelinek <jakub@redhat.com> wrote:
>
> Hi!
>
> The following patch adds another g++.dg/plugin/ testsuite plugin,
> this time to verify whether some std.cc exports aren't mistakenly
> omitted. The patch is on top of the uglification plugin patch,
> but only dependent on it because of the plugin_test_list hunk,
> it could be applied independently with a little effort.
>
> The patch is a reworked version of the
> https://gcc.gnu.org/pipermail/libstdc++/2025-August/thread.html#62859
> proof of concept. That version just dumped out everything it saw
> in the std namespace and its child namespaces (excluding non-inline
> subnamespaces with identifiers starting with underscore) and then I've
> used sed&grep to form a list of omissions.
>
> This patch keeps the previous walk of std namespace and namespaces children
> of it, but it only reports (in this version using error_at instead of inform
> previously) what it finds if it isn't exported from the module and is not
> deprecated (deprecated attribute is used usually for zombie.names in the
> standard).
>
> I've been strugling with the detection of what is and what isn't exported,
> had to try several different methods.
> What is DECL_MODULE_EXPORT_P is ignored, but that is not set on everything
> actually exported. In other cases there is OVL_EXPORT_P flag on OVERLOAD
> (but OVL_HIDDEN_P at the start doesn't have it). Another case are inline
> namespaces, e.g. for std::filesystem::__cxx11::begin or
> std::filesystem::__cxx11::directory_iterator. In the latter case, there
> is no sign of the above flags in __cxx11 binding entry, but there is a
> USING_DECL with the same name directly in std::filesystem. And for begin
> there is OVERLOAD with OVL_EXPORT_P in std::filesystem but not in
> std::filesystem::__cxx11.
>
> The tests currently FAIL:
> FAIL: g++.dg/plugin/std-module-exports-c++20.C -fplugin=./std_module_exports_plugin.so (test for excess errors)
> FAIL: g++.dg/plugin/std-module-exports-c++23.C -fplugin=./std_module_exports_plugin.so (test for excess errors)
> FAIL: g++.dg/plugin/std-module-exports-c++26.C -fplugin=./std_module_exports_plugin.so (test for excess errors)
> and the details are:
> sed -n '/^FAIL/,/^Executing on host/p' testsuite/g++/g++.log | grep 'FAIL\|error:.missing.using' | sed 's/^.*libstdc/libstdc/'
> FAIL: g++.dg/plugin/std-module-exports-c++20.C -fplugin=./std_module_exports_plugin.so (test for excess errors)
> libstdc++-v3/include/memory:159:3: error: missing using std::undeclare_reachable;
> libstdc++-v3/include/type_traits:2958:11: error: missing using std::result_of_t;
> libstdc++-v3/include/memory:167:1: error: missing using std::undeclare_no_pointers;
> libstdc++-v3/include/memory:171:1: error: missing using std::get_pointer_safety;
> libstdc++-v3/libsupc++/exception:101:40: error: missing using std::unexpected_handler;
> libstdc++-v3/include/type_traits:2725:12: error: missing using std::result_of;
> libstdc++-v3/include/memory:154:1: error: missing using std::declare_reachable;
> libstdc++-v3/include/memory:150:12: error: missing using std::pointer_safety;
> libstdc++-v3/include/memory:163:1: error: missing using std::declare_no_pointers;
> FAIL: g++.dg/plugin/std-module-exports-c++23.C -fplugin=./std_module_exports_plugin.so (test for excess errors)
> libstdc++-v3/include/type_traits:2958:11: error: missing using std::result_of_t;
> libstdc++-v3/include/bits/memoryfwd.h:86:12: error: missing using std::allocation_result;
> libstdc++-v3/include/bits/formatfwd.h:190:20: error: missing using std::enable_nonlocking_formatter_optimization;
> libstdc++-v3/include/type_traits:2725:12: error: missing using std::result_of;
> FAIL: g++.dg/plugin/std-module-exports-c++26.C -fplugin=./std_module_exports_plugin.so (test for excess errors)
> libstdc++-v3/include/type_traits:3566:25: error: missing using std::is_reflection_v;
> libstdc++-v3/include/type_traits:2958:11: error: missing using std::result_of_t;
> libstdc++-v3/include/type_traits:761:12: error: missing using std::is_reflection;
> libstdc++-v3/include/ranges:934:29: error: missing using std::ranges::views::indices;
> libstdc++-v3/include/bits/random.h:2346:29: error: missing using std::philox4x32;
> libstdc++-v3/include/bits/random.h:2353:45: error: missing using std::philox4x64;
> libstdc++-v3/include/bits/memoryfwd.h:86:12: error: missing using std::allocation_result;
> libstdc++-v3/include/bits/formatfwd.h:190:20: error: missing using std::enable_nonlocking_formatter_optimization;
> libstdc++-v3/include/type_traits:3923:27: error: missing using std::is_consteval_only_v;
> libstdc++-v3/include/bits/random.h:2059:11: error: missing using std::philox_engine;
> libstdc++-v3/include/type_traits:2725:12: error: missing using std::result_of;
> libstdc++-v3/include/type_traits:3914:12: error: missing using std::is_consteval_only;
>
> Now, for the C++20 (I know, bits/std.cc for C++20 is just an extension), all
> the reported names are C++23 zombie.names, but only
> {result_of{,_t},unexpected_handler} are C++20 zombie.names.
>
> So dunno what way you want to handle it, either the plugin can whitelist
> those for C++20, or we could export for C++20 only all but the 3 and
> deprecate the 3 for C++20+, or export for C++20 except for the 3 and
> whitelist in the plugin the 3.
>
> allocation_result has been added in PR118030 P0401 r16-7986 and I'll post a
> patch monetarily.
>
> enable_nonlocking_formatter_optimization has been added in PR121790 P3235R3
> r16-4351 and I have to wonder, though bits/formatfwd.h hunk already in
> PR121790 P3107R5 r16-4350. I wonder why it shows up for C++23 though.
P3235R3 was approved as a DR for C++23, at the 2024-06 meeting:
"8. Accept as a Defect Report and apply the changes in P3235R3
(std::print more types faster with less memory) to the C++ working
paper. "
The committee kept approving a LOT of std::format and std::print changes as DRs.
So it's enabled in the header for C++23, and so it should also be
exported from the module for C++23.
I'm not sure what we want to do about result_of and result_of_t. On
the one hand, it's not part of C++23 so should not exported from the
module. On the other hand, we do provide it in the headers for C++23,
as an extension. If users are relying on using it in C++23, they won't
be able to migrate to importing the std module until they stop using
it. Maybe that's OK, because there's a replacement
(std::invoke_result) and migrating to use modules will require code
changes anyway.
More information about the Libstdc++
mailing list