From: David Wells Date: Tue, 14 Jun 2022 20:23:48 +0000 (-0400) Subject: Fix the MPI window functions with clang. X-Git-Tag: v9.4.0-rc1~19^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F13975%2Fhead;p=dealii.git Fix the MPI window functions with clang. libc++ defines std::unique_ptr::reset() as _LIBCPP_INLINE_VISIBILITY void reset(nullptr_t = nullptr) _NOEXCEPT { pointer __tmp = __ptr_.first(); __ptr_.first() = nullptr; if (__tmp) __ptr_.second()(__tmp); } The result of this is that aligned_vector->elements.get() is nullptr at the point at which we call the deleter - hence this deleter won't work correctly. We can work around this by avoiding std::unique_ptr::get() and just using our own member variables or ptr, which are guaranteed to be valid since they will not be set to nullptr by std::unique_ptr::reset(). --- diff --git a/include/deal.II/base/aligned_vector.h b/include/deal.II/base/aligned_vector.h index 7913f06a31..e27b872b3e 100644 --- a/include/deal.II/base/aligned_vector.h +++ b/include/deal.II/base/aligned_vector.h @@ -1128,13 +1128,18 @@ AlignedVector::Deleter::MPISharedMemDeleterAction::delete_array( T * ptr) { (void)ptr; - Assert(aligned_vector->elements.get() == ptr, ExcInternalError()); + // It would be nice to assert that aligned_vector->elements.get() equals ptr, + // but it is not guaranteed to work: clang, for example, sets elements.get() + // to nullptr and then calls the deleter on a previously made copy. Hence we + // must assume here that elements.get() (which is managed by the unique_ptr) + // may be nullptr at this point. + // + // used_elements_end is a member variable of AlignedVector (i.e., we control + // it, not unique_ptr) so it is still set to its correct value. if (is_shmem_root) if (std::is_trivial::value == false) - for (T *p = aligned_vector->used_elements_end - 1; - p >= aligned_vector->elements.get(); - --p) + for (T *p = aligned_vector->used_elements_end - 1; p >= ptr; --p) p->~T(); int ierr;