EricWF created this revision. EricWF added reviewers: mclow.lists, rsmith, eugenis. EricWF added subscribers: cfe-commits, rsmith.
GCC fail's to compile a number of <valarray> tests because three valarray member functions cannot be inlined at various points throughout the header. This is an error because these functions are marked __always_inline__. Moving the definition of these member functions to directly before the extern template declaration solves the problem. An example failure can be found here: http://ds2.efcs.ca:8080/builders/gcc-builder/builds/36/steps/test.libcxx-cxx11/logs/FAIL%3A%20libc%2B%2B%3A%3Amultiply.pass.cpp @rsmith Would you be able to weigh in here. I'm concerned that we might be in "ill formed: no diagnostic required" territory. Do you think GCC's behavior is reasonable? http://reviews.llvm.org/D15432 Files: include/valarray
Index: include/valarray =================================================================== --- include/valarray +++ include/valarray @@ -819,6 +819,7 @@ valarray(const gslice_array<value_type>& __ga); valarray(const mask_array<value_type>& __ma); valarray(const indirect_array<value_type>& __ia); + _LIBCPP_INLINE_VISIBILITY ~valarray(); @@ -1058,10 +1059,63 @@ end(const valarray<_Up>& __v); }; +template <class _Tp> +void +valarray<_Tp>::resize(size_t __n, value_type __x) +{ + if (__begin_ != nullptr) + { + while (__end_ != __begin_) + (--__end_)->~value_type(); + _VSTD::__deallocate(__begin_); + __begin_ = __end_ = nullptr; + } + if (__n) + { + __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type))); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __n; --__n, ++__end_) + ::new (__end_) value_type(__x); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + resize(0); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } +} + + +template <class _Tp> +inline +valarray<_Tp>::valarray(size_t __n) + : __begin_(0), + __end_(0) +{ + resize(__n); +} + +template <class _Tp> +inline +valarray<_Tp>::~valarray() +{ + resize(0); +} + +// The definition for these three functions must appear before they are used and +// before these extern template declarations. +// Otherwise GCC will fail to inline the definition which is an error because +// the functions are declared always inline. _LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS valarray<size_t>::valarray(size_t)) _LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS valarray<size_t>::~valarray()) _LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void valarray<size_t>::resize(size_t, size_t)) + template <class _Op, class _Tp> struct _UnaryOp<_Op, valarray<_Tp> > { @@ -2747,14 +2801,6 @@ // valarray -template <class _Tp> -inline -valarray<_Tp>::valarray(size_t __n) - : __begin_(0), - __end_(0) -{ - resize(__n); -} template <class _Tp> inline @@ -2971,12 +3017,6 @@ } } -template <class _Tp> -inline -valarray<_Tp>::~valarray() -{ - resize(0); -} template <class _Tp> valarray<_Tp>& @@ -3689,37 +3729,6 @@ return __r; } -template <class _Tp> -void -valarray<_Tp>::resize(size_t __n, value_type __x) -{ - if (__begin_ != nullptr) - { - while (__end_ != __begin_) - (--__end_)->~value_type(); - _VSTD::__deallocate(__begin_); - __begin_ = __end_ = nullptr; - } - if (__n) - { - __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type))); -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - for (; __n; --__n, ++__end_) - ::new (__end_) value_type(__x); -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - resize(0); - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS - } -} - template<class _Tp> inline _LIBCPP_INLINE_VISIBILITY void
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits