* [PATCH] Fix ODR violations in code using <ext/atomicity.h>
@ 2019-06-21 16:01 Jonathan Wakely
2019-06-21 17:01 ` Nathan Sidwell
0 siblings, 1 reply; 8+ messages in thread
From: Jonathan Wakely @ 2019-06-21 16:01 UTC (permalink / raw)
To: libstdc++, gcc-patches; +Cc: Nathan Sidwell
[-- Attachment #1: Type: text/plain, Size: 5650 bytes --]
Nathan noticed that the 'static inline' functions in <ext/atomicity.h>
cause ODR violations when used from inline functions or templates (see
[basic.def.odr] p12 bullet (12.2)). His modules branch now diagnoses
those violations, so we need a fix.
Looking at the history (r114044 by Paolo) I believe the idea was indeed
to allow different definitions to be used in different TUs. I think
__attribute__((__always_inline__)) is a better match for that than
'static inline', and doesn't violate the ODR (at least, not if all TUs
have the same values for __GTHREADS and _GLIBCXX_ATOMIC_BUILTINS).
These functions still violate this rule in [dcl.inline]:
C++17: "If a function with external linkage is declared inline in one
translation unit, it shall be declared inline in all translation units
in which it appears; no diagnostic is required."
C++2a WP: "If a function or variable with external or module linkage
is declared inline in one translation unit, there shall be a reachable
inline declaration in all translation units in which it is declared;
no diagnostic is required."
But that doesn't seem to be diagnosable by today's implementations.
Does this change seem reasonable?
It does change the size of a few files, e.g. for x86_64 some are
bigger and some are smaller, overall slightly smaller:
text data bss dec hex filename
5400 8 352 5760 1680 src/c++11/cow-locale_init.o
5402 8 352 5762 1682 src/c++11/cow-locale_init.o [always_inline]
22772 2056 0 24828 60fc src/c++11/cow-shim_facets.o
22710 2056 0 24766 60be src/c++11/cow-shim_facets.o [always_inline]
49458 2184 0 51642 c9ba src/c++11/cow-sstream-inst.o
49482 2184 0 51666 c9d2 src/c++11/cow-sstream-inst.o [always_inline]
7461 8 0 7469 1d2d src/c++11/cow-stdexcept.o
7464 8 0 7472 1d30 src/c++11/cow-stdexcept.o [always_inline]
16753 8 32 16793 4199 src/c++11/cow-string-inst.o
16756 8 32 16796 419c src/c++11/cow-string-inst.o [always_inline]
17009 8 32 17049 4299 src/c++11/cow-wstring-inst.o
17008 8 32 17048 4298 src/c++11/cow-wstring-inst.o [always_inline]
20342 2072 0 22414 578e src/c++11/cxx11-shim_facets.o
20276 2072 0 22348 574c src/c++11/cxx11-shim_facets.o [always_inline]
2929 240 8 3177 c69 src/c++11/future.o
2945 240 8 3193 c79 src/c++11/future.o [always_inline]
6789 120 0 6909 1afd src/c++11/ios-inst.o
6750 120 0 6870 1ad6 src/c++11/ios-inst.o [always_inline]
2364 57 8 2429 97d src/c++11/ios.o
2362 57 8 2427 97b src/c++11/ios.o [always_inline]
94493 2712 192 97397 17c75 src/c++11/locale-inst.o
94498 2712 192 97402 17c7a src/c++11/locale-inst.o [always_inline]
93094 2712 192 95998 176fe src/c++11/wlocale-inst.o
93113 2712 192 96017 17711 src/c++11/wlocale-inst.o [always_inline]
20189 208 0 20397 4fad src/c++17/cow-fs_dir.o
20118 208 0 20326 4f66 src/c++17/cow-fs_dir.o [always_inline]
55077 8 0 55085 d72d src/c++17/cow-fs_ops.o
55103 8 0 55111 d747 src/c++17/cow-fs_ops.o [always_inline]
40200 304 0 40504 9e38 src/c++17/cow-fs_path.o
40204 304 0 40508 9e3c src/c++17/cow-fs_path.o [always_inline]
18672 208 0 18880 49c0 src/c++17/fs_dir.o
18628 208 0 18836 4994 src/c++17/fs_dir.o [always_inline]
60604 160 0 60764 ed5c src/c++17/fs_ops.o
60606 160 0 60766 ed5e src/c++17/fs_ops.o [always_inline]
39568 304 0 39872 9bc0 src/c++17/fs_path.o
39561 304 0 39865 9bb9 src/c++17/fs_path.o [always_inline]
3653 8 0 3661 e4d src/c++98/ios_init.o
3656 8 0 3664 e50 src/c++98/ios_init.o [always_inline]
6878 184 84 7146 1bea src/c++98/locale.o
6896 184 84 7164 1bfc src/c++98/locale.o [always_inline]
6693 768 5368 12829 321d src/c++98/locale_init.o
6710 768 5368 12846 322e src/c++98/locale_init.o [always_inline]
7222 8 0 7230 1c3e src/c++98/localename.o
7223 8 0 7231 1c3f src/c++98/localename.o [always_inline]
4036 144 208 4388 1124 src/c++98/pool_allocator.o
4044 144 208 4396 112c src/c++98/pool_allocator.o [always_inline]
1955 584 0 2539 9eb src/c++98/stdexcept.o
1957 584 0 2541 9ed src/c++98/stdexcept.o [always_inline]
25199 208 0 25407 633f src/filesystem/cow-dir.o
25248 208 0 25456 6370 src/filesystem/cow-dir.o [always_inline]
71134 8 0 71142 115e6 src/filesystem/cow-ops.o
71146 8 0 71154 115f2 src/filesystem/cow-ops.o [always_inline]
21995 184 0 22179 56a3 src/filesystem/cow-path.o
22013 184 0 22197 56b5 src/filesystem/cow-path.o [always_inline]
23708 208 0 23916 5d6c src/filesystem/dir.o
23690 208 0 23898 5d5a src/filesystem/dir.o [always_inline]
70268 160 0 70428 1131c src/filesystem/ops.o
70233 160 0 70393 112f9 src/filesystem/ops.o [always_inline]
815915 15841 6476 838232 cca58 TOTAL
815802 15841 6476 838119 cc9e7 TOTAL [always_inline]
[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 2519 bytes --]
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index ac98c0d02e7..ace1c8b565e 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2019-06-21 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/ext/atomicity.h [_GLIBCXX_ATOMIC_BUILTINS] (__atomic_add)
+ (__exchange_and_add): Replace 'static' specifier with always_inline
+ attribute.
+ (__exchange_and_add_single, __atomic_add_single)
+ (__exchange_and_add_dispatch, __atomic_add_dispatch): Likewise.
+
2019-06-20 Jonathan Wakely <jwakely@redhat.com>
* acinclude.m4 (GLIBCXX_ENABLE_DEBUG): Only do debug build for final
diff --git a/libstdc++-v3/include/ext/atomicity.h b/libstdc++-v3/include/ext/atomicity.h
index 0783a58e01a..5cee388854b 100644
--- a/libstdc++-v3/include/ext/atomicity.h
+++ b/libstdc++-v3/include/ext/atomicity.h
@@ -44,24 +44,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// __exchange_and_add_dispatch
// __atomic_add_dispatch
#ifdef _GLIBCXX_ATOMIC_BUILTINS
- static inline _Atomic_word
+ inline _Atomic_word
+ __attribute__((__always_inline__))
__exchange_and_add(volatile _Atomic_word* __mem, int __val)
{ return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
- static inline void
+ inline void
+ __attribute__((__always_inline__))
__atomic_add(volatile _Atomic_word* __mem, int __val)
{ __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
#else
_Atomic_word
- __attribute__ ((__unused__))
__exchange_and_add(volatile _Atomic_word*, int) throw ();
void
- __attribute__ ((__unused__))
__atomic_add(volatile _Atomic_word*, int) throw ();
#endif
- static inline _Atomic_word
+ inline _Atomic_word
+ __attribute__((__always_inline__))
__exchange_and_add_single(_Atomic_word* __mem, int __val)
{
_Atomic_word __result = *__mem;
@@ -69,12 +70,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __result;
}
- static inline void
+ inline void
+ __attribute__((__always_inline__))
__atomic_add_single(_Atomic_word* __mem, int __val)
{ *__mem += __val; }
- static inline _Atomic_word
- __attribute__ ((__unused__))
+ inline _Atomic_word
+ __attribute__ ((__always_inline__))
__exchange_and_add_dispatch(_Atomic_word* __mem, int __val)
{
#ifdef __GTHREADS
@@ -87,8 +89,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
}
- static inline void
- __attribute__ ((__unused__))
+ inline void
+ __attribute__ ((__always_inline__))
__atomic_add_dispatch(_Atomic_word* __mem, int __val)
{
#ifdef __GTHREADS
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix ODR violations in code using <ext/atomicity.h>
2019-06-21 16:01 [PATCH] Fix ODR violations in code using <ext/atomicity.h> Jonathan Wakely
@ 2019-06-21 17:01 ` Nathan Sidwell
2019-06-21 17:08 ` Jonathan Wakely
0 siblings, 1 reply; 8+ messages in thread
From: Nathan Sidwell @ 2019-06-21 17:01 UTC (permalink / raw)
To: Jonathan Wakely, libstdc++, gcc-patches
On 6/21/19 12:01 PM, Jonathan Wakely wrote:
> Nathan noticed that the 'static inline' functions in <ext/atomicity.h>
> cause ODR violations when used from inline functions or templates (see
> [basic.def.odr] p12 bullet (12.2)). His modules branch now diagnoses
> those violations, so we need a fix.
>
> Looking at the history (r114044 by Paolo) I believe the idea was indeed
> to allow different definitions to be used in different TUs. I think
> __attribute__((__always_inline__)) is a better match for that than
> 'static inline', and doesn't violate the ODR (at least, not if all TUs
> have the same values for __GTHREADS and _GLIBCXX_ATOMIC_BUILTINS).
>
> These functions still violate this rule in [dcl.inline]:
>
> C++17: "If a function with external linkage is declared inline in one
> translation unit, it shall be declared inline in all translation units
> in which it appears; no diagnostic is required."
>
> C++2a WP: "If a function or variable with external or module linkage
> is declared inline in one translation unit, there shall be a reachable
> inline declaration in all translation units in which it is declared;
> no diagnostic is required."
>
> But that doesn't seem to be diagnosable by today's implementations.
>
> Does this change seem reasonable?
yes, thanks!
nathan
--
Nathan Sidwell
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix ODR violations in code using <ext/atomicity.h>
2019-06-21 17:01 ` Nathan Sidwell
@ 2019-06-21 17:08 ` Jonathan Wakely
2019-06-21 17:13 ` Jonathan Wakely
0 siblings, 1 reply; 8+ messages in thread
From: Jonathan Wakely @ 2019-06-21 17:08 UTC (permalink / raw)
To: Nathan Sidwell; +Cc: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1632 bytes --]
On 21/06/19 13:01 -0400, Nathan Sidwell wrote:
>On 6/21/19 12:01 PM, Jonathan Wakely wrote:
>>Nathan noticed that the 'static inline' functions in <ext/atomicity.h>
>>cause ODR violations when used from inline functions or templates (see
>>[basic.def.odr] p12 bullet (12.2)). His modules branch now diagnoses
>>those violations, so we need a fix.
>>
>>Looking at the history (r114044 by Paolo) I believe the idea was indeed
>>to allow different definitions to be used in different TUs. I think
>>__attribute__((__always_inline__)) is a better match for that than
>>'static inline', and doesn't violate the ODR (at least, not if all TUs
>>have the same values for __GTHREADS and _GLIBCXX_ATOMIC_BUILTINS).
>>
>>These functions still violate this rule in [dcl.inline]:
>>
>>C++17: "If a function with external linkage is declared inline in one
>>translation unit, it shall be declared inline in all translation units
>>in which it appears; no diagnostic is required."
>>
>>C++2a WP: "If a function or variable with external or module linkage
>>is declared inline in one translation unit, there shall be a reachable
>>inline declaration in all translation units in which it is declared;
>>no diagnostic is required."
>>
>>But that doesn't seem to be diagnosable by today's implementations.
>>
>>Does this change seem reasonable?
>
>yes, thanks!
Actually, I think I prefer this version. This produces identical code
to the always_inline version, but without the indirection to
additional inline functions, i.e. just inline the relevant code into
the _dispatch functions.
Tests are still running but no failures so far, as expected.
[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 4128 bytes --]
commit 56040dad3b55a98f6e5090d04cb49945c40df39c
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Fri Jun 21 17:52:23 2019 +0100
Simplify
diff --git a/libstdc++-v3/include/ext/atomicity.h b/libstdc++-v3/include/ext/atomicity.h
index 0783a58e01a..30453c92315 100644
--- a/libstdc++-v3/include/ext/atomicity.h
+++ b/libstdc++-v3/include/ext/atomicity.h
@@ -43,62 +43,49 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// To abstract locking primitives across all thread policies, use:
// __exchange_and_add_dispatch
// __atomic_add_dispatch
-#ifdef _GLIBCXX_ATOMIC_BUILTINS
- static inline _Atomic_word
- __exchange_and_add(volatile _Atomic_word* __mem, int __val)
- { return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
-
- static inline void
- __atomic_add(volatile _Atomic_word* __mem, int __val)
- { __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
-#else
+#ifndef _GLIBCXX_ATOMIC_BUILTINS
_Atomic_word
- __attribute__ ((__unused__))
__exchange_and_add(volatile _Atomic_word*, int) throw ();
void
- __attribute__ ((__unused__))
__atomic_add(volatile _Atomic_word*, int) throw ();
#endif
- static inline _Atomic_word
- __exchange_and_add_single(_Atomic_word* __mem, int __val)
+ inline _Atomic_word
+ __attribute__ ((__always_inline__))
+ __exchange_and_add_dispatch(_Atomic_word* __mem, int __val)
{
+#ifdef __GTHREADS
+ if (__gthread_active_p())
+ {
+#ifdef _GLIBCXX_ATOMIC_BUILTINS
+ return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL);
+#else
+ return __exchange_and_add(__mem, __val);
+#endif
+ }
+#endif
_Atomic_word __result = *__mem;
*__mem += __val;
return __result;
}
- static inline void
- __atomic_add_single(_Atomic_word* __mem, int __val)
- { *__mem += __val; }
-
- static inline _Atomic_word
- __attribute__ ((__unused__))
- __exchange_and_add_dispatch(_Atomic_word* __mem, int __val)
- {
-#ifdef __GTHREADS
- if (__gthread_active_p())
- return __exchange_and_add(__mem, __val);
- else
- return __exchange_and_add_single(__mem, __val);
-#else
- return __exchange_and_add_single(__mem, __val);
-#endif
- }
-
- static inline void
- __attribute__ ((__unused__))
+ inline void
+ __attribute__ ((__always_inline__))
__atomic_add_dispatch(_Atomic_word* __mem, int __val)
{
#ifdef __GTHREADS
if (__gthread_active_p())
- __atomic_add(__mem, __val);
- else
- __atomic_add_single(__mem, __val);
+ {
+#ifdef _GLIBCXX_ATOMIC_BUILTINS
+ __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL);
#else
- __atomic_add_single(__mem, __val);
+ __atomic_add(__mem, __val);
#endif
+ }
+ else
+#endif
+ *__mem += __val;
}
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/src/c++98/mt_allocator.cc b/libstdc++-v3/src/c++98/mt_allocator.cc
index f842c6f9cfd..9b26f3dc993 100644
--- a/libstdc++-v3/src/c++98/mt_allocator.cc
+++ b/libstdc++-v3/src/c++98/mt_allocator.cc
@@ -302,7 +302,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__reclaimed > 1024)
{
__bin._M_used[__thread_id] -= __reclaimed;
- __atomic_add(&__reclaimed_base[__thread_id], -__reclaimed);
+ __atomic_fetch_add(&__reclaimed_base[__thread_id], -__reclaimed,
+ __ATOMIC_ACQ_REL);
}
if (__remove >= __net_used)
@@ -332,7 +333,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__block->_M_thread_id == __thread_id)
--__bin._M_used[__thread_id];
else
- __atomic_add(&__reclaimed_base[__block->_M_thread_id], 1);
+ __atomic_fetch_add(&__reclaimed_base[__block->_M_thread_id], 1,
+ __ATOMIC_ACQ_REL);
__block->_M_next = __bin._M_first[__thread_id];
__bin._M_first[__thread_id] = __block;
@@ -379,7 +381,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
reinterpret_cast<_Atomic_word*>(__bin._M_used + __max_threads);
const _Atomic_word __reclaimed = __reclaimed_base[__thread_id];
__bin._M_used[__thread_id] -= __reclaimed;
- __atomic_add(&__reclaimed_base[__thread_id], -__reclaimed);
+ __atomic_fetch_add(&__reclaimed_base[__thread_id], -__reclaimed,
+ __ATOMIC_ACQ_REL);
__gthread_mutex_lock(__bin._M_mutex);
if (__bin._M_first[0] == 0)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix ODR violations in code using <ext/atomicity.h>
2019-06-21 17:08 ` Jonathan Wakely
@ 2019-06-21 17:13 ` Jonathan Wakely
2019-07-05 16:26 ` Jonathan Wakely
0 siblings, 1 reply; 8+ messages in thread
From: Jonathan Wakely @ 2019-06-21 17:13 UTC (permalink / raw)
To: Nathan Sidwell; +Cc: libstdc++, gcc-patches
On 21/06/19 18:08 +0100, Jonathan Wakely wrote:
>On 21/06/19 13:01 -0400, Nathan Sidwell wrote:
>>On 6/21/19 12:01 PM, Jonathan Wakely wrote:
>>>Nathan noticed that the 'static inline' functions in <ext/atomicity.h>
>>>cause ODR violations when used from inline functions or templates (see
>>>[basic.def.odr] p12 bullet (12.2)). His modules branch now diagnoses
>>>those violations, so we need a fix.
>>>
>>>Looking at the history (r114044 by Paolo) I believe the idea was indeed
>>>to allow different definitions to be used in different TUs. I think
>>>__attribute__((__always_inline__)) is a better match for that than
>>>'static inline', and doesn't violate the ODR (at least, not if all TUs
>>>have the same values for __GTHREADS and _GLIBCXX_ATOMIC_BUILTINS).
>>>
>>>These functions still violate this rule in [dcl.inline]:
>>>
>>>C++17: "If a function with external linkage is declared inline in one
>>>translation unit, it shall be declared inline in all translation units
>>>in which it appears; no diagnostic is required."
>>>
>>>C++2a WP: "If a function or variable with external or module linkage
>>>is declared inline in one translation unit, there shall be a reachable
>>>inline declaration in all translation units in which it is declared;
>>>no diagnostic is required."
>>>
>>>But that doesn't seem to be diagnosable by today's implementations.
>>>
>>>Does this change seem reasonable?
>>
>>yes, thanks!
>
>Actually, I think I prefer this version. This produces identical code
>to the always_inline version, but without the indirection to
>additional inline functions, i.e. just inline the relevant code into
>the _dispatch functions.
>
>Tests are still running but no failures so far, as expected.
Oops, I spoke too soon:
FAIL: tr1/2_general_utilities/shared_ptr/thread/default_weaktoshared.cc (test for excess errors)
UNRESOLVED: tr1/2_general_utilities/shared_ptr/thread/default_weaktoshared.cc compilation failed to produce executable
FAIL: tr1/2_general_utilities/shared_ptr/thread/mutex_weaktoshared.cc (test for excess errors)
UNRESOLVED: tr1/2_general_utilities/shared_ptr/thread/mutex_weaktoshared.cc compilation failed to produce executable
Those tests explicitly use the __atomic_add function that the patch
removes. But those would be easy to adjust.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix ODR violations in code using <ext/atomicity.h>
2019-06-21 17:13 ` Jonathan Wakely
@ 2019-07-05 16:26 ` Jonathan Wakely
2019-07-05 18:28 ` Daniel Krügler
0 siblings, 1 reply; 8+ messages in thread
From: Jonathan Wakely @ 2019-07-05 16:26 UTC (permalink / raw)
To: Nathan Sidwell; +Cc: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 2684 bytes --]
On 21/06/19 18:13 +0100, Jonathan Wakely wrote:
>On 21/06/19 18:08 +0100, Jonathan Wakely wrote:
>>On 21/06/19 13:01 -0400, Nathan Sidwell wrote:
>>>On 6/21/19 12:01 PM, Jonathan Wakely wrote:
>>>>Nathan noticed that the 'static inline' functions in <ext/atomicity.h>
>>>>cause ODR violations when used from inline functions or templates (see
>>>>[basic.def.odr] p12 bullet (12.2)). His modules branch now diagnoses
>>>>those violations, so we need a fix.
>>>>
>>>>Looking at the history (r114044 by Paolo) I believe the idea was indeed
>>>>to allow different definitions to be used in different TUs. I think
>>>>__attribute__((__always_inline__)) is a better match for that than
>>>>'static inline', and doesn't violate the ODR (at least, not if all TUs
>>>>have the same values for __GTHREADS and _GLIBCXX_ATOMIC_BUILTINS).
>>>>
>>>>These functions still violate this rule in [dcl.inline]:
>>>>
>>>>C++17: "If a function with external linkage is declared inline in one
>>>>translation unit, it shall be declared inline in all translation units
>>>>in which it appears; no diagnostic is required."
>>>>
>>>>C++2a WP: "If a function or variable with external or module linkage
>>>>is declared inline in one translation unit, there shall be a reachable
>>>>inline declaration in all translation units in which it is declared;
>>>>no diagnostic is required."
>>>>
>>>>But that doesn't seem to be diagnosable by today's implementations.
>>>>
>>>>Does this change seem reasonable?
>>>
>>>yes, thanks!
>>
>>Actually, I think I prefer this version. This produces identical code
>>to the always_inline version, but without the indirection to
>>additional inline functions, i.e. just inline the relevant code into
>>the _dispatch functions.
>>
>>Tests are still running but no failures so far, as expected.
>
>Oops, I spoke too soon:
>
>FAIL: tr1/2_general_utilities/shared_ptr/thread/default_weaktoshared.cc (test for excess errors)
>UNRESOLVED: tr1/2_general_utilities/shared_ptr/thread/default_weaktoshared.cc compilation failed to produce executable
>FAIL: tr1/2_general_utilities/shared_ptr/thread/mutex_weaktoshared.cc (test for excess errors)
>UNRESOLVED: tr1/2_general_utilities/shared_ptr/thread/mutex_weaktoshared.cc compilation failed to produce executable
>
>Those tests explicitly use the __atomic_add function that the patch
>removes. But those would be easy to adjust.
I decided against the simplification in the second patch, and
committed the attached one which is closer to the first patch I sent
(preserving the __atomic_add and __exchange_and_add functions even
when they just call the built-ins).
Tested x86_64-linux, powerpc64-linux, powerpc-aix. Committed to trunk.
[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 3225 bytes --]
commit 0d26b6506f20dcb1c956338baba0c26f623e25f2
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Fri Jul 5 15:15:46 2019 +0100
Fix ODR violations in code using <ext/atomicity.h>
Because the inline versions of __exchange_and_add and __atomic_add are
also marked static, they cannot be used from templates or other inline
functions without ODR violations. This change gives them external
linkage, but adds the always_inline attribute.
* include/ext/atomicity.h [_GLIBCXX_ATOMIC_BUILTINS] (__atomic_add)
(__exchange_and_add): Replace static specifier with always_inline
attribute.
(__exchange_and_add_single, __atomic_add_single): Likewise.
(__exchange_and_add_dispatch, __atomic_add_dispatch): Likewise. Also
combine !__gthread_active_p() and !__GTHREADS branches.
diff --git a/libstdc++-v3/include/ext/atomicity.h b/libstdc++-v3/include/ext/atomicity.h
index 0783a58e01a..73225b3de20 100644
--- a/libstdc++-v3/include/ext/atomicity.h
+++ b/libstdc++-v3/include/ext/atomicity.h
@@ -44,24 +44,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// __exchange_and_add_dispatch
// __atomic_add_dispatch
#ifdef _GLIBCXX_ATOMIC_BUILTINS
- static inline _Atomic_word
+ inline _Atomic_word
+ __attribute__((__always_inline__))
__exchange_and_add(volatile _Atomic_word* __mem, int __val)
{ return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
- static inline void
+ inline void
+ __attribute__((__always_inline__))
__atomic_add(volatile _Atomic_word* __mem, int __val)
{ __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
#else
_Atomic_word
- __attribute__ ((__unused__))
__exchange_and_add(volatile _Atomic_word*, int) throw ();
void
- __attribute__ ((__unused__))
__atomic_add(volatile _Atomic_word*, int) throw ();
#endif
- static inline _Atomic_word
+ inline _Atomic_word
+ __attribute__((__always_inline__))
__exchange_and_add_single(_Atomic_word* __mem, int __val)
{
_Atomic_word __result = *__mem;
@@ -69,36 +70,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __result;
}
- static inline void
+ inline void
+ __attribute__((__always_inline__))
__atomic_add_single(_Atomic_word* __mem, int __val)
{ *__mem += __val; }
- static inline _Atomic_word
- __attribute__ ((__unused__))
+ inline _Atomic_word
+ __attribute__ ((__always_inline__))
__exchange_and_add_dispatch(_Atomic_word* __mem, int __val)
{
#ifdef __GTHREADS
if (__gthread_active_p())
return __exchange_and_add(__mem, __val);
- else
- return __exchange_and_add_single(__mem, __val);
-#else
- return __exchange_and_add_single(__mem, __val);
#endif
+ return __exchange_and_add_single(__mem, __val);
}
- static inline void
- __attribute__ ((__unused__))
+ inline void
+ __attribute__ ((__always_inline__))
__atomic_add_dispatch(_Atomic_word* __mem, int __val)
{
#ifdef __GTHREADS
if (__gthread_active_p())
__atomic_add(__mem, __val);
- else
- __atomic_add_single(__mem, __val);
-#else
- __atomic_add_single(__mem, __val);
#endif
+ __atomic_add_single(__mem, __val);
}
_GLIBCXX_END_NAMESPACE_VERSION
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix ODR violations in code using <ext/atomicity.h>
2019-07-05 16:26 ` Jonathan Wakely
@ 2019-07-05 18:28 ` Daniel Krügler
2019-07-05 19:11 ` Jonathan Wakely
0 siblings, 1 reply; 8+ messages in thread
From: Daniel Krügler @ 2019-07-05 18:28 UTC (permalink / raw)
To: Jonathan Wakely; +Cc: Nathan Sidwell, libstdc++, gcc-patches List
Am Fr., 5. Juli 2019 um 18:13 Uhr schrieb Jonathan Wakely <jwakely@redhat.com>:
>
[..]
> I decided against the simplification in the second patch, and
> committed the attached one which is closer to the first patch I sent
> (preserving the __atomic_add and __exchange_and_add functions even
> when they just call the built-ins).
>
> Tested x86_64-linux, powerpc64-linux, powerpc-aix. Committed to trunk.
Unrelated to the actual patch, I noticed some explicit "throw()" forms
used as exception specifications - shouldn't these be replaced by
either explicit "noexcept" or at least by a library macro that expands
to one or the other? (I'm sorry, if such unrelated questions are
considered as inappropriate for this list).
- Daniel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix ODR violations in code using <ext/atomicity.h>
2019-07-05 18:28 ` Daniel Krügler
@ 2019-07-05 19:11 ` Jonathan Wakely
2019-07-06 22:02 ` Jonathan Wakely
0 siblings, 1 reply; 8+ messages in thread
From: Jonathan Wakely @ 2019-07-05 19:11 UTC (permalink / raw)
To: Daniel Krügler; +Cc: Nathan Sidwell, libstdc++, gcc-patches List
On 05/07/19 20:23 +0200, Daniel Krügler wrote:
>Am Fr., 5. Juli 2019 um 18:13 Uhr schrieb Jonathan Wakely <jwakely@redhat.com>:
>>
>[..]
>> I decided against the simplification in the second patch, and
>> committed the attached one which is closer to the first patch I sent
>> (preserving the __atomic_add and __exchange_and_add functions even
>> when they just call the built-ins).
>>
>> Tested x86_64-linux, powerpc64-linux, powerpc-aix. Committed to trunk.
>
>Unrelated to the actual patch, I noticed some explicit "throw()" forms
>used as exception specifications - shouldn't these be replaced by
>either explicit "noexcept" or at least by a library macro that expands
>to one or the other?
Yes, they should be _GLIBCXX_NOTHROW.
>(I'm sorry, if such unrelated questions are
>considered as inappropriate for this list).
Entirely appropriate, thanks!
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix ODR violations in code using <ext/atomicity.h>
2019-07-05 19:11 ` Jonathan Wakely
@ 2019-07-06 22:02 ` Jonathan Wakely
0 siblings, 0 replies; 8+ messages in thread
From: Jonathan Wakely @ 2019-07-06 22:02 UTC (permalink / raw)
To: Daniel Krügler
Cc: Nathan Sidwell, libstdc++, gcc-patches List, Iain Sandoe
[-- Attachment #1: Type: text/plain, Size: 1045 bytes --]
On 05/07/19 19:44 +0100, Jonathan Wakely wrote:
>On 05/07/19 20:23 +0200, Daniel Krügler wrote:
>>Am Fr., 5. Juli 2019 um 18:13 Uhr schrieb Jonathan Wakely <jwakely@redhat.com>:
>>>
>>[..]
>>>I decided against the simplification in the second patch, and
>>>committed the attached one which is closer to the first patch I sent
>>>(preserving the __atomic_add and __exchange_and_add functions even
>>>when they just call the built-ins).
>>>
>>>Tested x86_64-linux, powerpc64-linux, powerpc-aix. Committed to trunk.
>>
>>Unrelated to the actual patch, I noticed some explicit "throw()" forms
>>used as exception specifications - shouldn't these be replaced by
>>either explicit "noexcept" or at least by a library macro that expands
>>to one or the other?
>
>Yes, they should be _GLIBCXX_NOTHROW.
>
>>(I'm sorry, if such unrelated questions are
>>considered as inappropriate for this list).
>
>Entirely appropriate, thanks!
Here's a patch to fix that and the dumb mistake I made in
__atomic_add_dispatch. I'll commit after testing finishes.
[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 1285 bytes --]
commit 1542776ebab8848109d125d05a548fca5efb513a
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Sat Jul 6 21:24:51 2019 +0100
Fix recent regression in __atomic_add_dispatch
* include/ext/atomicity.h (__exchange_and_add, __atomic_add): Replace
throw() with _GLIBCXX_NOTHROW.
(__atomic_add_dispatch): Return after performing atomic increment.
diff --git a/libstdc++-v3/include/ext/atomicity.h b/libstdc++-v3/include/ext/atomicity.h
index 73225b3de20..333c8843e14 100644
--- a/libstdc++-v3/include/ext/atomicity.h
+++ b/libstdc++-v3/include/ext/atomicity.h
@@ -55,10 +55,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
#else
_Atomic_word
- __exchange_and_add(volatile _Atomic_word*, int) throw ();
+ __exchange_and_add(volatile _Atomic_word*, int) _GLIBCXX_NOTHROW;
void
- __atomic_add(volatile _Atomic_word*, int) throw ();
+ __atomic_add(volatile _Atomic_word*, int) _GLIBCXX_NOTHROW;
#endif
inline _Atomic_word
@@ -92,7 +92,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
#ifdef __GTHREADS
if (__gthread_active_p())
- __atomic_add(__mem, __val);
+ {
+ __atomic_add(__mem, __val);
+ return;
+ }
#endif
__atomic_add_single(__mem, __val);
}
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2019-07-06 20:35 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-21 16:01 [PATCH] Fix ODR violations in code using <ext/atomicity.h> Jonathan Wakely
2019-06-21 17:01 ` Nathan Sidwell
2019-06-21 17:08 ` Jonathan Wakely
2019-06-21 17:13 ` Jonathan Wakely
2019-07-05 16:26 ` Jonathan Wakely
2019-07-05 18:28 ` Daniel Krügler
2019-07-05 19:11 ` Jonathan Wakely
2019-07-06 22:02 ` Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).