[clang] [clang][sema] Add support and documentation for `__has_extension(c_fixed_enum)` (PR #117507)
Aidan Goldfarb via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 28 08:15:49 PST 2024
https://github.com/AidanGoldfarb updated https://github.com/llvm/llvm-project/pull/117507
>From a6c9b5ca52f35fe451a52c590ce93584c2b4f3ac Mon Sep 17 00:00:00 2001
From: Aidan Goldfarb <47676355+AidanGoldfarb at users.noreply.github.com>
Date: Fri, 22 Nov 2024 19:06:29 -0500
Subject: [PATCH 1/9] Update LanguageExtensions.rst
---
clang/docs/LanguageExtensions.rst | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index 3c9078bcdf8118..1c400d87c4948b 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1986,7 +1986,7 @@ Enumerations with a fixed underlying type
-----------------------------------------
Clang provides support for C++11 enumerations with a fixed underlying type
-within Objective-C. For example, one can write an enumeration type as:
+within Objective-C and C `prior to C23 <https://open-std.org/JTC1/SC22/WG14/www/docs/n3030.htm>`_. For example, one can write an enumeration type as:
.. code-block:: c++
@@ -1998,6 +1998,9 @@ value, is ``unsigned char``.
Use ``__has_feature(objc_fixed_enum)`` to determine whether support for fixed
underlying types is available in Objective-C.
+Use ``__has_extension(c_fixed_enum)`` to determine whether support for fixed
+underlying types is available in C.
+
Interoperability with C++11 lambdas
-----------------------------------
>From d9e06150893a723cfeee0e08a7b8e652f2facf5c Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Sun, 24 Nov 2024 15:09:02 -0500
Subject: [PATCH 2/9] Updated Features.def to include c_fixed_enum. Updated
enum.c test to check for support of enums with a fixed underlying type in C23
and <C23.
---
clang/include/clang/Basic/Features.def | 1 +
clang/test/Sema/enum.c | 12 ++++++++++++
2 files changed, 13 insertions(+)
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index 9088c867d53ce4..c63f4ab75deda2 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -131,6 +131,7 @@ FEATURE(objc_arc_fields, true)
FEATURE(objc_arc_weak, LangOpts.ObjCWeak)
FEATURE(objc_default_synthesize_properties, LangOpts.ObjC)
FEATURE(objc_fixed_enum, LangOpts.ObjC)
+FEATURE(c_fixed_enum, true)
FEATURE(objc_instancetype, LangOpts.ObjC)
FEATURE(objc_kindof, LangOpts.ObjC)
FEATURE(objc_modules, LangOpts.ObjC && LangOpts.Modules)
diff --git a/clang/test/Sema/enum.c b/clang/test/Sema/enum.c
index 4f6d04ba7f9182..053053192e4ad5 100644
--- a/clang/test/Sema/enum.c
+++ b/clang/test/Sema/enum.c
@@ -121,6 +121,17 @@ int NegativeShortTest[NegativeShort == -1 ? 1 : -1];
enum Color { Red, Green, Blue }; // expected-note{{previous use is here}}
typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type that does not match previous declaration}}
+// Enumerations with a fixed underlying type.
+// https://github.com/llvm/llvm-project/issues/116880
+#if __STDC_VERSION__ >= 202311L
+ typedef enum : unsigned char { Pink, Black, Cyan } Color;
+#else
+ _Static_assert(__has_extension(c_fixed_enum), "Ensure language extension support for enumerations with a fixed underlying type in <C23");
+ typedef enum : unsigned char { Pink, Black, Cyan } Color; // expected-warning {{enumeration types with a fixed underlying type are a C23 extension}}
+#endif
+
+
+
// PR28903
// In C it is valid to define tags inside enums.
struct PR28903 {
@@ -174,6 +185,7 @@ enum IncOverflow {
V3 // pre-c23-warning {{incremented enumerator value which exceeds the range of 'int' is a C23 extension}}
};
+
#if __STDC_VERSION__ >= 202311L
// FIXME: GCC picks __uint128_t as the underlying type for the enumeration
// value and Clang picks unsigned long long.
>From 9fd4a259bea6df7c1e9db8e2c8fe79654937dc9a Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Sun, 24 Nov 2024 15:57:31 -0500
Subject: [PATCH 3/9] Added c_fixed_enum as an extension. Cleaned up enum.c
---
clang/include/clang/Basic/Features.def | 5 ++++-
clang/test/Sema/enum.c | 1 -
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index c63f4ab75deda2..ab963a876db342 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -131,7 +131,6 @@ FEATURE(objc_arc_fields, true)
FEATURE(objc_arc_weak, LangOpts.ObjCWeak)
FEATURE(objc_default_synthesize_properties, LangOpts.ObjC)
FEATURE(objc_fixed_enum, LangOpts.ObjC)
-FEATURE(c_fixed_enum, true)
FEATURE(objc_instancetype, LangOpts.ObjC)
FEATURE(objc_kindof, LangOpts.ObjC)
FEATURE(objc_modules, LangOpts.ObjC && LangOpts.Modules)
@@ -309,6 +308,10 @@ EXTENSION(datasizeof, LangOpts.CPlusPlus)
FEATURE(cxx_abi_relative_vtable, LangOpts.CPlusPlus && LangOpts.RelativeCXXABIVTables)
+//Fixed enum feature and extension, to be relocated in this file
+FEATURE(c_fixed_enum, true)
+EXTENSION(c_fixed_enum, true)
+
// CUDA/HIP Features
FEATURE(cuda_noinline_keyword, LangOpts.CUDA)
EXTENSION(cuda_implicit_host_device_templates, LangOpts.CUDA && LangOpts.OffloadImplicitHostDeviceTemplates)
diff --git a/clang/test/Sema/enum.c b/clang/test/Sema/enum.c
index 053053192e4ad5..3b30b24a6c13f1 100644
--- a/clang/test/Sema/enum.c
+++ b/clang/test/Sema/enum.c
@@ -185,7 +185,6 @@ enum IncOverflow {
V3 // pre-c23-warning {{incremented enumerator value which exceeds the range of 'int' is a C23 extension}}
};
-
#if __STDC_VERSION__ >= 202311L
// FIXME: GCC picks __uint128_t as the underlying type for the enumeration
// value and Clang picks unsigned long long.
>From 53ba18d1453b310fd778e0095b75faddf68ec75b Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Sun, 24 Nov 2024 16:27:04 -0500
Subject: [PATCH 4/9] formatting changes
---
clang/test/Sema/enum.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/clang/test/Sema/enum.c b/clang/test/Sema/enum.c
index 3b30b24a6c13f1..7b3f7d30e91d82 100644
--- a/clang/test/Sema/enum.c
+++ b/clang/test/Sema/enum.c
@@ -130,8 +130,6 @@ typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type
typedef enum : unsigned char { Pink, Black, Cyan } Color; // expected-warning {{enumeration types with a fixed underlying type are a C23 extension}}
#endif
-
-
// PR28903
// In C it is valid to define tags inside enums.
struct PR28903 {
>From 8722c53336e6073e3b521140a07c4c9c0aa18fdc Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Mon, 25 Nov 2024 11:14:02 -0500
Subject: [PATCH 5/9] fixed enum.c typed enum logic
---
clang/test/Sema/enum.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/clang/test/Sema/enum.c b/clang/test/Sema/enum.c
index 7b3f7d30e91d82..9b8360864ea0cb 100644
--- a/clang/test/Sema/enum.c
+++ b/clang/test/Sema/enum.c
@@ -123,11 +123,12 @@ typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type
// Enumerations with a fixed underlying type.
// https://github.com/llvm/llvm-project/issues/116880
-#if __STDC_VERSION__ >= 202311L
+#if __STDC_VERSION__ >= 202311L && !__has_extension(c_fixed_enum)
+ #error c_fixed_enum should be set in C23 mode
+#elif __STDC_VERSION__ >= 202311L
typedef enum : unsigned char { Pink, Black, Cyan } Color;
#else
- _Static_assert(__has_extension(c_fixed_enum), "Ensure language extension support for enumerations with a fixed underlying type in <C23");
- typedef enum : unsigned char { Pink, Black, Cyan } Color; // expected-warning {{enumeration types with a fixed underlying type are a C23 extension}}
+ typedef enum : unsigned char { Pink, Black, Cyan } Color; // pre-c23-warning {{enumeration types with a fixed underlying type are a C23 extension}}
#endif
// PR28903
>From 3a10186af69a871ed912dfb2d624270e0ca22f13 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Mon, 25 Nov 2024 14:14:52 -0500
Subject: [PATCH 6/9] reverted to using pre-c23-warning
---
clang/test/Sema/enum.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/clang/test/Sema/enum.c b/clang/test/Sema/enum.c
index 9b8360864ea0cb..2a1f0f1dd40608 100644
--- a/clang/test/Sema/enum.c
+++ b/clang/test/Sema/enum.c
@@ -125,8 +125,6 @@ typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type
// https://github.com/llvm/llvm-project/issues/116880
#if __STDC_VERSION__ >= 202311L && !__has_extension(c_fixed_enum)
#error c_fixed_enum should be set in C23 mode
-#elif __STDC_VERSION__ >= 202311L
- typedef enum : unsigned char { Pink, Black, Cyan } Color;
#else
typedef enum : unsigned char { Pink, Black, Cyan } Color; // pre-c23-warning {{enumeration types with a fixed underlying type are a C23 extension}}
#endif
>From 7925096fae552bea468042ba64676d2db09420a5 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Tue, 26 Nov 2024 15:50:15 -0500
Subject: [PATCH 7/9] Added `__has_feature(c_fixed_enum)` test to `enum.c`.
Reoganized `Features.def`.
---
clang/include/clang/Basic/Features.def | 9 ++++-----
clang/test/Sema/enum.c | 6 ++++--
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index ab963a876db342..302d54f842a321 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -156,13 +156,15 @@ FEATURE(objc_class_property, LangOpts.ObjC)
FEATURE(objc_c_static_assert, LangOpts.C11)
FEATURE(objc_cxx_static_assert, LangOpts.CPlusPlus11)
EXTENSION(objc_c_static_assert, true)
-// C11 features
+// C11 features
FEATURE(c_alignas, LangOpts.C11)
FEATURE(c_alignof, LangOpts.C11)
FEATURE(c_atomic, LangOpts.C11)
FEATURE(c_generic_selections, LangOpts.C11)
FEATURE(c_static_assert, LangOpts.C11)
FEATURE(c_thread_local, LangOpts.C11 &&PP.getTargetInfo().isTLSSupported())
+// C23 features
+FEATURE(c_fixed_enum, true)
// C++11 features
FEATURE(cxx_access_control_sfinae, LangOpts.CPlusPlus11)
FEATURE(cxx_alias_templates, LangOpts.CPlusPlus11)
@@ -269,6 +271,7 @@ EXTENSION(c_static_assert, true)
EXTENSION(c_thread_local, PP.getTargetInfo().isTLSSupported())
// C23 features supported by other languages as extensions
EXTENSION(c_attributes, true)
+EXTENSION(c_fixed_enum, true)
// C++11 features supported by other languages as extensions.
EXTENSION(cxx_atomic, LangOpts.CPlusPlus)
EXTENSION(cxx_default_function_template_args, LangOpts.CPlusPlus)
@@ -308,10 +311,6 @@ EXTENSION(datasizeof, LangOpts.CPlusPlus)
FEATURE(cxx_abi_relative_vtable, LangOpts.CPlusPlus && LangOpts.RelativeCXXABIVTables)
-//Fixed enum feature and extension, to be relocated in this file
-FEATURE(c_fixed_enum, true)
-EXTENSION(c_fixed_enum, true)
-
// CUDA/HIP Features
FEATURE(cuda_noinline_keyword, LangOpts.CUDA)
EXTENSION(cuda_implicit_host_device_templates, LangOpts.CUDA && LangOpts.OffloadImplicitHostDeviceTemplates)
diff --git a/clang/test/Sema/enum.c b/clang/test/Sema/enum.c
index 2a1f0f1dd40608..f04a42f6a22fe8 100644
--- a/clang/test/Sema/enum.c
+++ b/clang/test/Sema/enum.c
@@ -123,8 +123,10 @@ typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type
// Enumerations with a fixed underlying type.
// https://github.com/llvm/llvm-project/issues/116880
-#if __STDC_VERSION__ >= 202311L && !__has_extension(c_fixed_enum)
- #error c_fixed_enum should be set in C23 mode
+#if __STDC_VERSION__ >= 202311L && !__has_feature(c_fixed_enum)
+ #error c_fixed_enum should be set a feature in C23 mode
+#elif __STDC_VERSION__ < 202311L && !__has_extension(c_fixed_enum)
+ #error c_fixed_enum should be a language extension in <C23 mode
#else
typedef enum : unsigned char { Pink, Black, Cyan } Color; // pre-c23-warning {{enumeration types with a fixed underlying type are a C23 extension}}
#endif
>From e06f7398d54b0423ad0d1ae7ac2cc48cf814ca31 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Wed, 27 Nov 2024 11:47:27 -0500
Subject: [PATCH 8/9] Remove extra space in Features.def
---
clang/include/clang/Basic/Features.def | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index 302d54f842a321..067e0b0c9aadee 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -156,7 +156,7 @@ FEATURE(objc_class_property, LangOpts.ObjC)
FEATURE(objc_c_static_assert, LangOpts.C11)
FEATURE(objc_cxx_static_assert, LangOpts.CPlusPlus11)
EXTENSION(objc_c_static_assert, true)
-// C11 features
+// C11 features
FEATURE(c_alignas, LangOpts.C11)
FEATURE(c_alignof, LangOpts.C11)
FEATURE(c_atomic, LangOpts.C11)
>From 4a467b9b91756c51547a79d7d745bcd1c044f290 Mon Sep 17 00:00:00 2001
From: Aidan <aidan.goldfarb at mail.mcgill.ca>
Date: Thu, 28 Nov 2024 11:15:29 -0500
Subject: [PATCH 9/9] Updated enum.c to use static assertions. Updated
Features.def to define `c_fixed_enum` as a C23 feature only. Updated
LanguageExtension.rst to reflect `c_fixed_enum` as a feature and extension
depending on C version
---
clang/docs/LanguageExtensions.rst | 7 +++++--
clang/include/clang/Basic/Features.def | 2 +-
clang/test/Sema/enum.c | 11 ++++++-----
3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index 1c400d87c4948b..55590ab76dbc17 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1996,10 +1996,13 @@ This specifies that the underlying type, which is used to store the enumeration
value, is ``unsigned char``.
Use ``__has_feature(objc_fixed_enum)`` to determine whether support for fixed
-underlying types is available in Objective-C.
+underlying types is available in Objective-C
Use ``__has_extension(c_fixed_enum)`` to determine whether support for fixed
-underlying types is available in C.
+underlying types is available in C prior to C23
+
+Use ``__has_feature(c_fixed_enum)`` to determine whether support for fixed
+underlying types is available in C23 and later
Interoperability with C++11 lambdas
-----------------------------------
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index 067e0b0c9aadee..15c59c6bcdf29c 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -164,7 +164,7 @@ FEATURE(c_generic_selections, LangOpts.C11)
FEATURE(c_static_assert, LangOpts.C11)
FEATURE(c_thread_local, LangOpts.C11 &&PP.getTargetInfo().isTLSSupported())
// C23 features
-FEATURE(c_fixed_enum, true)
+FEATURE(c_fixed_enum, LangOpts.C23)
// C++11 features
FEATURE(cxx_access_control_sfinae, LangOpts.CPlusPlus11)
FEATURE(cxx_alias_templates, LangOpts.CPlusPlus11)
diff --git a/clang/test/Sema/enum.c b/clang/test/Sema/enum.c
index f04a42f6a22fe8..f12ce61ac13a61 100644
--- a/clang/test/Sema/enum.c
+++ b/clang/test/Sema/enum.c
@@ -123,13 +123,14 @@ typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type
// Enumerations with a fixed underlying type.
// https://github.com/llvm/llvm-project/issues/116880
-#if __STDC_VERSION__ >= 202311L && !__has_feature(c_fixed_enum)
- #error c_fixed_enum should be set a feature in C23 mode
-#elif __STDC_VERSION__ < 202311L && !__has_extension(c_fixed_enum)
- #error c_fixed_enum should be a language extension in <C23 mode
+#if __STDC_VERSION__ >= 202311L
+ static_assert(__has_feature(c_fixed_enum));
+ static_assert(__has_extension(c_fixed_enum)); // Matches behavior for c_alignas, etc
#else
- typedef enum : unsigned char { Pink, Black, Cyan } Color; // pre-c23-warning {{enumeration types with a fixed underlying type are a C23 extension}}
+ _Static_assert(__has_extension(c_fixed_enum), "");
+ _Static_assert(!__has_feature(c_fixed_enum), "");
#endif
+typedef enum : unsigned char { Pink, Black, Cyan } Color; // pre-c23-warning {{enumeration types with a fixed underlying type are a C23 extension}}
// PR28903
// In C it is valid to define tags inside enums.
More information about the cfe-commits
mailing list