[LLVMbugs] [Bug 16583] New: template deduction error with array types

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Wed Jul 10 01:51:13 PDT 2013


            Bug ID: 16583
           Summary: template deduction error with array types
           Product: clang
           Version: trunk
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++
          Assignee: unassignedclangbugs at nondot.org
          Reporter: andyg1001 at hotmail.co.uk
                CC: dgregor at apple.com, llvmbugs at cs.uiuc.edu
    Classification: Unclassified

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;
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

You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20130710/d892ba36/attachment.html>

More information about the llvm-bugs mailing list