-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[Clang] Remove __is_referenceable builtin #123078
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: Nikolas Klauser (philnik777) Changes
Full diff: https://github.com/llvm/llvm-project/pull/123078.diff 7 Files Affected:
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index 2eb0777dbdc6c8..ab21970c8eb24d 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1694,10 +1694,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.
* ``__is_rvalue_reference`` (C++, Embarcadero)
* ``__is_same`` (C++, Embarcadero)
* ``__is_same_as`` (GCC): Synonym for ``__is_same``.
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c6bc95594f6133..110bee20023b0c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -93,6 +93,10 @@ C++ Specific Potentially Breaking Changes
few users and can be written as ``__is_same(__remove_cv(T), decltype(nullptr))``,
which GCC supports as well.
+- 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.
+
- Clang will now correctly diagnose as ill-formed a constant expression where an
enum without a fixed underlying type is set to a value outside the range of
the enumeration's values.
@@ -310,7 +314,7 @@ C++23 Feature Support
- Extend lifetime of temporaries in mem-default-init for P2718R0. Clang now fully
supports `P2718R0 Lifetime extension in range-based for loops <https://wg21.link/P2718R0>`_.
-
+
- ``__cpp_explicit_this_parameter`` is now defined. (#GH82780)
C++20 Feature Support
@@ -717,7 +721,7 @@ Improvements to Clang's diagnostics
- Clang now diagnoses dangling references for C++20's parenthesized aggregate initialization (#101957).
-- Fixed a bug where Clang would not emit ``-Wunused-private-field`` warnings when an unrelated class
+- Fixed a bug where Clang would not emit ``-Wunused-private-field`` warnings when an unrelated class
defined a defaulted comparison operator (#GH116270).
.. code-block:: c++
@@ -936,7 +940,7 @@ Bug Fixes to C++ Support
- Fixed an assertion failure caused by invalid default argument substitutions in non-defining
friend declarations. (#GH113324)
- Fix a crash caused by incorrect argument position in merging deduced template arguments. (#GH113659)
-- Fixed a parser crash when using pack indexing as a nested name specifier. (#GH119072)
+- Fixed a parser crash when using pack indexing as a nested name specifier. (#GH119072)
- Fixed a null pointer dereference issue when heuristically computing ``sizeof...(pack)`` expressions. (#GH81436)
- Fixed an assertion failure caused by mangled names with invalid identifiers. (#GH112205)
- Fixed an incorrect lambda scope of generic lambdas that caused Clang to crash when computing potential lambda
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 2c692c999bdff5..2724689956fe15 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -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)
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index fddb8a5729ee8c..43db715ac6d70f 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -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,
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 8dd72db8f5b4a2..be20ce1369fa3b 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -805,7 +805,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);
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 1e39d69e8b230f..34219e0235a74f 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -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();
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index 1b9e2ba6ff162f..b130024503101b 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -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));
}
};
|
You can test this locally with the following command:git-clang-format --diff 4562efc674a5b5e052abdfc40047e82a359d0df0 44a8c5297be6a24ae6d37bd478d8f7a1c30a2ffa --extensions cpp -- clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Parse/ParseExpr.cpp clang/lib/Sema/SemaExprCXX.cpp clang/test/SemaCXX/type-traits.cpp View the diff from clang-format here.diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 43db715ac6..1e9cebf9ce 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1775,63 +1775,31 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
Tok.isOneOf(
#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait,
#include "clang/Basic/TransformTypeTraits.def"
- tok::kw___is_abstract,
- tok::kw___is_aggregate,
- tok::kw___is_arithmetic,
- 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,
- tok::kw___is_const,
- tok::kw___is_constructible,
- tok::kw___is_convertible,
- tok::kw___is_convertible_to,
- tok::kw___is_destructible,
- tok::kw___is_empty,
- tok::kw___is_enum,
- tok::kw___is_floating_point,
- tok::kw___is_final,
- tok::kw___is_function,
- tok::kw___is_fundamental,
- tok::kw___is_integral,
- tok::kw___is_interface_class,
- tok::kw___is_literal,
- tok::kw___is_lvalue_expr,
- tok::kw___is_lvalue_reference,
- tok::kw___is_member_function_pointer,
- tok::kw___is_member_object_pointer,
- tok::kw___is_member_pointer,
- tok::kw___is_nothrow_assignable,
- tok::kw___is_nothrow_constructible,
- tok::kw___is_nothrow_convertible,
- tok::kw___is_nothrow_destructible,
- tok::kw___is_object,
- tok::kw___is_pod,
- tok::kw___is_pointer,
- tok::kw___is_polymorphic,
- tok::kw___is_reference,
- tok::kw___is_rvalue_expr,
- tok::kw___is_rvalue_reference,
- tok::kw___is_same,
- tok::kw___is_scalar,
- tok::kw___is_scoped_enum,
- tok::kw___is_sealed,
- tok::kw___is_signed,
- tok::kw___is_standard_layout,
- tok::kw___is_trivial,
+ tok::kw___is_abstract, tok::kw___is_aggregate,
+ tok::kw___is_arithmetic, 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, tok::kw___is_const,
+ tok::kw___is_constructible, tok::kw___is_convertible,
+ tok::kw___is_convertible_to, tok::kw___is_destructible,
+ tok::kw___is_empty, tok::kw___is_enum, tok::kw___is_floating_point,
+ tok::kw___is_final, tok::kw___is_function, tok::kw___is_fundamental,
+ tok::kw___is_integral, tok::kw___is_interface_class,
+ tok::kw___is_literal, tok::kw___is_lvalue_expr,
+ tok::kw___is_lvalue_reference, tok::kw___is_member_function_pointer,
+ tok::kw___is_member_object_pointer, tok::kw___is_member_pointer,
+ tok::kw___is_nothrow_assignable, tok::kw___is_nothrow_constructible,
+ tok::kw___is_nothrow_convertible, tok::kw___is_nothrow_destructible,
+ tok::kw___is_object, tok::kw___is_pod, tok::kw___is_pointer,
+ tok::kw___is_polymorphic, tok::kw___is_reference,
+ tok::kw___is_rvalue_expr, tok::kw___is_rvalue_reference,
+ tok::kw___is_same, tok::kw___is_scalar, tok::kw___is_scoped_enum,
+ tok::kw___is_sealed, tok::kw___is_signed,
+ tok::kw___is_standard_layout, tok::kw___is_trivial,
tok::kw___is_trivially_equality_comparable,
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,
- tok::kw___is_volatile
- ))
+ 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, tok::kw___is_volatile))
// GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the
// name of struct templates, but some are keywords in GCC >= 4.3
// and Clang. Therefore, when we see the token sequence "struct
|
Should we deprecate it in 20, remove in 21? almost is not 0 |
What exactly would you like to do? Make |
Eh, it is pretty effectively 0. If you subtract ones that are wrapped in '#if 0' or part of libcxx, the first two pages have like 3 entries on them.
I would just say 'document for a release' then remove, but that is a better idea. perhaps |
Works for me |
I took a look at the projects I could find using it on sourcegraph and I agree that we should be fine to document for a release and then remove. |
`__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. See #123078
3be2249
to
44a8c52
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but please update the patch summary when landing to mention that this was deprecated in Clang 20.
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/195/builds/4539 Here is the relevant piece of the build log for the reference
|
`__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.
__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.