On 28/11/18 14:46 +0100, Richard Biener wrote:
On Wed, Nov 28, 2018 at 1:30 PM Jonathan Wakely <jwak...@redhat.com> wrote:
On 28/11/18 11:11 +0000, Jonathan Wakely wrote:
>On 28/11/18 11:46 +0100, Richard Biener wrote:
>>On Wed, Nov 28, 2018 at 12:26 AM Jonathan Wakely <jwak...@redhat.com> wrote:
>>>
>>>This resolves a longstanding issue where the lock policy for shared_ptr
>>>reference counting depends on compilation options when the header is
>>>included, so that different -march options can cause ABI changes. For
>>>example, objects compiled with -march=armv7 will use atomics to
>>>synchronize reference counts, and objects compiled with -march=armv5t
>>>will use a mutex. That means the shared_ptr control block will have a
>>>different layout in different objects, causing ODR violations and
>>>undefined behaviour. This was the root cause of PR libstdc++/42734 as
>>>well as PR libstdc++/67843.
>>>
>>>The solution is to decide on the lock policy at build time, when
>>>libstdc++ is configured. The configure script checks for the
>>>availability of the necessary atomic built-ins for the target and fixes
>>>that choice permanently. Different -march flags used to compile user
>>>code will not cause changes to the lock policy. This results in an ABI
>>>change for certain compilations, but only where there was already an ABI
>>>incompatibility between the libstdc++.so library and objects built with
>>>an incompatible -march option. In general, this means a more stable ABI
>>>that isn't silently altered when -march flags make addition atomic ops
>>>available.
>>>
>>>To force a target to use "atomic" or "mutex" the new configure option
>>>--with-libstdcxx-lock-policy can be used.
>>>
>>>In order to turn ODR violations into linker errors, the uses of
>>>shared_ptr in filesystem directory iterators have been replaced
>>>with __shared_ptr, and explicit instantiations are declared. This
>>>ensures that object files using those types cannot link to libstdc++
>>>libs unless they use the same lock policy.
>>
>>Would it be possible to have both in libstdc++ and with differnet mangling of
>>different kind ensure compatibility between different user CUs? Or is
>>that too awkward for the user to get right?
>
>It would mean duplicating a lot more code, which is already duplicated
>once for the std::string ABI, so we'd have four permuations!
>
>It still wouldn't ensure compatibility between different user CUs,
>only between any user CU and any build of libstdc++. Different user
>CUs would still disagree on the ABI of the types, and so couldn't pass
>them between CUs. I see no advantage to supporting that for the
>std::filesystem library (unlike std::string and std::iostream, which
>are probably used in the majority of CUs).
>
>I do not want to get to the point where every type in libstdc++ exists
>multiple times and you select some combination via command-line flags.
>It's already becoming unmanageable with multiple std::string and long
>double ABIs.
Also, in practice, I don't see a need. The common cases where this bug
arises are limited to 32-bit ARM, and for arm-linux the kernel helpers
mean that you can always use "atomic". For bare metal ARM toolchains
you probably don't want to be mixing CUs built against different
versions of libstdc++ anyway. You have your toolchain for the board,
and you use that. If it is configured to use "atomic", then that's
what you get. If it's configured to use "mutex", then that's what you
get. You probably don't want to use a toolchain configured for a
different board, but you could use --with-libstdcxx-lock-policy to
ensure a consistent policy across those toolchains if needed.
It's also possible for problems to arise on i386. If you build GCC for
i386 then it will choose "mutex" and be incompatible with a libstdc++
built for i486 or later. In that case, you could use the option
--with-libstdcxx-lock-policy=atomic to force the use of "atomic" (and
then you'd need to link to libatomic to provide the ops, as there are
no kernel helpers for i386 in libgcc).
I think the default should be part of the platform ABI somehow,
like the i386 incompatibility should better not arise.
What do you suggest to ensure that?
Just imake i386 default to the "atomic" lock policy, and require anybody
silly enough to configure for i386 to either link to libatomic, or
explicitly use --with-libstdcxx-lock-policy=mutex if they really want
to be incompatible with default i486 builds?
I suppose
libstdc++ configury doesn't read in gcc/config.gcc but does it
have sth similar where it's easy to see defaults for plaforms?
There's configure.host but I'm not sure this is related at all.
No, I don't think we do. When there are target-specific things
hardcoded it's spread out around acinclude.m4 and configure.ac