aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Chancellor <nathan@kernel.org>2024-04-03 18:39:53 +0200
committerGitHub <noreply@github.com>2024-04-03 18:39:53 +0200
commitcc308f60d41744b5920ec2e2e5b25e1273c8704b (patch)
tree7e8c7c706a686fb815a31ae2dd06e74b6906bb58
parent5b959310b0fae723bd119ed8815bf1cb1a8c67d4 (diff)
downloadllvm-cc308f60d41744b5920ec2e2e5b25e1273c8704b.zip
llvm-cc308f60d41744b5920ec2e2e5b25e1273c8704b.tar.gz
llvm-cc308f60d41744b5920ec2e2e5b25e1273c8704b.tar.bz2
[clang] Support __typeof_unqual__ in all C modes (#87392)
GCC has added __typeof_unqual__ to allow typeof_unqual to be used in all C modes (not just C23 and newer), similar to __typeof__ and typeof. https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=607d9d50ee44163cee621cd991600acaf78c2fee The Linux kernel would like to start using __typeof_unqual__ to strip type qualifiers such as address spaces from inputs to macros but cannot switch to C23 due to compiler version requirements. Match GCC and allow __typeof_unqual__ in all C modes. Closes: https://github.com/llvm/llvm-project/issues/76423 Link: https://lore.kernel.org/CAFULd4YG21NdF_qNVBGDtXO6xnaYFeRPvKicB=gpgUUqYE=4jw@mail.gmail.com/
-rw-r--r--clang/docs/ReleaseNotes.rst3
-rw-r--r--clang/include/clang/Basic/TokenKinds.def46
-rw-r--r--clang/test/Parser/c2x-typeof-ext-warns.c7
-rw-r--r--clang/test/SemaCXX/typeof_unqual.cpp5
4 files changed, 37 insertions, 24 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 096376a..e4c0e49 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -193,6 +193,9 @@ Non-comprehensive list of changes in this release
with support for any unsigned integer type. Like the previous builtins, these
new builtins are constexpr and may be used in constant expressions.
+- ``__typeof_unqual__`` is available in all C modes as an extension, which behaves
+ like ``typeof_unqual`` from C23, similar to ``__typeof__`` and ``typeof``.
+
New Compiler Flags
------------------
- ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 3a96f8a..800af0e 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -665,28 +665,30 @@ KEYWORD(__kindof , KEYOBJC)
// Alternate spelling for various tokens. There are GCC extensions in all
// languages, but should not be disabled in strict conformance mode.
-ALIAS("__alignof__" , __alignof , KEYALL)
-ALIAS("__asm" , asm , KEYALL)
-ALIAS("__asm__" , asm , KEYALL)
-ALIAS("__attribute__", __attribute, KEYALL)
-ALIAS("__complex" , _Complex , KEYALL)
-ALIAS("__complex__" , _Complex , KEYALL)
-ALIAS("__const" , const , KEYALL)
-ALIAS("__const__" , const , KEYALL)
-ALIAS("__decltype" , decltype , KEYCXX)
-ALIAS("__imag__" , __imag , KEYALL)
-ALIAS("__inline" , inline , KEYALL)
-ALIAS("__inline__" , inline , KEYALL)
-ALIAS("__nullptr" , nullptr , KEYCXX)
-ALIAS("__real__" , __real , KEYALL)
-ALIAS("__restrict" , restrict , KEYALL)
-ALIAS("__restrict__" , restrict , KEYALL)
-ALIAS("__signed" , signed , KEYALL)
-ALIAS("__signed__" , signed , KEYALL)
-ALIAS("__typeof" , typeof , KEYALL)
-ALIAS("__typeof__" , typeof , KEYALL)
-ALIAS("__volatile" , volatile , KEYALL)
-ALIAS("__volatile__" , volatile , KEYALL)
+ALIAS("__alignof__" , __alignof , KEYALL)
+ALIAS("__asm" , asm , KEYALL)
+ALIAS("__asm__" , asm , KEYALL)
+ALIAS("__attribute__" , __attribute , KEYALL)
+ALIAS("__complex" , _Complex , KEYALL)
+ALIAS("__complex__" , _Complex , KEYALL)
+ALIAS("__const" , const , KEYALL)
+ALIAS("__const__" , const , KEYALL)
+ALIAS("__decltype" , decltype , KEYCXX)
+ALIAS("__imag__" , __imag , KEYALL)
+ALIAS("__inline" , inline , KEYALL)
+ALIAS("__inline__" , inline , KEYALL)
+ALIAS("__nullptr" , nullptr , KEYCXX)
+ALIAS("__real__" , __real , KEYALL)
+ALIAS("__restrict" , restrict , KEYALL)
+ALIAS("__restrict__" , restrict , KEYALL)
+ALIAS("__signed" , signed , KEYALL)
+ALIAS("__signed__" , signed , KEYALL)
+ALIAS("__typeof" , typeof , KEYALL)
+ALIAS("__typeof__" , typeof , KEYALL)
+ALIAS("__typeof_unqual" , typeof_unqual, KEYALL)
+ALIAS("__typeof_unqual__", typeof_unqual, KEYALL)
+ALIAS("__volatile" , volatile , KEYALL)
+ALIAS("__volatile__" , volatile , KEYALL)
// Type nullability.
KEYWORD(_Nonnull , KEYALL)
diff --git a/clang/test/Parser/c2x-typeof-ext-warns.c b/clang/test/Parser/c2x-typeof-ext-warns.c
index 3871844..7a1f673 100644
--- a/clang/test/Parser/c2x-typeof-ext-warns.c
+++ b/clang/test/Parser/c2x-typeof-ext-warns.c
@@ -12,9 +12,12 @@
// standards before C23, and Clang has followed suit. Neither compiler exposes
// 'typeof_unqual' as a non-conforming extension.
-// Show what happens with the underscored version of the keyword, which is a
-// conforming extension.
+// Show what happens with the underscored version of the keywords, which are
+// conforming extensions.
__typeof__(int) i = 12;
+__typeof(int) _i = 12;
+__typeof_unqual__(int) u = 12;
+__typeof_unqual(int) _u = 12;
// Show what happens with a regular 'typeof' use.
typeof(i) j = 12; // c11-error {{expected function body after function declarator}} \
diff --git a/clang/test/SemaCXX/typeof_unqual.cpp b/clang/test/SemaCXX/typeof_unqual.cpp
new file mode 100644
index 0000000..335e579
--- /dev/null
+++ b/clang/test/SemaCXX/typeof_unqual.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typeof_unqual(int) u = 12; // expected-error {{expected function body after function declarator}}
+__typeof_unqual(int) _u = 12;
+__typeof_unqual__(int) __u = 12;