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

Reply via email to