NVCC bug when trying simple Template Metaprogramming

At the end of this post is my code.

I’m working on emulating something similar to Concepts using the detector idiom proposed for standardization in Library Fundamentals 2 TS. Unfortunately, NVCC refuses to correctly compile the code when it’s within a CU file. When it’s a standard CPP file it gets compiled by the host compiler and all is good.

I have verified that this example compiles under:
gcc++ 4.7 and newer
clang++ 3.4 and newer
icpc 13.0 and newer
pgi 15.4 and newer

But somehow it still fails with NVCC.

I’m using CUDA 8.0 currently (v8.0.61)

the exact command it fails with is the first pass of the cuda frontend compiler (cudafe)

cudafe --allow_managed --m64 --gnu_version=40903 --c++11 -tused --no_remove_unneeded_entities --gen_c_file_name “mwe.cudafe1.c” --stub_file_name “mwe.cudafe1.stub.c” --gen_device_file_name “mwe.cudafe1.gpu” --nv_arch “compute_20” --gen_module_id_file --module_id_file_name “mwe.module_id” --include_file_name “mwe.fatbin.c” “mwe.cpp1.ii”

==============================

// compiled with:
//
// nvcc -std=c++11 <filename.cu>

// TMP bool types

template <typename T, T Val>
struct integral_constant {
  using type = T;
  static constexpr T value = Val;
};

template <bool B>
using bool_ = integral_constant<bool, B>;

using true_type = bool_<true>;
using false_type = bool_<false>;

// detector idiom

template <class...>
struct voider {
  using type = void;
};

template <class... T>
using void_t = typename voider<T...>::type;

template <class, template <class...> class Op, class... Args>
struct detector {
  using value_t = false_type;
};

template <template <class...> class Op, class... Args>
struct detector<void_t<Op<Args...>>, Op, Args...> {
  using value_t = true_type;
  using type = int;
};

// concepts

template <typename T>
T&& declval() noexcept;

template <typename T>
using IsAType = decltype(declval<T>());

// user code

int main()
{
  static_assert(detector<void, IsAType, int>::value_t::value,
                "int is somehow not a type");
  // this static_assert somehow fails but should NOT fail
}

Keep in mind, you can wrap things in code blocks by using [code] [/code ], just without the space between the last bracket there.

Out of curiosity, what’s the exact failure message that you’re receiving? Is it just the static assert failing or are things outright not even compiling?

The static_assert fails, which causes the compilation to abort immediately.

I’m able to reproduce the issue as described.

I haven’t researched it closely, but I certainly agree that if g++ can handle it, nvcc should be able to. I have access to CUDA 9 EA, so my normal next step would be to test it there. If it still fails, I would file a (internal) bug. You can short-circuit the process by filing your own bug at developer.nvidia.com if you wish.

Apparently this works on the CUDA 9 EA, but this is still bugfix worthy for 8, is it not?

It won’t get fixed for CUDA 8. Guaranteed. People who have a concern about this would be directed to use CUDA 9.

You’re welcome to file a bug though.