Hi Arsen,

> On 15 Dec 2022, at 18:00, Arsen Arsenović via Gcc-patches 
> <gcc-patches@gcc.gnu.org> wrote:

> Jason Merrill <ja...@redhat.com> writes:
> 
>> 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.
> 
> Ah, sorry.  I'm not well versed in the mangler code, so I didn't realize
> (frankly, I was initially surprised when I saw that DECL_ASSEMBLER_NAME
> was set that early, but went with it).  That makes sense.
> 
> How about this?  Tested on x86_64-pc-linux-gnu via check-g++.
> 
> From 2a2d98e94bdd7a8d7f862b2accda849927e4509e Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Arsen=20Arsenovi=C4=87?= <ar...@aarsen.me>
> Date: Thu, 15 Dec 2022 18:56:59 +0100
> Subject: [PATCH v2] c++: Mangle contracts in write_mangled_name
> unconditionally
> 
> 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                              | 14 +++++++-------
> .../g++.dg/contracts/contracts-externC.C      | 19 +++++++++++++++++++
> 2 files changed, 26 insertions(+), 7 deletions(-)
> create mode 100644 gcc/testsuite/g++.dg/contracts/contracts-externC.C
> 
> diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
> index e363ef35b9f..074cf27ec7a 100644
> --- a/gcc/cp/mangle.cc
> +++ b/gcc/cp/mangle.cc
> @@ -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");
> }

I think you want to use 'write_string (JOIN_STR “pre”);’ etc. since that 
handles targets
that cannot use a period in symbol names.

> 
> /* 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
> 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();
> +}
> -- 
> 2.39.0
> 
> 
> I did run c++filt (afaik, it uses the libiberty demangler) on this
> revision, and I got:
> 
>          .type        f(int) [clone .pre], @function
>  f(int) [clone .pre]:
> 
> out of ``void f(int x) [[ pre: x > 10 ]] {}'', which seems to match your
> description.
> 
> If I understand this right, write_xxx corresponds to xxx in the Itanium
> ABI mangling BNF, in which case, I believe I have the correct spot here.
> In that case, a similar change should happen for coroutines; I think
> Iain was working on that.

If this is the right place, then I can update my patch for coroutines - both
Gor and Lewis replied that ‘extern “C”’ coroutines seemed reasonable to
them.

Iain

Reply via email to