This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbd3f48eefc11: [clang] adds `__is_bounded_array` and 
`__is_unbounded_array` as builtins (authored by cjdb).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D135175/new/

https://reviews.llvm.org/D135175

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/SemaCXX/type-traits.cpp

Index: clang/test/SemaCXX/type-traits.cpp
===================================================================
--- clang/test/SemaCXX/type-traits.cpp
+++ clang/test/SemaCXX/type-traits.cpp
@@ -702,6 +702,70 @@
   int t31[F(__is_array(cvoid*))];
 }
 
+void is_bounded_array(int n) {
+  static_assert(__is_bounded_array(IntAr), "");
+  static_assert(!__is_bounded_array(IntArNB), "");
+  static_assert(__is_bounded_array(UnionAr), "");
+
+  static_assert(!__is_bounded_array(void), "");
+  static_assert(!__is_bounded_array(cvoid), "");
+  static_assert(!__is_bounded_array(float), "");
+  static_assert(!__is_bounded_array(double), "");
+  static_assert(!__is_bounded_array(long double), "");
+  static_assert(!__is_bounded_array(bool), "");
+  static_assert(!__is_bounded_array(char), "");
+  static_assert(!__is_bounded_array(signed char), "");
+  static_assert(!__is_bounded_array(unsigned char), "");
+  static_assert(!__is_bounded_array(wchar_t), "");
+  static_assert(!__is_bounded_array(short), "");
+  static_assert(!__is_bounded_array(unsigned short), "");
+  static_assert(!__is_bounded_array(int), "");
+  static_assert(!__is_bounded_array(unsigned int), "");
+  static_assert(!__is_bounded_array(long), "");
+  static_assert(!__is_bounded_array(unsigned long), "");
+  static_assert(!__is_bounded_array(Union), "");
+  static_assert(!__is_bounded_array(Derives), "");
+  static_assert(!__is_bounded_array(ClassType), "");
+  static_assert(!__is_bounded_array(Enum), "");
+  static_assert(!__is_bounded_array(void *), "");
+  static_assert(!__is_bounded_array(cvoid *), "");
+
+  int t32[n];
+  (void)__is_bounded_array(decltype(t32)); // expected-error{{variable length arrays are not supported for '__is_bounded_array'}}
+}
+
+void is_unbounded_array(int n) {
+  static_assert(!__is_unbounded_array(IntAr), "");
+  static_assert(__is_unbounded_array(IntArNB), "");
+  static_assert(!__is_unbounded_array(UnionAr), "");
+
+  static_assert(!__is_unbounded_array(void), "");
+  static_assert(!__is_unbounded_array(cvoid), "");
+  static_assert(!__is_unbounded_array(float), "");
+  static_assert(!__is_unbounded_array(double), "");
+  static_assert(!__is_unbounded_array(long double), "");
+  static_assert(!__is_unbounded_array(bool), "");
+  static_assert(!__is_unbounded_array(char), "");
+  static_assert(!__is_unbounded_array(signed char), "");
+  static_assert(!__is_unbounded_array(unsigned char), "");
+  static_assert(!__is_unbounded_array(wchar_t), "");
+  static_assert(!__is_unbounded_array(short), "");
+  static_assert(!__is_unbounded_array(unsigned short), "");
+  static_assert(!__is_unbounded_array(int), "");
+  static_assert(!__is_unbounded_array(unsigned int), "");
+  static_assert(!__is_unbounded_array(long), "");
+  static_assert(!__is_unbounded_array(unsigned long), "");
+  static_assert(!__is_unbounded_array(Union), "");
+  static_assert(!__is_unbounded_array(Derives), "");
+  static_assert(!__is_unbounded_array(ClassType), "");
+  static_assert(!__is_unbounded_array(Enum), "");
+  static_assert(!__is_unbounded_array(void *), "");
+  static_assert(!__is_unbounded_array(cvoid *), "");
+
+  int t32[n];
+  (void)__is_unbounded_array(decltype(t32)); // expected-error{{variable length arrays are not supported for '__is_unbounded_array'}}
+}
+
 template <typename T> void tmpl_func(T&) {}
 
 template <typename T> struct type_wrapper {
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -2627,12 +2627,10 @@
 
   if (T->isVariableArrayType() && !Context.getTargetInfo().isVLASupported()) {
     // CUDA device code and some other targets don't support VLAs.
-    targetDiag(Loc, (getLangOpts().CUDA && getLangOpts().CUDAIsDevice)
-                        ? diag::err_cuda_vla
-                        : diag::err_vla_unsupported)
-        << ((getLangOpts().CUDA && getLangOpts().CUDAIsDevice)
-                ? CurrentCUDATarget()
-                : CFT_InvalidTarget);
+    bool IsCUDADevice = (getLangOpts().CUDA && getLangOpts().CUDAIsDevice);
+    targetDiag(Loc,
+               IsCUDADevice ? diag::err_cuda_vla : diag::err_vla_unsupported)
+        << (IsCUDADevice ? CurrentCUDATarget() : 0);
   }
 
   // If this is not C99, diagnose array size modifiers on non-VLAs.
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -21,11 +21,13 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/AlignedAllocation.h"
 #include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TokenKinds.h"
 #include "clang/Basic/TypeTraits.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/DeclSpec.h"
@@ -4756,6 +4758,7 @@
   case UTT_IsIntegral:
   case UTT_IsFloatingPoint:
   case UTT_IsArray:
+  case UTT_IsBoundedArray:
   case UTT_IsPointer:
   case UTT_IsLvalueReference:
   case UTT_IsRvalueReference:
@@ -4782,6 +4785,7 @@
   case UTT_IsConst:
   case UTT_IsVolatile:
   case UTT_IsSigned:
+  case UTT_IsUnboundedArray:
   case UTT_IsUnsigned:
 
   // This type trait always returns false, checking the type is moot.
@@ -4901,6 +4905,22 @@
     return T->isFloatingType();
   case UTT_IsArray:
     return T->isArrayType();
+  case UTT_IsBoundedArray:
+    if (!T->isVariableArrayType()) {
+      return T->isArrayType() && !T->isIncompleteArrayType();
+    }
+
+    Self.Diag(KeyLoc, diag::err_vla_unsupported)
+        << 1 << tok::kw___is_bounded_array;
+    return false;
+  case UTT_IsUnboundedArray:
+    if (!T->isVariableArrayType()) {
+      return T->isIncompleteArrayType();
+    }
+
+    Self.Diag(KeyLoc, diag::err_vla_unsupported)
+        << 1 << tok::kw___is_unbounded_array;
+    return false;
   case UTT_IsPointer:
     return T->isAnyPointerType();
   case UTT_IsLvalueReference:
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -1067,6 +1067,7 @@
           REVERTIBLE_TYPE_TRAIT(__is_arithmetic);
           REVERTIBLE_TYPE_TRAIT(__is_array);
           REVERTIBLE_TYPE_TRAIT(__is_assignable);
+          REVERTIBLE_TYPE_TRAIT(__is_bounded_array);
           REVERTIBLE_TYPE_TRAIT(__is_base_of);
           REVERTIBLE_TYPE_TRAIT(__is_class);
           REVERTIBLE_TYPE_TRAIT(__is_complete_type);
@@ -1109,6 +1110,7 @@
           REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable);
           REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible);
           REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable);
