[clang] [Clang] Improve type traits recognition in `__has_builtin` (PR #111516)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 8 11:24:15 PDT 2024
https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/111516
>From 94874b7acb9ce763f502b74bc50d983ee3012d53 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Tue, 8 Oct 2024 12:28:24 +0200
Subject: [PATCH 1/2] [Clang] Improve type traits recognition in
`__has_builtin`
`__has_builtin` was relying on reversible identifiers and
string matching to recognize builtin-type traits, leading
to some newer type traits not being recognized.
Fixes #111477
---
clang/docs/ReleaseNotes.rst | 2 +
clang/include/clang/Basic/TokenKinds.def | 5 ++-
clang/lib/Lex/PPMacroExpansion.cpp | 52 ++++++++++++++---------
clang/test/Preprocessor/feature_tests.cpp | 5 ++-
4 files changed, 43 insertions(+), 21 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index bd86fff6dd03fa..c1122e1180ab91 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -408,6 +408,8 @@ Bug Fixes to Compiler Builtins
- ``__noop`` can now be used in a constant expression. (#GH102064)
+- Fix ``__has_builtin`` incorrectly returning ``false`` for some C++ type traits. (#GH111477)
+
Bug Fixes to Attribute Support
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index c5c3838407cf48..fdfb35de9cf287 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -64,6 +64,10 @@
#ifndef EXPRESSION_TRAIT
#define EXPRESSION_TRAIT(I,E,K) KEYWORD(I,K)
#endif
+#ifndef TRANSFORM_TYPE_TRAIT_DEF
+#define TRANSFORM_TYPE_TRAIT_DEF(K, Trait) KEYWORD(__##Trait, KEYCXX)
+#endif
+
#ifndef ALIAS
#define ALIAS(X,Y,Z)
#endif
@@ -534,7 +538,6 @@ TYPE_TRAIT_1(__has_unique_object_representations,
TYPE_TRAIT_2(__is_layout_compatible, IsLayoutCompatible, KEYCXX)
TYPE_TRAIT_2(__is_pointer_interconvertible_base_of, IsPointerInterconvertibleBaseOf, KEYCXX)
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) KEYWORD(__##Trait, KEYCXX)
#include "clang/Basic/TransformTypeTraits.def"
// Clang-only C++ Type Traits
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 27d09b4c8ee744..d48bb8a9a9cded 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1616,6 +1616,34 @@ asm("_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_"
"RSt8ios_basecPK2tmPKcSB_");
#endif
+static bool IsBuiltinTrait(Token &Tok) {
+
+#define TYPE_TRAIT_1(Spelling, Name, Key) \
+ case tok::kw_##Spelling: \
+ return true;
+#define TYPE_TRAIT_2(Spelling, Name, Key) \
+ case tok::kw_##Spelling: \
+ return true;
+#define TYPE_TRAIT_N(Spelling, Name, Key) \
+ case tok::kw_##Spelling: \
+ return true;
+#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) \
+ case tok::kw_##Spelling: \
+ return true;
+#define EXPRESSION_TRAIT(Spelling, Name, Key) \
+ case tok::kw_##Spelling: \
+ return true;
+#define TRANSFORM_TYPE_TRAIT_DEF(K, Spelling) \
+ case tok::kw___##Spelling: \
+ return true;
+
+ switch (Tok.getKind()) {
+ default:
+ return false;
+#include "clang/Basic/TokenKinds.def"
+ }
+}
+
/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
/// as a builtin macro, handle it and return the next token as 'Tok'.
void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
@@ -1814,25 +1842,11 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
getTargetInfo().getTargetOpts().FeatureMap);
}
return true;
- } else if (II->getTokenID() != tok::identifier ||
- II->hasRevertedTokenIDToIdentifier()) {
- // Treat all keywords that introduce a custom syntax of the form
- //
- // '__some_keyword' '(' [...] ')'
- //
- // as being "builtin functions", even if the syntax isn't a valid
- // function call (for example, because the builtin takes a type
- // argument).
- if (II->getName().starts_with("__builtin_") ||
- II->getName().starts_with("__is_") ||
- II->getName().starts_with("__has_"))
- return true;
- return llvm::StringSwitch<bool>(II->getName())
- .Case("__array_rank", true)
- .Case("__array_extent", true)
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) .Case("__" #Trait, true)
-#include "clang/Basic/TransformTypeTraits.def"
- .Default(false);
+ } else if (IsBuiltinTrait(Tok)) {
+ return true;
+ } else if (II->getTokenID() != tok::identifier &&
+ II->getName().starts_with("__builtin_")) {
+ return true;
} else {
return llvm::StringSwitch<bool>(II->getName())
// Report builtin templates as being builtins.
diff --git a/clang/test/Preprocessor/feature_tests.cpp b/clang/test/Preprocessor/feature_tests.cpp
index 00421d74e6282a..a73d7dbe716d13 100644
--- a/clang/test/Preprocessor/feature_tests.cpp
+++ b/clang/test/Preprocessor/feature_tests.cpp
@@ -31,7 +31,10 @@
!__has_builtin(__underlying_type) || \
!__has_builtin(__is_trivial) || \
!__has_builtin(__is_same_as) || \
- !__has_builtin(__has_unique_object_representations)
+ !__has_builtin(__has_unique_object_representations) || \
+ !__has_builtin(__is_trivially_equality_comparable) || \
+ !__has_builtin(__reference_constructs_from_temporary) || \
+ !__has_builtin(__reference_binds_to_temporary)
#error Clang should have these
#endif
>From b684ba401edade208bebbaeae67b6200498dcfc2 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Tue, 8 Oct 2024 19:26:58 +0200
Subject: [PATCH 2/2] add test
---
clang/test/Preprocessor/feature_tests.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/test/Preprocessor/feature_tests.cpp b/clang/test/Preprocessor/feature_tests.cpp
index a73d7dbe716d13..13e2a9a261b667 100644
--- a/clang/test/Preprocessor/feature_tests.cpp
+++ b/clang/test/Preprocessor/feature_tests.cpp
@@ -34,7 +34,8 @@
!__has_builtin(__has_unique_object_representations) || \
!__has_builtin(__is_trivially_equality_comparable) || \
!__has_builtin(__reference_constructs_from_temporary) || \
- !__has_builtin(__reference_binds_to_temporary)
+ !__has_builtin(__reference_binds_to_temporary) || \
+ !__has_builtin(__reference_converts_from_temporary)
#error Clang should have these
#endif
More information about the cfe-commits
mailing list