-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Description
Clang currently reports that __is_array(T[0]) is true, which leads to std::is_array<T[0]> being true as well.
- GCC says it's false, MSVC says it's true (see Godbolt).
- The Standard says that
T[0]is downright ill-formed: http://eel.is/c++draft/dcl.array#1
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:
- Errors out when we try to form
T[0]since it's ill-formed, or - At least not report that
T[0]is an array from its__is_arraybuiltin (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:
+ // We don't want to report T[0] as being an array type.
+ if (ConstantArrayType const* CAT = C.getAsConstantArrayType(T))
+ return CAT->getSize() != 0;
return T->isArrayType();
case UTT_IsPointer:
return T->isAnyPointerType();
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index d576e4388d6f..ce45d1857179 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -23,6 +23,7 @@ typedef Empty EmptyArMB[1][2];
typedef int Int;
typedef Int IntAr[10];
typedef Int IntArNB[];
+typedef Int IntArZero[0];
class Statics { static int priv; static NonPOD np; };
union EmptyUnion {};
union IncompleteUnion; // expected-note {{forward declaration of 'IncompleteUnion'}}
@@ -673,7 +674,8 @@ void is_array()
{
int t01[T(__is_array(IntAr))];
int t02[T(__is_array(IntArNB))];
- int t03[T(__is_array(UnionAr))];
+ int t03[F(__is_array(IntArZero))];
+ int t04[T(__is_array(UnionAr))];
int t10[F(__is_array(void))];
int t11[F(__is_array(cvoid))];