cat > mod.h <<EOT #ifndef MOD_H #define MOD_H template<typename T> concept rhubarb = true; template<typename T> constexpr bool nothrow = true; void donkey(rhubarb auto i) noexcept(nothrow<decltype(i)>) { } #endif EOT cat > mod.H <<EOT #include "mod.h" EOT cat > mod.C <<EOT #include "mod.h" import "mod.H"; int main() { donkey(1); } EOT g++ -std=c++20 -fmodule-header mod.H -c g++ -std=c++20 -fmodules-ts mod.C This gives a bogus error: In file included from mod.H:1, of module ./mod.H, imported at mod.C:2: mod.h: In function ‘int main()’: mod.h:5:6: error: conflicting global module declaration ‘template<class auto:1> void donkey(auto:1)’ 5 | void donkey(rhubarb auto i) noexcept(nothrow<decltype(i)>) { } | ^~~~~~ In file included from mod.C:1: mod.h:5:6: note: existing declaration ‘template<class auto:1> requires rhubarb<auto:1> void donkey(auto:1)’ 5 | void donkey(rhubarb auto i) noexcept(nothrow<decltype(i)>) { } | ^~~~~~ mod.C:6:3: note: during load of binding ‘::donkey’ 6 | donkey(1); | ^~~~~~ The code compiles OK if the noexcept-specifier doesn't refer to the auto:1 type.
This causes: FAIL: g++.dg/modules/xtreme-header-2_b.C -std=c++2a (test for excess errors) FAIL: g++.dg/modules/xtreme-header-2_b.C -std=c++2b (test for excess errors) FAIL: g++.dg/modules/xtreme-tr1_b.C -std=c++2a (test for excess errors) FAIL: g++.dg/modules/xtreme-tr1_b.C -std=c++2b (test for excess errors)
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:0b7a11874d4eb428c18a91f38786032ce0e77a96 commit r12-2313-g0b7a11874d4eb428c18a91f38786032ce0e77a96 Author: Jason Merrill <jason@redhat.com> Date: Wed Jul 14 17:10:49 2021 -0400 c++: fix tree_contains_struct for C++ types [PR101095] Many of the types from cp-tree.def were only marked as having tree_common, when actually most of them have type_non_common. This broke g++.dg/modules/xtreme-header-2, as the modules code relies on tree_contains_struct to know what bits it needs to stream. We don't seem to use type_non_common for TYPE_ARGUMENT_PACK, so I bumped it down to TS_TYPE_COMMON. I tried doing the same in cp_tree_size, but that breaks without more extensive changes to tree_node_structure. Why do we need the init_ts function anyway? It seems redundant with tree_node_structure. PR c++/101095 gcc/cp/ChangeLog: * cp-objcp-common.c (cp_common_init_ts): Mark types as types. (cp_tree_size): Remove redundant entries.
The releases/gcc-11 branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:0a63e3ee2d5c9aa0e51aa1eb54c3d14c06418ac3 commit r11-9680-g0a63e3ee2d5c9aa0e51aa1eb54c3d14c06418ac3 Author: Jason Merrill <jason@redhat.com> Date: Wed Jul 14 17:10:49 2021 -0400 c++: fix tree_contains_struct for C++ types [PR101095] Many of the types from cp-tree.def were only marked as having tree_common, when actually most of them have type_non_common. This broke g++.dg/modules/xtreme-header-2, as the modules code relies on tree_contains_struct to know what bits it needs to stream. We don't seem to use type_non_common for TYPE_ARGUMENT_PACK, so I bumped it down to TS_TYPE_COMMON. I tried doing the same in cp_tree_size, but that breaks without more extensive changes to tree_node_structure. Why do we need the init_ts function anyway? It seems redundant with tree_node_structure. PR c++/101095 gcc/cp/ChangeLog: * cp-objcp-common.c (cp_common_init_ts): Mark types as types. (cp_tree_size): Remove redundant entries.
Fixed for GCC 11.3+ I suppose