On 8/28/23 09:58, Jakub Jelinek wrote:
Hi!
On Thu, Aug 24, 2023 at 06:39:10PM +0200, Jakub Jelinek via Gcc-patches wrote:
Maybe do this in mangle_decomp, based on the actual mangling in process
instead of this pseudo-mangling?
Not sure that is possible, for 2 reasons:
1) determine_local_discriminator otherwise works on DECL_NAME, not mangled
names, so if one uses (albeit implementation reserved)
_ZZN1N3fooI1TB3bazEEivEDC1h1iEB6foobar and similar identifiers, they
could clash with the counting of the structured bindings
I guess, but those names are reserved so that we don't need to worry
about that.
2) seems the local discriminator counting shouldn't take into account
details like abi tags, e.g. if I have:
Right, you'd need to use the partial mangled name before the ABI tags,
e.g. with get_identifier_with_length (obstack_base, obstack_object_size).
But the way you have it is fine too.
The following updated patch handles everything except it leaves for the
above 2 reasons the determination of local discriminator where it was.
I had to add a new (defaulted) argument to cp_finish_decl and do
cp_maybe_mangle_decomp from there, so that it is after e.g. auto type
deduction and maybe_commonize_var (which had to be changed as well) and
spots in cp_finish_decl where we need or might need mangled names already.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
There is one difference between g++ with this patch and clang++,
g++ uses
_ZZ3barI1TB3quxEivEDC1o1pEB3qux
while clang++ uses
_ZZ3barI1TB3quxEivEDC1o1pE
but from what I can see, such a difference is there also when just using
normal local decls:
struct [[gnu::abi_tag ("foobar")]] S { int i; };
struct [[gnu::abi_tag ("qux")]] T { int i; S j; int k; };
inline int
foo ()
{
static S c;
static T d;
return ++c.i + ++d.i;
}
template <typename T>
inline int
bar ()
{
static S c;
static T d;
return ++c.i + ++d.i;
}
int (*p) () = &foo;
int (*q) () = &bar<T>;
where both compilers mangle c in foo as:
_ZZ3foovE1cB6foobar
and d in there as
_ZZ3foovE1dB3qux
and similarly both compilers mangle c in bar as
_ZZ3barI1TB3quxEivE1cB6foobar
but g++ mangles d in bar as
_ZZ3barI1TB3quxEivE1dB3qux
while clang++ mangles it as just
_ZZ3barI1TB3quxEivE1d
No idea what is right or wrong according to Itanium mangling.
I think g++ is right.
This has to do with the ABI "If part of a declaration's type is not
represented in the mangling, i.e. the type of a variable or a return
type that is not represented in the mangling of a function, any ABI tags
on that type (or components of a compound type) that are not also
present in a mangled part of the type are applied to the name of the
declaration."
Here the type of bar::d is not mangled, so the tags of T are applied to
the name d.
I guess clang interpreted the above as "any ABI tags on that type that
are not already present in the mangled name...", which would also be a
reasonable rule but is not the actual rule in the ABI.
2023-08-28 Jakub Jelinek <ja...@redhat.com>
PR c++/111069
gcc/
* common.opt (fabi-version=): Document version 19.
* doc/invoke.texi (-fabi-version=): Likewise.
gcc/c-family/
* c-opts.cc (c_common_post_options): Change latest_abi_version to 19.
gcc/cp/
* cp-tree.h (determine_local_discriminator): Add NAME argument with
NULL_TREE default.
(struct cp_decomp): New type.
Maybe cp_finish_decomp should take this as well? And
tsubst_decomp_names, and various other functions with
decomp_first_name/decomp_cnt parms?
+ if (tree tags = get_abi_tags (decl))
+ {
+ /* We didn't emit ABI tags for structured bindings before ABI 19. */
+ if (!G.need_abi_warning
+ && abi_warn_or_compat_version_crosses (19))
+ G.need_abi_warning = 1;
In general we should probably only warn about mangling changes if
TREE_PUBLIC (decl).
Jason