Handle alignment in __atomic_is_lock_free
gcc: 2015-09-17 Richard Henderson <rth@redhat.com> PR libstdc++/65913 * builtins.c (fold_builtin_atomic_always_lock_free): Handle fake pointers that encode the alignment of the object. libstdc++-v3: 2015-09-17 Jonathan Wakely <jwakely@redhat.com> PR libstdc++/65913 * include/bits/atomic_base.h (__atomic_base<_TTp>::is_lock_free(), __atomic_base<_PTp*>::is_lock_free()): Call the built-in with the immediate pointer value, not a variable. * include/std/atomic (atomic<T>::is_lock_free()): Likewise. * testsuite/29_atomics/atomic/65913.cc: New. From-SVN: r227878
This commit is contained in:
parent
308fbc4290
commit
310055e7b4
|
@ -1,3 +1,9 @@
|
|||
2015-09-17 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR libstdc++/65913
|
||||
* builtins.c (fold_builtin_atomic_always_lock_free): Handle fake
|
||||
pointers that encode the alignment of the object.
|
||||
|
||||
2015-09-17 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
PR rtl-optimization/66790
|
||||
|
|
|
@ -5635,8 +5635,20 @@ fold_builtin_atomic_always_lock_free (tree arg0, tree arg1)
|
|||
mode = mode_for_size (size, MODE_INT, 0);
|
||||
mode_align = GET_MODE_ALIGNMENT (mode);
|
||||
|
||||
if (TREE_CODE (arg1) == INTEGER_CST && INTVAL (expand_normal (arg1)) == 0)
|
||||
type_align = mode_align;
|
||||
if (TREE_CODE (arg1) == INTEGER_CST)
|
||||
{
|
||||
unsigned HOST_WIDE_INT val = UINTVAL (expand_normal (arg1));
|
||||
|
||||
/* Either this argument is null, or it's a fake pointer encoding
|
||||
the alignment of the object. */
|
||||
val = val & -val;
|
||||
val *= BITS_PER_UNIT;
|
||||
|
||||
if (val == 0 || mode_align < val)
|
||||
type_align = mode_align;
|
||||
else
|
||||
type_align = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
tree ttype = TREE_TYPE (arg1);
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
2015-09-17 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/65913
|
||||
* include/bits/atomic_base.h (__atomic_base<_TTp>::is_lock_free(),
|
||||
__atomic_base<_PTp*>::is_lock_free()): Call the built-in with the
|
||||
immediate pointer value, not a variable.
|
||||
* include/std/atomic (atomic<T>::is_lock_free()): Likewise.
|
||||
* testsuite/29_atomics/atomic/65913.cc: New.
|
||||
|
||||
* testsuite/experimental/filesystem/operations/canonical.cc: Remove
|
||||
non-deterministic part of the test.
|
||||
|
||||
|
|
|
@ -350,17 +350,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
bool
|
||||
is_lock_free() const noexcept
|
||||
{
|
||||
// Produce a fake, minimally aligned pointer.
|
||||
void *__a = reinterpret_cast<void *>(-__alignof(_M_i));
|
||||
return __atomic_is_lock_free(sizeof(_M_i), __a);
|
||||
// Use a fake, minimally aligned pointer.
|
||||
return __atomic_is_lock_free(sizeof(_M_i),
|
||||
reinterpret_cast<void *>(-__alignof(_M_i)));
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free() const volatile noexcept
|
||||
{
|
||||
// Produce a fake, minimally aligned pointer.
|
||||
void *__a = reinterpret_cast<void *>(-__alignof(_M_i));
|
||||
return __atomic_is_lock_free(sizeof(_M_i), __a);
|
||||
// Use a fake, minimally aligned pointer.
|
||||
return __atomic_is_lock_free(sizeof(_M_i),
|
||||
reinterpret_cast<void *>(-__alignof(_M_i)));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE void
|
||||
|
@ -666,16 +666,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
is_lock_free() const noexcept
|
||||
{
|
||||
// Produce a fake, minimally aligned pointer.
|
||||
void *__a = reinterpret_cast<void *>(-__alignof(_M_p));
|
||||
return __atomic_is_lock_free(sizeof(_M_p), __a);
|
||||
return __atomic_is_lock_free(sizeof(_M_p),
|
||||
reinterpret_cast<void *>(-__alignof(_M_p)));
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free() const volatile noexcept
|
||||
{
|
||||
// Produce a fake, minimally aligned pointer.
|
||||
void *__a = reinterpret_cast<void *>(-__alignof(_M_p));
|
||||
return __atomic_is_lock_free(sizeof(_M_p), __a);
|
||||
return __atomic_is_lock_free(sizeof(_M_p),
|
||||
reinterpret_cast<void *>(-__alignof(_M_p)));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE void
|
||||
|
|
|
@ -208,16 +208,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
is_lock_free() const noexcept
|
||||
{
|
||||
// Produce a fake, minimally aligned pointer.
|
||||
void *__a = reinterpret_cast<void *>(-__alignof(_M_i));
|
||||
return __atomic_is_lock_free(sizeof(_M_i), __a);
|
||||
return __atomic_is_lock_free(sizeof(_M_i),
|
||||
reinterpret_cast<void *>(-__alignof(_M_i)));
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free() const volatile noexcept
|
||||
{
|
||||
// Produce a fake, minimally aligned pointer.
|
||||
void *__a = reinterpret_cast<void *>(-__alignof(_M_i));
|
||||
return __atomic_is_lock_free(sizeof(_M_i), __a);
|
||||
return __atomic_is_lock_free(sizeof(_M_i),
|
||||
reinterpret_cast<void *>(-__alignof(_M_i)));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (C) 2015 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-do run { target x86_64-*-linux* powerpc*-*-linux* } }
|
||||
// { dg-options "-std=gnu++11 -O0" }
|
||||
|
||||
#include <atomic>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
// PR libstdc++/65913
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
struct Int { int i; };
|
||||
VERIFY( std::atomic<Int>{}.is_lock_free() );
|
||||
VERIFY( std::atomic<int>{}.is_lock_free() );
|
||||
VERIFY( std::atomic<int*>{}.is_lock_free() );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
}
|
Loading…
Reference in New Issue