c++: mangle contracts in write_mangled_name
authorArsen Arsenović <arsen@aarsen.me>
Thu, 15 Dec 2022 17:56:59 +0000 (18:56 +0100)
committerJason Merrill <jason@redhat.com>
Thu, 15 Dec 2022 21:48:00 +0000 (16:48 -0500)
This fixes contract-checked extern "C" functions.

gcc/cp/ChangeLog:

* mangle.cc (write_encoding): Move contract pre/post function
mangling from here...
(write_mangled_name): ... to here, and make it happen always.

gcc/testsuite/ChangeLog:

* g++.dg/contracts/contracts-externC.C: New test.

gcc/cp/mangle.cc
gcc/testsuite/g++.dg/contracts/contracts-externC.C [new file with mode: 0644]

index e363ef3..074cf27 100644 (file)
@@ -798,6 +798,13 @@ write_mangled_name (const tree decl, bool top_level)
       write_string ("_Z");
       write_encoding (decl);
     }
+
+  /* If this is the pre/post function for a guarded function, append
+     .pre/post, like something from create_virtual_clone.  */
+  if (DECL_IS_PRE_FN_P (decl))
+    write_string (".pre");
+  else if (DECL_IS_POST_FN_P (decl))
+    write_string (".post");
 }
 
 /* Returns true if the return type of DECL is part of its signature, and
@@ -856,13 +863,6 @@ write_encoding (const tree decl)
                                mangle_return_type_p (decl),
                                d);
 
-      /* If this is the pre/post function for a guarded function, append
-        .pre/post, like something from create_virtual_clone.  */
-      if (DECL_IS_PRE_FN_P (decl))
-       write_string (".pre");
-      else if (DECL_IS_POST_FN_P (decl))
-       write_string (".post");
-
       /* If this is a coroutine helper, then append an appropriate string to
         identify which.  */
       if (tree ramp = DECL_RAMP_FN (decl))
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-externC.C b/gcc/testsuite/g++.dg/contracts/contracts-externC.C
new file mode 100644 (file)
index 0000000..873056b
--- /dev/null
@@ -0,0 +1,19 @@
+// simple check to ensure we don't emit a function with the same name twice,
+// when wrapping functions in pre- and postconditions.
+// { dg-do link }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+volatile int x = 10;
+
+extern "C" void
+f ()
+  [[ pre: x < 10 ]]
+{
+}
+
+int
+main ()
+  [[ post: x > 10 ]]
+{
+  f();
+}