[PATCH v2] libgcc, libstdc++: Make TU-local declarations in headers external linkage [PR115126]
Jason Merrill
jason@redhat.com
Fri Sep 27 18:45:52 GMT 2024
On 9/26/24 6:34 AM, Nathaniel Shead wrote:
> On Thu, Sep 26, 2024 at 01:46:27PM +1000, Nathaniel Shead wrote:
>> On Wed, Sep 25, 2024 at 01:30:55PM +0200, Jakub Jelinek wrote:
>>> On Wed, Sep 25, 2024 at 12:18:07PM +0100, Jonathan Wakely wrote:
>>>>>> And whether similarly we couldn't use
>>>>>> __attribute__((__visibility__ ("hidden"))) on the static block scope
>>>>>> vars for C++ (again, if compiler supports that), so that the changes
>>>>>> don't affect ABI of C++ libraries.
>>>>>
>>>>> That sounds good too.
>>>>
>>>> Can you use visibility attributes on a local static? I get a warning
>>>> that it's ignored.
>>>
>>> Indeed :(
>>>
>>> And #pragma GCC visibility push(hidden)/#pragma GCC visibility pop around
>>> just the static block scope var definition does nothing.
>>> If it is around the whole inline function though, then it seems to work.
>>> Though, unsure if we want that around the whole header; wonder what it would
>>> do with the weakrefs.
>>>
>>> Jakub
>>>
>>
>> Thanks for the thoughts. WRT visibility, it looks like the main gthr.h
>> surrounds the whole function in a
>>
>> #ifndef HIDE_EXPORTS
>> #pragma GCC visibility push(default)
>> #endif
>>
>> block, though I can't quite work out what the purpose of that is here
>> (since everything is currently internal linkage to start with).
>>
>> But it sounds like doing something like
>>
>> #ifdef __has_attribute
>> # if __has_attribute(__always_inline__)
>> # define __GTHREAD_ALWAYS_INLINE __attribute__((__always_inline__))
>> # endif
>> #endif
>> #ifndef __GTHREAD_ALWAYS_INLINE
>> # define __GTHREAD_ALWAYS_INLINE
>> #endif
>>
>> #ifdef __cplusplus
>> # define __GTHREAD_INLINE inline __GTHREAD_ALWAYS_INLINE
>> #else
>> # define __GTHREAD_INLINE static inline
>> #endif
>>
>> and then marking maybe even just the new inline functions with
>> visibility hidden should be OK?
>>
>> Nathaniel
>
> Here's a new patch that does this. Also since v1 it adds another two
> internal linkage declarations I'd missed earlier from libstdc++, in
> pstl; it turns out that <bits/stdc++.h> doesn't include <execution>.
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu and
> aarch64-unknown-linux-gnu, OK for trunk?
>
> -- >8 --
>
> In C++20, modules streaming check for exposures of TU-local entities.
> In general exposing internal linkage functions in a header is liable to
> cause ODR violations in C++, and this is now detected in a module
> context.
>
> This patch goes through and removes 'static' from many declarations
> exposed through libstdc++ to prevent code like the following from
> failing:
>
> export module M;
> extern "C++" {
> #include <bits/stdc++.h>
> }
>
> Since gthreads is used from C as well, we need to choose whether to use
> 'inline' or 'static inline' depending on whether we're compiling for C
> or C++ (since the semantics of 'inline' are different between the
> languages). Additionally we need to remove static global variables, so
> we migrate these to function-local statics to avoid the ODR issues.
Why function-local static rather than inline variable?
> +++ b/libstdc++-v3/include/pstl/algorithm_impl.h
> @@ -2890,7 +2890,7 @@ __pattern_includes(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _
> });
> }
>
> -constexpr auto __set_algo_cut_off = 1000;
> +inline constexpr auto __set_algo_cut_off = 1000;
>
> +++ b/libstdc++-v3/include/pstl/unseq_backend_simd.h
> @@ -22,7 +22,7 @@ namespace __unseq_backend
> {
>
> // Expect vector width up to 64 (or 512 bit)
> -const std::size_t __lane_size = 64;
> +inline const std::size_t __lane_size = 64;
These changes should not be necessary; the uses of these variables are
not exposures under https://eel.is/c++draft/basic#link-14.4
Jason
More information about the Libstdc++
mailing list