Out-of-line definitions of destructors for class templates result in warnings on Clang 12

Issue #490 resolved
Amir Kamil created an issue

When compiling with -Wall -Werror -pedantic on Clang 12/MacOS, the definitions of the destructors for atomic_domain_untyped<size,bit_flavor> and device_allocator_core<cuda_device> result in the following errors:

/usr/bin/clang++ -std=c++17 -Wall -pedantic -Werror -Wall   -D_GNU_SOURCE=1 -DGASNET_SEQ     -I/Users/akamil/work/upcxx/bld/GASNet-stable -I/Users/akamil/work/upcxx/bld/GASNet-stable/smp-conduit -I/Users/akamil/work/upcxx/bld/GASNet-stable/other   -I/Users/akamil/work/upcxx/bld/GASNet-stable/extended-ref/vis -I/Users/akamil/work/upcxx/bld/GASNet-stable/extended-ref/coll -I/Users/akamil/work/upcxx/bld/GASNet-stable/extended-ref/ratomic -I/Users/akamil/work/upcxx/bld/GASNet-stable/extended-ref -I/Users/akamil/work/upcxx/bld/GASNet-stable/other/kinds -I/Users/akamil/work/upcxx/bld/gasnet.debug   -g -O0   -Wno-unused -Wunused-result -Wno-unused-parameter -Wno-address     -DUPCXXI_ASSERT_ENABLED=1 -DUPCXXI_BACKEND=1 -DUPCXXI_BACKEND_GASNET_SEQ=1 -I/Users/akamil/work/upcxx/bld/upcxx.assert1.optlev0.dbgsym1.gasnet_seq.smp/include -I/Users/akamil/work/upcxx/bld/upcxx.assert1.optlev0.dbgsym1.gasnet_seq.smp/gen_include   -c /Users/akamil/work/upcxx/src/./atomic.cpp -o atomic.o
/Users/akamil/work/upcxx/src/./atomic.cpp:193:54: error: ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~' [-Werror,-Wdtor-name]
upcxx::detail::atomic_domain_untyped<size,bit_flavor>::~atomic_domain_untyped() {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
                                                     ::atomic_domain_untyped
1 error generated.
/usr/bin/clang++ -std=c++17 -Wall -pedantic -Werror -Wall   -D_GNU_SOURCE=1 -DGASNET_PAR -D_REENTRANT    -I/Users/akamil/work/upcxx/bld/GASNet-stable -I/Users/akamil/work/upcxx/bld/GASNet-stable/udp-conduit -I/Users/akamil/work/upcxx/bld/GASNet-stable/other -I/Users/akamil/work/upcxx/bld/GASNet-stable/other/amudp -I/Users/akamil/work/upcxx/bld/gasnet.debug/other/amudp   -I/Users/akamil/work/upcxx/bld/GASNet-stable/extended-ref/vis -I/Users/akamil/work/upcxx/bld/GASNet-stable/extended-ref/coll -I/Users/akamil/work/upcxx/bld/GASNet-stable/extended-ref/ratomic -I/Users/akamil/work/upcxx/bld/GASNet-stable/extended-ref -I/Users/akamil/work/upcxx/bld/GASNet-stable/other/kinds -I/Users/akamil/work/upcxx/bld/gasnet.debug   -g -O0   -Wno-unused -Wunused-result -Wno-unused-parameter -Wno-address     -DUPCXXI_ASSERT_ENABLED=1 -DUPCXXI_BACKEND=1 -DUPCXXI_BACKEND_GASNET_PAR=1 -I/Users/akamil/work/upcxx/bld/upcxx.assert1.optlev0.dbgsym1.gasnet_par.udp/include -I/Users/akamil/work/upcxx/bld/upcxx.assert1.optlev0.dbgsym1.gasnet_par.udp/gen_include   -c /Users/akamil/work/upcxx/src/./cuda.cpp -o cuda.o
/Users/akamil/work/upcxx/src/./cuda.cpp:361:50: error: ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~' [-Werror,-Wdtor-name]
detail::device_allocator_core<upcxx::cuda_device>::~device_allocator_core() {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
                                                 ::device_allocator_core
1 error generated.

Possible fix:

diff --git a/src/atomic.cpp b/src/atomic.cpp
index f0ce6840..2e840680 100644
--- a/src/atomic.cpp
+++ b/src/atomic.cpp
@@ -190,7 +190,7 @@ void upcxx::detail::atomic_domain_untyped<size,bit_flavor>::destroy(entry_barrie
 }

 template<std::size_t size, int bit_flavor>
-upcxx::detail::atomic_domain_untyped<size,bit_flavor>::~atomic_domain_untyped() {
+upcxx::detail::atomic_domain_untyped<size,bit_flavor>::~atomic_domain_untyped<size,bit_flavor>() {
   if(backend::init_count > 0) { // we don't assert on leaks after finalization
     UPCXX_ASSERT_ALWAYS(
       atomic_gex_ops == 0,
diff --git a/src/cuda.cpp b/src/cuda.cpp
index 410433d6..601c1784 100644
--- a/src/cuda.cpp
+++ b/src/cuda.cpp
@@ -358,7 +358,7 @@ void detail::device_allocator_core<upcxx::cuda_device>::destroy() {
 }

 GASNETT_COLD
-detail::device_allocator_core<upcxx::cuda_device>::~device_allocator_core() {
+detail::device_allocator_core<upcxx::cuda_device>::~device_allocator_core<upcxx::cuda_device>() {
   if(upcxx::initialized()) {
     // The thread safety restriction of this call still applies when upcxx isn't
     // initialized, we just have no good way of asserting it so we conditionalize

Comments (6)

  1. Paul Hargrove

    With Xcode 12.5.1, I find that configure --with-cxxflags=-Wdtor-name is sufficient to reproduce these warnings.

  2. Dan Bonachea

    This issue is currently assigned to @Colin MacLean .

    Is anyone planning to attempt a fix by code freeze?

  3. Colin MacLean

    There is, unfortunately, not a perfect way to fix this issue. PR 381 would have added the template specification to the destructor names as in the patch proposed in the original issue. However, this syntax is erroneously rejected by EDG-based compilers such as the NVHPC and pre-LLVM Intel compilers.

    The Clang diagnostic is correct in its warning, as explained in the following post: https://stackoverflow.com/questions/68751682/is-a-class-templates-name-in-scope-for-a-qualified-out-of-line-destructors-def. This requirement appears to be the result of a language defect and the original syntax should be valid in C++23.

    To silence this warning without inlining the destructor, a workaround of creating a real_destructor() member function and calling it from an inline destructor was used in PR 382.

  4. Log in to comment