re PR libstdc++/48760 (std::complex constructor buggy in the face of NaN's)
2011-04-28 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/48760 * include/std/complex (complex<float>::complex(float, float), complex<double>::complex(double, double), complex<long double>::complex(long double, long double)): Use list-initialization in C++0x mode, initialize in the body in C++03 mode. * testsuite/26_numerics/complex/cons/48760.cc: New. * testsuite/26_numerics/complex/cons/48760_c++0x.cc: Likewise. 2011-04-28 Paolo Carlini <paolo.carlini@oracle.com> * include/std/bitset (_Base_bitset(unsigned long long)): Minor tweak, remove redundant round braces. From-SVN: r173065
This commit is contained in:
parent
6ecde111c1
commit
9f1163b171
12 changed files with 223 additions and 35 deletions
|
@ -1,3 +1,19 @@
|
|||
2011-04-28 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR libstdc++/48760
|
||||
* include/std/complex (complex<float>::complex(float, float),
|
||||
complex<double>::complex(double, double),
|
||||
complex<long double>::complex(long double, long double)): Use
|
||||
list-initialization in C++0x mode, initialize in the body in
|
||||
C++03 mode.
|
||||
* testsuite/26_numerics/complex/cons/48760.cc: New.
|
||||
* testsuite/26_numerics/complex/cons/48760_c++0x.cc: Likewise.
|
||||
|
||||
2011-04-28 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
* include/std/bitset (_Base_bitset(unsigned long long)): Minor
|
||||
tweak, remove redundant round braces.
|
||||
|
||||
2011-04-27 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
* include/bits/move.h (move_if_noexcept): Add.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008, 2009, 2010, 2011 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
|
||||
|
@ -116,7 +116,11 @@ namespace __gnu_parallel
|
|||
* @brief The destructor.
|
||||
*/
|
||||
~_LoserTreeBase()
|
||||
{ ::operator delete(_M_losers); }
|
||||
{
|
||||
for (unsigned int __i = 0; __i < (2 * _M_k); ++__i)
|
||||
_M_losers[__i].~_Loser();
|
||||
::operator delete(_M_losers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the sequence "_M_source" with the element "__key".
|
||||
|
@ -131,15 +135,15 @@ namespace __gnu_parallel
|
|||
{
|
||||
unsigned int __pos = _M_k + __source;
|
||||
|
||||
if(_M_first_insert)
|
||||
if (_M_first_insert)
|
||||
{
|
||||
// Construct all keys, so we can easily deconstruct them.
|
||||
// Construct all keys, so we can easily destruct them.
|
||||
for (unsigned int __i = 0; __i < (2 * _M_k); ++__i)
|
||||
new(&(_M_losers[__i]._M_key)) _Tp(__key);
|
||||
_M_first_insert = false;
|
||||
}
|
||||
else
|
||||
new(&(_M_losers[__pos]._M_key)) _Tp(__key);
|
||||
_M_losers[__pos]._M_key = __key;
|
||||
|
||||
_M_losers[__pos]._M_sup = __sup;
|
||||
_M_losers[__pos]._M_source = __source;
|
||||
|
@ -379,7 +383,7 @@ namespace __gnu_parallel
|
|||
}
|
||||
|
||||
~_LoserTreePointerBase()
|
||||
{ ::operator delete[](_M_losers); }
|
||||
{ delete[] _M_losers; }
|
||||
|
||||
int __get_min_source()
|
||||
{ return _M_losers[0]._M_source; }
|
||||
|
@ -592,13 +596,17 @@ namespace __gnu_parallel
|
|||
|
||||
for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i)
|
||||
{
|
||||
_M_losers[__i]._M_key = __sentinel;
|
||||
::new(&(_M_losers[__i]._M_key)) _Tp(__sentinel);
|
||||
_M_losers[__i]._M_source = -1;
|
||||
}
|
||||
}
|
||||
|
||||
~_LoserTreeUnguardedBase()
|
||||
{ ::operator delete(_M_losers); }
|
||||
{
|
||||
for (unsigned int __i = 0; __i < (2 * _M_k); ++__i)
|
||||
_M_losers[__i].~_Loser();
|
||||
::operator delete(_M_losers);
|
||||
}
|
||||
|
||||
int
|
||||
__get_min_source()
|
||||
|
@ -615,7 +623,7 @@ namespace __gnu_parallel
|
|||
{
|
||||
unsigned int __pos = _M_k + __source;
|
||||
|
||||
new(&(_M_losers[__pos]._M_key)) _Tp(__key);
|
||||
::new(&(_M_losers[__pos]._M_key)) _Tp(__key);
|
||||
_M_losers[__pos]._M_source = __source;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1045,11 +1045,12 @@ namespace __gnu_parallel
|
|||
_ValueType;
|
||||
|
||||
// __k sequences.
|
||||
_SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);
|
||||
const _SeqNumber __k
|
||||
= static_cast<_SeqNumber>(__seqs_end - __seqs_begin);
|
||||
|
||||
_ThreadIndex __num_threads = omp_get_num_threads();
|
||||
const _ThreadIndex __num_threads = omp_get_num_threads();
|
||||
|
||||
_DifferenceType __num_samples =
|
||||
const _DifferenceType __num_samples =
|
||||
__gnu_parallel::_Settings::get().merge_oversampling * __num_threads;
|
||||
|
||||
_ValueType* __samples = static_cast<_ValueType*>
|
||||
|
@ -1096,6 +1097,10 @@ namespace __gnu_parallel
|
|||
__pieces[__slab][__seq].second =
|
||||
_GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]);
|
||||
}
|
||||
|
||||
for (_SeqNumber __s = 0; __s < __k; ++__s)
|
||||
for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
|
||||
__samples[__s * __num_samples + __i].~_ValueType();
|
||||
::operator delete(__samples);
|
||||
}
|
||||
|
||||
|
@ -1258,10 +1263,10 @@ namespace __gnu_parallel
|
|||
__length = std::min<_DifferenceTp>(__length, __total_length);
|
||||
|
||||
if (__total_length == 0 || __k == 0)
|
||||
{
|
||||
delete[] __ne_seqs;
|
||||
return __target;
|
||||
}
|
||||
{
|
||||
delete[] __ne_seqs;
|
||||
return __target;
|
||||
}
|
||||
|
||||
std::vector<std::pair<_DifferenceType, _DifferenceType> >* __pieces;
|
||||
|
||||
|
|
|
@ -378,6 +378,8 @@ namespace __gnu_parallel
|
|||
|
||||
# pragma omp barrier
|
||||
|
||||
for (_DifferenceType __i = 0; __i < __length_local; ++__i)
|
||||
__sd->_M_temporary[__iam][__i].~_ValueType();
|
||||
::operator delete(__sd->_M_temporary[__iam]);
|
||||
}
|
||||
|
||||
|
@ -413,6 +415,7 @@ namespace __gnu_parallel
|
|||
// shared variables
|
||||
_PMWMSSortingData<_RAIter> __sd;
|
||||
_DifferenceType* __starts;
|
||||
_DifferenceType __size;
|
||||
|
||||
# pragma omp parallel num_threads(__num_threads)
|
||||
{
|
||||
|
@ -427,7 +430,7 @@ namespace __gnu_parallel
|
|||
|
||||
if (!__exact)
|
||||
{
|
||||
_DifferenceType __size =
|
||||
__size =
|
||||
(_Settings::get().sort_mwms_oversampling * __num_threads - 1)
|
||||
* __num_threads;
|
||||
__sd._M_samples = static_cast<_ValueType*>
|
||||
|
@ -463,7 +466,11 @@ namespace __gnu_parallel
|
|||
delete[] __sd._M_temporary;
|
||||
|
||||
if (!__exact)
|
||||
::operator delete(__sd._M_samples);
|
||||
{
|
||||
for (_DifferenceType __i = 0; __i < __size; ++__i)
|
||||
__sd._M_samples[__i].~_ValueType();
|
||||
::operator delete(__sd._M_samples);
|
||||
}
|
||||
|
||||
delete[] __sd._M_offsets;
|
||||
delete[] __sd._M_pieces;
|
||||
|
|
|
@ -91,8 +91,7 @@ namespace __gnu_parallel
|
|||
_ThreadIndex __iam = omp_get_thread_num();
|
||||
|
||||
// Neutral element.
|
||||
_Result* __reduct = static_cast<_Result*>
|
||||
(::operator new(sizeof(_Result)));
|
||||
_Result* __reduct;
|
||||
|
||||
_DifferenceType
|
||||
__start = __equally_split_point(__length, __num_threads, __iam),
|
||||
|
@ -100,7 +99,7 @@ namespace __gnu_parallel
|
|||
|
||||
if (__start < __stop)
|
||||
{
|
||||
new(__reduct) _Result(__f(__o, __begin + __start));
|
||||
__reduct = new _Result(__f(__o, __begin + __start));
|
||||
++__start;
|
||||
__constructed[__iam] = true;
|
||||
}
|
||||
|
@ -110,18 +109,26 @@ namespace __gnu_parallel
|
|||
for (; __start < __stop; ++__start)
|
||||
*__reduct = __r(*__reduct, __f(__o, __begin + __start));
|
||||
|
||||
__thread_results[__iam] = *__reduct;
|
||||
if (__constructed[__iam])
|
||||
{
|
||||
::new(&__thread_results[__iam]) _Result(*__reduct);
|
||||
delete __reduct;
|
||||
}
|
||||
} //parallel
|
||||
|
||||
for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
|
||||
if (__constructed[__i])
|
||||
__output = __r(__output, __thread_results[__i]);
|
||||
{
|
||||
__output = __r(__output, __thread_results[__i]);
|
||||
__thread_results[__i].~_Result();
|
||||
}
|
||||
|
||||
// Points to last element processed (needed as return value for
|
||||
// some algorithms like transform).
|
||||
__f._M_finish_iterator = __begin + __length;
|
||||
|
||||
delete[] __thread_results;
|
||||
::operator delete(__thread_results);
|
||||
|
||||
delete[] __constructed;
|
||||
|
||||
return __o;
|
||||
|
|
|
@ -184,7 +184,10 @@ namespace __gnu_parallel
|
|||
__bin_op, __sums[__iam]);
|
||||
} //parallel
|
||||
|
||||
for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
|
||||
__sums[__i].~_ValueType();
|
||||
::operator delete(__sums);
|
||||
|
||||
delete[] __borders;
|
||||
|
||||
return __result + __n;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008, 2009, 2010, 2011 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
|
||||
|
@ -82,6 +82,8 @@ namespace __gnu_parallel
|
|||
_DifferenceType __split = __parallel_partition(__begin, __end,
|
||||
__pred, __num_threads);
|
||||
|
||||
for (_DifferenceType __s = 0; __s < __num_samples; ++__s)
|
||||
__samples[__s].~_ValueType();
|
||||
::operator delete(__samples);
|
||||
|
||||
return __split;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008, 2009, 2010, 2011 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
|
||||
|
@ -209,7 +209,7 @@ namespace __gnu_parallel
|
|||
_ThreadIndex __target_p = __bin_proc[__target_bin];
|
||||
|
||||
// Last column [__d->_M_num_threads] stays unchanged.
|
||||
::new(&(__temporaries[__target_p][__dist[__target_bin + 1]++]))
|
||||
::new(&(__temporaries[__target_p][__dist[__target_bin + 1]++]))
|
||||
_ValueType(*(__source + __i + __start));
|
||||
}
|
||||
|
||||
|
@ -227,8 +227,8 @@ namespace __gnu_parallel
|
|||
(__sd->_M_temporaries[__iam]
|
||||
+ (__b == __d->_M_bins_begin
|
||||
? 0 : __sd->_M_dist[__b][__d->_M_num_threads])),
|
||||
* __end = (__sd->_M_temporaries[__iam]
|
||||
+ __sd->_M_dist[__b + 1][__d->_M_num_threads]);
|
||||
*__end = (__sd->_M_temporaries[__iam]
|
||||
+ __sd->_M_dist[__b + 1][__d->_M_num_threads]);
|
||||
|
||||
__sequential_random_shuffle(__begin, __end, __rng);
|
||||
std::copy(__begin, __end, __sd->_M_source + __global_offset
|
||||
|
@ -236,6 +236,8 @@ namespace __gnu_parallel
|
|||
? 0 : __sd->_M_dist[__b][__d->_M_num_threads]));
|
||||
}
|
||||
|
||||
for (_SequenceIndex __i = 0; __i < __offset; ++__i)
|
||||
__sd->_M_temporaries[__iam][__i].~_ValueType();
|
||||
::operator delete(__sd->_M_temporaries[__iam]);
|
||||
}
|
||||
|
||||
|
@ -501,6 +503,9 @@ namespace __gnu_parallel
|
|||
delete[] __dist0;
|
||||
delete[] __dist1;
|
||||
delete[] __oracles;
|
||||
|
||||
for (_DifferenceType __i = 0; __i < __n; ++__i)
|
||||
__target[__i].~_ValueType();
|
||||
::operator delete(__target);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -80,11 +80,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
constexpr _Base_bitset(unsigned long long __val)
|
||||
: _M_w({ _WordT(__val)
|
||||
: _M_w{ _WordT(__val)
|
||||
#if __SIZEOF_LONG_LONG__ > __SIZEOF_LONG__
|
||||
, _WordT(__val >> _GLIBCXX_BITSET_BITS_PER_WORD)
|
||||
#endif
|
||||
}) { }
|
||||
} { }
|
||||
#else
|
||||
_Base_bitset(unsigned long __val)
|
||||
: _M_w()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// The template and inlines for the -*- C++ -*- complex number classes.
|
||||
|
||||
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
// 2006, 2007, 2008, 2009, 2010
|
||||
// 2006, 2007, 2008, 2009, 2010, 2011
|
||||
// Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
|
@ -1046,7 +1046,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
_GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { }
|
||||
|
||||
_GLIBCXX_CONSTEXPR complex(float __r = 0.0f, float __i = 0.0f)
|
||||
: _M_value(__r + __i * 1.0fi) { }
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
: _M_value{ __r, __i } { }
|
||||
#else
|
||||
{
|
||||
__real__ _M_value = __r;
|
||||
__imag__ _M_value = __i;
|
||||
}
|
||||
#endif
|
||||
|
||||
explicit _GLIBCXX_CONSTEXPR complex(const complex<double>&);
|
||||
explicit _GLIBCXX_CONSTEXPR complex(const complex<long double>&);
|
||||
|
@ -1186,7 +1193,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
_GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { }
|
||||
|
||||
_GLIBCXX_CONSTEXPR complex(double __r = 0.0, double __i = 0.0)
|
||||
: _M_value(__r + __i * 1.0i) { }
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
: _M_value{ __r, __i } { }
|
||||
#else
|
||||
{
|
||||
__real__ _M_value = __r;
|
||||
__imag__ _M_value = __i;
|
||||
}
|
||||
#endif
|
||||
|
||||
_GLIBCXX_CONSTEXPR complex(const complex<float>& __z)
|
||||
: _M_value(__z.__rep()) { }
|
||||
|
@ -1328,7 +1342,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
|
||||
_GLIBCXX_CONSTEXPR complex(long double __r = 0.0L,
|
||||
long double __i = 0.0L)
|
||||
: _M_value(__r + __i * 1.0Li) { }
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
: _M_value{ __r, __i } { }
|
||||
#else
|
||||
{
|
||||
__real__ _M_value = __r;
|
||||
__imag__ _M_value = __i;
|
||||
}
|
||||
#endif
|
||||
|
||||
_GLIBCXX_CONSTEXPR complex(const complex<float>& __z)
|
||||
: _M_value(__z.__rep()) { }
|
||||
|
|
56
libstdc++-v3/testsuite/26_numerics/complex/cons/48760.cc
Normal file
56
libstdc++-v3/testsuite/26_numerics/complex/cons/48760.cc
Normal file
|
@ -0,0 +1,56 @@
|
|||
// Copyright (C) 2011 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/>.
|
||||
|
||||
#include <complex>
|
||||
#include <limits>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
template<typename T>
|
||||
void do_test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
if (std::numeric_limits<T>::has_quiet_NaN)
|
||||
{
|
||||
std::complex<T> c1(T(0), std::numeric_limits<T>::quiet_NaN());
|
||||
VERIFY( c1.real() == T(0) );
|
||||
VERIFY( std::isnan(c1.imag()) );
|
||||
|
||||
std::complex<T> c2(std::numeric_limits<T>::quiet_NaN(), T(0));
|
||||
VERIFY( std::isnan(c2.real()) );
|
||||
VERIFY( c2.imag() == T(0) );
|
||||
|
||||
std::complex<T> c3(std::numeric_limits<T>::quiet_NaN(),
|
||||
std::numeric_limits<T>::quiet_NaN());
|
||||
VERIFY( std::isnan(c3.real()) );
|
||||
VERIFY( std::isnan(c3.imag()) );
|
||||
}
|
||||
}
|
||||
|
||||
// libstdc++/48760
|
||||
void test01()
|
||||
{
|
||||
do_test01<float>();
|
||||
do_test01<double>();
|
||||
do_test01<long double>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
// { dg-options "-std=gnu++0x" }
|
||||
|
||||
// Copyright (C) 2011 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/>.
|
||||
|
||||
#include <complex>
|
||||
#include <limits>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
template<typename T>
|
||||
void do_test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
if (std::numeric_limits<T>::has_quiet_NaN)
|
||||
{
|
||||
std::complex<T> c1(T(0), std::numeric_limits<T>::quiet_NaN());
|
||||
VERIFY( c1.real() == T(0) );
|
||||
VERIFY( std::isnan(c1.imag()) );
|
||||
|
||||
std::complex<T> c2(std::numeric_limits<T>::quiet_NaN(), T(0));
|
||||
VERIFY( std::isnan(c2.real()) );
|
||||
VERIFY( c2.imag() == T(0) );
|
||||
|
||||
std::complex<T> c3(std::numeric_limits<T>::quiet_NaN(),
|
||||
std::numeric_limits<T>::quiet_NaN());
|
||||
VERIFY( std::isnan(c3.real()) );
|
||||
VERIFY( std::isnan(c3.imag()) );
|
||||
}
|
||||
}
|
||||
|
||||
// libstdc++/48760
|
||||
void test01()
|
||||
{
|
||||
do_test01<float>();
|
||||
do_test01<double>();
|
||||
do_test01<long double>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue