#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] = {
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;
}
--- /dev/null
+// ICE in explicit instantiation of a function with contracts
+// { dg-do run }
+// { dg-options "-std=c++20 -fcontracts -fcontract-continuation-mode=on" }
+
+template<class T>
+void foo(T t)
+[[pre : t == 9 ]] {
+}
+
+template void foo<int>(int i);
+
+
+template<class T>
+struct templateS
+{
+ void fooS(T t)
+ [[pre : t == 9 ]] {
+ }
+};
+
+template struct templateS<int>;
+
+
+struct S {
+
+ template<class T>
+ void fooS(T t)
+ [[pre : t == 9 ]] {
+ }
+
+ template<class T>
+ static void fooStatic(T t)
+ [[pre : t == 9 ]] {
+ }
+};
+
+template void S::fooS<int>(int i);
+
+template void S::fooStatic<int>(int i);
+
+int main()
+{
+ foo(3);
+
+ templateS<int> ts;
+ ts.fooS(3);
+
+ S s;
+ s.fooS(3);
+ S::fooStatic(3);
+}
+
+// { dg-output "contract violation in function foo<int> at .* t == 9.*(\n|\r\n|\r)" }
+// { dg-output "contract violation in function templateS<int>::fooS at .* t == 9.*(\n|\r\n|\r)" }
+// { dg-output "contract violation in function S::fooS<int> at .* t == 9.*(\n|\r\n|\r)" }
+// { dg-output "contract violation in function S::fooStatic<int> at .* t == 9.*(\n|\r\n|\r)" }