[patch] libstdc++/66017 Avoid bad casts and fix alignment of _Rb_tree_node<long long>::_M_storage
Jonathan Wakely
jwakely@redhat.com
Tue May 26 15:18:00 GMT 2015
On 22/05/15 18:48 +0100, Jonathan Wakely wrote:
>On 22/05/15 16:21 +0100, Jonathan Wakely wrote:
>>On 22/05/15 17:13 +0200, Jakub Jelinek wrote:
>>>On Fri, May 22, 2015 at 03:59:47PM +0100, Jonathan Wakely wrote:
>>>>>>+ alignas(alignof(_Tp2)) unsigned char _M_storage[sizeof(_Tp)];
>>>>>
>>>>>Is alignof(_Tp2) always the same as alignof(_Tp2::_M_t) on all targets
>>>>>(I mean, won't some target align the structure more than its only field)?
>>>>
>>>>Hmm, maybe. I don't know.
>>>>
>>>>>Wouldn't it be safer to use alignof(_Tp2::_M_t) here?
>>>>
>>>>Yes.
>>>>
>>>>>Though, apparently that is a GNU extension, so you'd need to use __alignof__
>>>>>instead.
>>>>
>>>>Yes, that's what I did in an earlier version of the patch, so I'll go
>>>>back to that.
>>>
>>>Just grepped around, and e.g. on powerpc64le-linux -std=c++11 -malign-power -O2
>>>typedef double _Tp;
>>>struct _Tp2 { _Tp _M_t; };
>>>extern _Tp2 tp2e;
>>>int a = alignof(_Tp2);
>>>int b = __alignof__(_Tp2::_M_t);
>>>int c = alignof(_Tp);
>>>int d = __alignof__(tp2e._M_t);
>>>int e = alignof(_Tp2::_M_t);
>>>
>>>we have a = 8, b = 4, c = 8, d = 4, e = 4.
>>
>>OK, thanks.
>>
>>>Note clang++ with -pedantic-errors errors out on alignof(_Tp2::_M_t) though.
>>
>>It allows __alignof__ though.
>
>Revised patches attached, as two separate commits because the first
>should be backported but the second doesn't need to be.
>
>This includes the necessary changes for the Python printers.
The change to __aligned_buffer (which makes _Rb_tree_node<long long>
consistent in c++98 and c++11 modes) also affects some other
C++11-only types. Compiling the attached program with -std=gnu++11
-m32 before and after the patch produces these results:
Before:
future<long long> shared state: alignment: 8 size: 24
shared_ptr<long long> control block: alignment: 8 size: 24
forward_list<long long> node: alignment: 8 size: 16
unordered_set<long long> node: alignment: 8 size: 16
After:
future<long long> shared state: alignment: 4 size: 20
shared_ptr<long long> control block: alignment: 4 size: 20
forward_list<long long> node: alignment: 4 size: 12
unordered_set<long long> node: alignment: 4 size: 12
The fix for _Rb_tree_node<long long> is a bug fix and necessary for
consistency with existing c++98 code, which is more important than
consistency with existing c++11 code using 5.1 or earlier releases.
But changing the other types as well would make 5.2 inconsistent with
5.1 for those types. We could just make that change and deal with it,
or I could keep __aligned_buffer unchanged and add a new
__aligned_buffer_mem for use in _Rb_tree_node, so we only change the
one type that is currently inconsistent between c++98 and c++11 modes.
The attached patch makes that smaller change (the second patch in my
last mail remains unchanged).
It's a shame to waste some space in the other types using
__aligned_buffer, and to have to maintain both __aligned_buffer and
__aligned_buffer_mem, but I think this is safer.
-------------- next part --------------
#include <iostream>
#include <future>
#include <memory>
#include <forward_list>
#include <unordered_set>
using namespace std;
template<typename T>
void f(const char* s)
{
cout << s << ": alignment: " << alignof(T) << " size: " << sizeof(T) << '\n';
}
int main()
{
f<__future_base::_Result<long long>>("future<long long> shared state");
f<_Sp_counted_ptr_inplace<long long, allocator<long long>, __default_lock_policy>>("shared_ptr<long long> control block");
f<_Fwd_list_node<long long>>("forward_list<long long> node");
f<__detail::_Hash_node<long long, false>>("unordered_set<long long> node");
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.txt
Type: text/x-patch
Size: 5465 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20150526/d6f8b490/attachment.bin>
More information about the Gcc-patches
mailing list