[Clang] Remove __is_referenceable builtin (#123078)

`__is_referenceable` is almost unused in the wild, and the few cases I
was able to find had checks around them. Since the places in the
standard library where `__is_referenceable` is used have bespoke
builtins, it doesn't make a ton of sense to keep this builtin around.

`__is_referenceable` has been documented as deprecated in Clang 20.
This commit is contained in:
Nikolas Klauser 2025-02-06 15:04:23 +01:00 committed by GitHub
parent b74176a3a2
commit 9598f74133
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 4 additions and 42 deletions

View File

@ -1803,10 +1803,6 @@ The following type trait primitives are supported by Clang. Those traits marked
* ``__is_pointer_interconvertible_base_of`` (C++, GNU, Microsoft)
* ``__is_polymorphic`` (C++, GNU, Microsoft, Embarcadero)
* ``__is_reference`` (C++, Embarcadero)
* ``__is_referenceable`` (C++, GNU, Microsoft, Embarcadero):
Returns true if a type is referenceable, and false otherwise. A referenceable
type is a type that's either an object type, a reference type, or an unqualified
function type. This trait is deprecated and will be removed in Clang 21.
* ``__is_rvalue_reference`` (C++, Embarcadero)
* ``__is_same`` (C++, Embarcadero)
* ``__is_same_as`` (GCC): Synonym for ``__is_same``.

View File

@ -42,6 +42,10 @@ C/C++ Language Potentially Breaking Changes
C++ Specific Potentially Breaking Changes
-----------------------------------------
- The type trait builtin ``__is_referenceable`` has been removed, since it has
very few users and all the type traits that could benefit from it in the
standard library already have their own bespoke builtins.
ABI Changes in This Version
---------------------------

View File

@ -546,7 +546,6 @@ TYPE_TRAIT_1(__is_trivially_equality_comparable, IsTriviallyEqualityComparable,
TYPE_TRAIT_1(__is_bounded_array, IsBoundedArray, KEYCXX)
TYPE_TRAIT_1(__is_unbounded_array, IsUnboundedArray, KEYCXX)
TYPE_TRAIT_1(__is_scoped_enum, IsScopedEnum, KEYCXX)
TYPE_TRAIT_1(__is_referenceable, IsReferenceable, KEYCXX)
TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
TYPE_TRAIT_2(__reference_constructs_from_temporary, ReferenceConstructsFromTemporary, KEYCXX)

View File

@ -1813,7 +1813,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
tok::kw___is_pointer,
tok::kw___is_polymorphic,
tok::kw___is_reference,
tok::kw___is_referenceable,
tok::kw___is_rvalue_expr,
tok::kw___is_rvalue_reference,
tok::kw___is_same,

View File

@ -824,7 +824,6 @@ bool Parser::isRevertibleTypeTrait(const IdentifierInfo *II,
REVERTIBLE_TYPE_TRAIT(__is_pointer);
REVERTIBLE_TYPE_TRAIT(__is_polymorphic);
REVERTIBLE_TYPE_TRAIT(__is_reference);
REVERTIBLE_TYPE_TRAIT(__is_referenceable);
REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr);
REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference);
REVERTIBLE_TYPE_TRAIT(__is_same);

View File

@ -5032,7 +5032,6 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
case UTT_IsArray:
case UTT_IsBoundedArray:
case UTT_IsPointer:
case UTT_IsReferenceable:
case UTT_IsLvalueReference:
case UTT_IsRvalueReference:
case UTT_IsMemberFunctionPointer:
@ -5679,8 +5678,6 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
return T.isTriviallyRelocatableType(C);
case UTT_IsBitwiseCloneable:
return T.isBitwiseCloneableType(C);
case UTT_IsReferenceable:
return T.isReferenceable();
case UTT_CanPassInRegs:
if (CXXRecordDecl *RD = T->getAsCXXRecordDecl(); RD && !T.hasQualifiers())
return RD->canPassInRegisters();

View File

@ -779,36 +779,6 @@ void is_unbounded_array(int n) {
(void)__is_unbounded_array(decltype(t32)); // expected-error{{variable length arrays are not supported in '__is_unbounded_array'}}
}
void is_referenceable() {
static_assert(__is_referenceable(int));
static_assert(__is_referenceable(const int));
static_assert(__is_referenceable(volatile int));
static_assert(__is_referenceable(const volatile int));
static_assert(__is_referenceable(int *));
static_assert(__is_referenceable(int &));
static_assert(__is_referenceable(int &&));
static_assert(__is_referenceable(int (*)()));
static_assert(__is_referenceable(int (&)()));
static_assert(__is_referenceable(int(&&)()));
static_assert(__is_referenceable(IntAr));
static_assert(__is_referenceable(IntArNB));
static_assert(__is_referenceable(decltype(nullptr)));
static_assert(__is_referenceable(Empty));
static_assert(__is_referenceable(Union));
static_assert(__is_referenceable(Derives));
static_assert(__is_referenceable(Enum));
static_assert(__is_referenceable(EnumClass));
static_assert(__is_referenceable(int Empty::*));
static_assert(__is_referenceable(int(Empty::*)()));
static_assert(__is_referenceable(AnIncompleteType));
static_assert(__is_referenceable(struct AnIncompleteType));
using function_type = void(int);
static_assert(__is_referenceable(function_type));
static_assert(!__is_referenceable(void));
}
template <typename T> void tmpl_func(T&) {}
template <typename T> struct type_wrapper {
@ -4739,8 +4709,6 @@ struct CheckAbominableFunction<M S::*> {
static_assert(__is_same(remove_cvref_t<M>, M));
static_assert(__is_same(remove_pointer_t<M>, M));
static_assert(__is_same(remove_reference_t<M>, M));
static_assert(!__is_referenceable(M));
}
};