Clang reports that __is_array(T[0]) is true (original) (raw)

Clang currently reports that __is_array(T[0]) is true, which leads to std::is_array<T[0]> being true as well.

Since it's ill-formed, I guess Clang is technically conforming, however it still leads to code like this surprisingly compiling with Clang:

static_assert(!std::is_bounded_array_v<T[0]>);
static_assert(!std::is_unbounded_array_v<T[0]>);
static_assert(std::is_array_v<T[0]>);

So it looks like T[0] is neither a bounded array nor an unbounded array, but it is an array, which is quite confusing. I would suggest Clang either:

  1. Errors out when we try to form T[0] since it's ill-formed, or
  2. At least not report that T[0] is an array from its __is_array builtin (patch provided for this)

Also note that Clang will not match a partial specialization like template <class T, size_t N> struct foo<T[N]> { ... }; when instantiating it with T[0], which seems to support the fact that we really don't want to treat T[0] as an array type.

Here's a potential patch that changes __is_array(T[0]) to false, but I suspect we may want a deeper fix in the compiler.

diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index f360dc6e1a23..c7178e097213 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4870,6 +4870,9 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, case UTT_IsFloatingPoint: return T->isFloatingType(); case UTT_IsArray: