diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc index 39f0487ea36..4d2849a289a 100644 --- a/gcc/cp/contracts.cc +++ b/gcc/cp/contracts.cc @@ -145,6 +145,7 @@ along with GCC; see the file COPYING3. If not see #include "print-tree.h" #include "stor-layout.h" #include "intl.h" +#include "cgraph.h" const int max_custom_roles = 32; static contract_role contract_build_roles[max_custom_roles] = { @@ -1458,9 +1459,14 @@ build_contract_condition_function (tree fndecl, bool pre) DECL_WEAK (fn) = false; DECL_COMDAT (fn) = false; - /* We haven't set the comdat group on the guarded function yet, we'll add - this to the same group in comdat_linkage later. */ - gcc_assert (!DECL_ONE_ONLY (fndecl)); + /* We may not have set the comdat group on the guarded function yet. + If we haven't, we'll add this to the same group in comdat_linkage + later. Otherwise, add it to the same comdat group now. */ + if (DECL_ONE_ONLY (fndecl)) + { + symtab_node *n = symtab_node::get (fndecl); + cgraph_node::get_create (fn)->add_to_same_comdat_group (n); + } DECL_INTERFACE_KNOWN (fn) = true; } diff --git a/gcc/testsuite/g++.dg/contracts/pr116490.C b/gcc/testsuite/g++.dg/contracts/pr116490.C new file mode 100644 index 00000000000..e3a5d77bafd --- /dev/null +++ b/gcc/testsuite/g++.dg/contracts/pr116490.C @@ -0,0 +1,56 @@ +// ICE in explicit instantiation of a function with contracts +// { dg-do run } +// { dg-options "-std=c++20 -fcontracts -fcontract-continuation-mode=on" } + +template +void foo(T t) +[[pre : t == 9 ]] { +} + +template void foo(int i); + + +template +struct templateS +{ + void fooS(T t) + [[pre : t == 9 ]] { + } +}; + +template struct templateS; + + +struct S { + + template + void fooS(T t) + [[pre : t == 9 ]] { + } + + template + static void fooStatic(T t) + [[pre : t == 9 ]] { + } +}; + +template void S::fooS(int i); + +template void S::fooStatic(int i); + +int main() +{ + foo(3); + + templateS ts; + ts.fooS(3); + + S s; + s.fooS(3); + S::fooStatic(3); +} + +// { dg-output "contract violation in function foo at .* t == 9.*(\n|\r\n|\r)" } +// { dg-output "contract violation in function templateS::fooS at .* t == 9.*(\n|\r\n|\r)" } +// { dg-output "contract violation in function S::fooS at .* t == 9.*(\n|\r\n|\r)" } +// { dg-output "contract violation in function S::fooStatic at .* t == 9.*(\n|\r\n|\r)" }