+          REVERTIBLE_TYPE_TRAIT(__is_unbounded_array);
           REVERTIBLE_TYPE_TRAIT(__is_union);
           REVERTIBLE_TYPE_TRAIT(__is_unsigned);
           REVERTIBLE_TYPE_TRAIT(__is_void);
Index: clang/lib/Parse/ParseDeclCXX.cpp
===================================================================
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -1579,6 +1579,7 @@
           tok::kw___is_array,
           tok::kw___is_assignable,
           tok::kw___is_base_of,
+          tok::kw___is_bounded_array,
           tok::kw___is_class,
           tok::kw___is_complete_type,
           tok::kw___is_compound,
@@ -1620,6 +1621,7 @@
           tok::kw___is_trivially_assignable,
           tok::kw___is_trivially_constructible,
           tok::kw___is_trivially_copyable,
+          tok::kw___is_unbounded_array,
           tok::kw___is_union,
           tok::kw___is_unsigned,
           tok::kw___is_void,
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -518,6 +518,8 @@
 
 // Clang-only C++ Type Traits
 TYPE_TRAIT_1(__is_trivially_relocatable, IsTriviallyRelocatable, KEYCXX)
+TYPE_TRAIT_1(__is_bounded_array, IsBoundedArray, KEYCXX)
+TYPE_TRAIT_1(__is_unbounded_array, IsUnboundedArray, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 
 // Embarcadero Expression Traits
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -147,7 +147,7 @@
   "variable length array folded to constant array as an extension">,
   InGroup<GNUFoldingConstant>;
 def err_vla_unsupported : Error<
-  "variable length arrays are not supported for the current target">;
+  "variable length arrays are not supported for %select{the current target|'%1'}0">;
 def note_vla_unsupported : Note<
   "variable length arrays are not supported for the current target">;
 
Index: clang/docs/LanguageExtensions.rst
===================================================================
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -1392,6 +1392,7 @@
 * ``__is_array`` (C++, Embarcadero)
 * ``__is_assignable`` (C++, MSVC 2015)
 * ``__is_base_of`` (C++, GNU, Microsoft, Embarcadero)
+* ``__is_bounded_array`` (C++, GNU, Microsoft, Embarcadero)
 * ``__is_class`` (C++, GNU, Microsoft, Embarcadero)
 * ``__is_complete_type(type)`` (Embarcadero):
   Return ``true`` if ``type`` is a complete type.
@@ -1454,6 +1455,7 @@
   functionally equivalent to copying the underlying bytes and then dropping the
   source object on the floor. This is true of trivial types and types which
   were made trivially relocatable via the ``clang::trivial_abi`` attribute.
+* ``__is_unbounded_array`` (C++, GNU, Microsoft, Embarcadero)
 * ``__is_union`` (C++, GNU, Microsoft, Embarcadero)
 * ``__is_unsigned`` (C++, Embarcadero):
   Returns false for enumeration types. Note, before Clang 13, returned true for
@@ -4245,7 +4247,7 @@
 
   #pragma clang attribute pop
 
-A single push directive can contain multiple attributes, however, 
+A single push directive can contain multiple attributes, however,
 only one syntax style can be used within a single directive:
 
 .. code-block:: c++
@@ -4255,7 +4257,7 @@
   void function1(); // The function now has the [[noreturn]] and [[noinline]] attributes
 
   #pragma clang attribute pop
-  
+
   #pragma clang attribute push (__attribute((noreturn, noinline)), apply_to = function)
 
   void function2(); // The function now has the __attribute((noreturn)) and __attribute((noinline)) attributes
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to