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