On 12/10/22 08:13, Arsen Arsenović wrote:
If the mangler is relied on, functions with extern "C" on them emit multiple
definitions of the same name.
But doing it here interferes with lazy mangling. How about appending
the suffix into write_mangled_name instead of write_encoding? The
demangler already expects "clone" suffixes at the end of the mangled name.
gcc/cp/ChangeLog:
* contracts.cc (build_contract_condition_function): Add pre/post
suffixes to pre- and postcondition clones.
* mangle.cc (write_encoding): Don't mangle pre- and postconditions.
gcc/testsuite/ChangeLog:
* g++.dg/contracts/contracts-externC.C: New test.
---
Afternoon,
This change prevents contracts from emitting wrapper functions that have the
same name as the original function, by moving the logic that disambiguates them
from the mangler into the build_contract_condition_function helper.
Thanks, have nice day.
gcc/cp/contracts.cc | 3 +++
gcc/cp/mangle.cc | 7 -------
.../g++.dg/contracts/contracts-externC.C | 19 +++++++++++++++++++
3 files changed, 22 insertions(+), 7 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/contracts/contracts-externC.C
diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc
index 26316372389..f09eb87e283 100644
--- a/gcc/cp/contracts.cc
+++ b/gcc/cp/contracts.cc
@@ -161,6 +161,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "print-tree.h"
#include "stor-layout.h"
+#include "cgraph.h"
const int max_custom_roles = 32;
static contract_role contract_build_roles[max_custom_roles] = {
@@ -1451,6 +1452,8 @@ build_contract_condition_function (tree fndecl, bool pre)
TREE_TYPE (fn) = build_method_type (class_type, TREE_TYPE (fn));
DECL_NAME (fn) = copy_node (DECL_NAME (fn));
+ auto suffix = pre ? "pre" : "post";
+ SET_DECL_ASSEMBLER_NAME (fn, clone_function_name (fn, suffix));
DECL_INITIAL (fn) = error_mark_node;
DECL_ABSTRACT_ORIGIN (fn) = fndecl;
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index e363ef35b9f..e97428e8f30 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -856,13 +856,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
index 00000000000..873056b742b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-externC.C
@@ -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();
+}