From: Daniel Arndt <daniel.arndt@iwr.uni-heidelberg.de>
Date: Thu, 8 Nov 2018 08:41:40 +0000 (+0100)
Subject: Fix MemorySpace check for zero sized ArrayViews
X-Git-Tag: v9.1.0-rc1~569^2
X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F7430%2Fhead;p=dealii.git

Fix MemorySpace check for zero sized ArrayViews
---

diff --git a/include/deal.II/base/array_view.h b/include/deal.II/base/array_view.h
index ff410441b2..7cd0749284 100644
--- a/include/deal.II/base/array_view.h
+++ b/include/deal.II/base/array_view.h
@@ -312,11 +312,12 @@ inline ArrayView<ElementType, MemorySpaceType>::ArrayView(
   : starting_element(starting_element)
   , n_elements(n_elements)
 {
-  Assert(internal::ArrayViewHelper::is_in_correct_memory_space<MemorySpaceType>(
-           starting_element),
-         ExcMessage(
-           "The memory space indicated by the template parameter "
-           "and the one derived from the pointer value do not match!"));
+  Assert(
+    n_elements == 0 ||
+      internal::ArrayViewHelper::is_in_correct_memory_space<MemorySpaceType>(
+        starting_element),
+    ExcMessage("The memory space indicated by the template parameter "
+               "and the one derived from the pointer value do not match!"));
 }
 
 
@@ -351,11 +352,6 @@ inline ArrayView<ElementType, MemorySpaceType>::ArrayView(
                 "object has a const value_type. In other words, you can "
                 "only create an ArrayView to const values from a const "
                 "std::vector.");
-  Assert(internal::ArrayViewHelper::is_in_correct_memory_space<MemorySpaceType>(
-           vector.data()),
-         ExcMessage(
-           "The memory space indicated by the template parameter "
-           "and the one derived from the pointer value do not match!"));
 }
 
 
@@ -474,11 +470,11 @@ template <typename ElementType, typename MemorySpaceType>
 inline typename ArrayView<ElementType, MemorySpaceType>::value_type &
   ArrayView<ElementType, MemorySpaceType>::operator[](const std::size_t i) const
 {
+  Assert(i < n_elements, ExcIndexRange(i, 0, n_elements));
   Assert(
     (std::is_same<MemorySpaceType, MemorySpace::Host>::value),
     ExcMessage(
       "Accessing elements is only allowed if the data is stored in CPU memory!"));
-  Assert(i < n_elements, ExcIndexRange(i, 0, n_elements));
 
   return *(starting_element + i);
 }
diff --git a/tests/cuda/array_view_wrong_memory.cu b/tests/cuda/array_view_wrong_memory.cu
index 81bad10ed9..5516431222 100644
--- a/tests/cuda/array_view_wrong_memory.cu
+++ b/tests/cuda/array_view_wrong_memory.cu
@@ -60,5 +60,11 @@ main(int argc, char **argv)
   deallog << "Testing device ArrayView with device memory" << std::endl;
   ArrayView<unsigned int, MemorySpace::CUDA> view_4(dummy_cuda.get(), 2);
 
+  deallog << "Testing host ArrayView to a nullptr with length 0" << std::endl;
+  ArrayView<unsigned int, MemorySpace::Host> view_5(nullptr, 0);
+
+  deallog << "Testing device ArrayView to a nullptr with length 0" << std::endl;
+  ArrayView<unsigned int, MemorySpace::CUDA> view_6(nullptr, 0);
+
   return 0;
 }
diff --git a/tests/cuda/array_view_wrong_memory.debug.output b/tests/cuda/array_view_wrong_memory.debug.output
index a714815cf8..bc64f38489 100644
--- a/tests/cuda/array_view_wrong_memory.debug.output
+++ b/tests/cuda/array_view_wrong_memory.debug.output
@@ -6,7 +6,7 @@ DEAL::
 An error occurred in file <array_view.h> in function
     dealii::ArrayView<ElementType, MemorySpaceType>::ArrayView(dealii::ArrayView<ElementType, MemorySpaceType>::value_type*, std::size_t) [with ElementType = unsigned int; MemorySpaceType = dealii::MemorySpace::CUDA; dealii::ArrayView<ElementType, MemorySpaceType>::value_type = unsigned int; std::size_t = long unsigned int]
 The violated condition was: 
-    internal::ArrayViewHelper::is_in_correct_memory_space<MemorySpaceType>( starting_element)
+    n_elements == 0 || internal::ArrayViewHelper::is_in_correct_memory_space<MemorySpaceType>( starting_element)
 Additional information: 
     The memory space indicated by the template parameter and the one derived from the pointer value do not match!
 --------------------------------------------------------
@@ -17,9 +17,11 @@ DEAL::
 An error occurred in file <array_view.h> in function
     dealii::ArrayView<ElementType, MemorySpaceType>::ArrayView(dealii::ArrayView<ElementType, MemorySpaceType>::value_type*, std::size_t) [with ElementType = unsigned int; MemorySpaceType = dealii::MemorySpace::Host; dealii::ArrayView<ElementType, MemorySpaceType>::value_type = unsigned int; std::size_t = long unsigned int]
 The violated condition was: 
-    internal::ArrayViewHelper::is_in_correct_memory_space<MemorySpaceType>( starting_element)
+    n_elements == 0 || internal::ArrayViewHelper::is_in_correct_memory_space<MemorySpaceType>( starting_element)
 Additional information: 
     The memory space indicated by the template parameter and the one derived from the pointer value do not match!
 --------------------------------------------------------
 
 DEAL::Testing device ArrayView with device memory
+DEAL::Testing host ArrayView to a nullptr with length 0
+DEAL::Testing device ArrayView to a nullptr with length 0