<html>
    <head>
      <base href="http://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 --- - template deduction error with array types"
   href="http://llvm.org/bugs/show_bug.cgi?id=16583">16583</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>template deduction error with array types
          </td>
        </tr>

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

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

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </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++
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>andyg1001@hotmail.co.uk
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The following code fails on clang all the way up to r185997 due to applying the
wrong template specialisation where a type is a zero-sized array:


template <typename T> struct X                   { typedef T type; };
template <typename T> struct X<T[0]>             { typedef T type; };
template <typename T, unsigned S> struct X<T[S]> { typedef T type; };
template <typename T> struct X<T[]>              { typedef T type; };

template <typename, typename> struct is_same { enum { value = false }; };
template <typename T> struct is_same<T, T>   { enum { value = true  }; };

static_assert(is_same<X<int>::type, int>::value, "oops");
static_assert(is_same<X<int[]>::type, int>::value, "oops");
static_assert(is_same<X<int[1]>::type, int>::value, "oops");
static_assert(is_same<X<int[0]>::type, int>::value, "oops"); // fails


template <typename T> struct Y                   { enum { value = -2 }; };
template <typename T> struct Y<T[0]>             { enum { value =  0 }; };
template <typename T, unsigned S> struct Y<T[S]> { enum { value =  S }; };
template <typename T> struct Y<T[]>              { enum { value = -1 }; };

static_assert(Y<int>::value == -2, "oops");
static_assert(Y<int[]>::value == -1, "oops");
static_assert(Y<int[1]>::value == 1, "oops");
static_assert(Y<int[0]>::value == 0, "oops"); // fails


And the following code fails because the compiler thinks the call to "test" is
ambiguous where the parameter in the function call is an array type:


template <typename T>
int test(T*) { return 0; }

template <typename T, unsigned I>
char test(T(&)[I]) { return 1; }

int *i;
int j[10];

int a = test(i);
int b = test(j);              // fails; ambiguous call
int c = test((int[]){1,2,3});
int d = test("hello");        // fails; ambiguous call

struct Z {
  int *a;
  int b[1];
  int c[0];
} z;

static_assert(is_same<decltype(test(z.a)), int>::value, "oops");
static_assert(is_same<decltype(test(z.b)), char>::value, "oops"); // fails;
ambiguous
static_assert(is_same<decltype(test(z.c)), char>::value, "oops"); // fails (*)


The fail marked (*) is the only fail that is correct, I believe, since 'z.c'
must be decayed to a pointer for the function call.  This is also, in my
opinion, why clang doesn't report an ambiguous call in this case.

Apart from the use of static_assert/decltype in the test code, the same issues
exist in all C++ modes.

The code compiles fine under gcc -- except for the fail marked (*) as discussed
above.</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>