<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - Zero-sized array not Sfinae-failure in non-type template parameter"
   href="https://llvm.org/bugs/show_bug.cgi?id=28386">28386</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Zero-sized array not Sfinae-failure in non-type template parameter
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++11
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>lf-bt@thax.hardliners.org
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>#include <type_traits>

template <unsigned int... Is>
struct index_sequence {};

template <bool B> using Sfinae=char (*)[B]; // does not work with msvc+clang;
works with g++
//template <bool B> using Sfinae=char (*)[2*B-1]; // works with g++ and
clang;(msvc does strange things)
//template <bool B> using Sfinae=typename std::enable_if<B,int>::type; //
works.

template <unsigned int N,unsigned int... Is,typename =Sfinae<N==0>>
constexpr index_sequence<Is...> make_index_sequence(...)
{ return {}; }

template <unsigned int N,unsigned int... Is,typename =Sfinae<(N>0)>>
constexpr auto make_index_sequence(...)
  -> decltype(make_index_sequence<N-1,N-1,Is...>(index_sequence<>())) //
argument forces ADL
{ return {}; }

int main()
{
  index_sequence<0,1> t=make_index_sequence<2>(); 
}

----
clang++ will happily go from I=0 to I=4294967295 ... until it hits the template
instantiation limit.

According to my and g++'s understanding, using the first version should work,
as zero-size array should lead to an SFINAE failure, just like negative sized
arrays do.

Using the Sfinae-type as function argument instead of as template parameter,
all three versions compile fine, i.e. the zero sized array is treated as SFINAE
failure, e.g.:

  template <unsigned int N,unsigned int... Is>
  constexpr index_sequence<Is...> make_index_sequence(index_sequence<>
x={},Sfinae<N==0> =0)
  ...

  template <unsigned int N,unsigned int... Is>
  constexpr auto make_index_sequence(index_sequence<> x={},Sfinae<(N>0)> =0)
  ...


(MSVC's problem with the second version has been reported here:
<a href="https://connect.microsoft.com/VisualStudio/feedback/details/2881697">https://connect.microsoft.com/VisualStudio/feedback/details/2881697</a> )</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>