[clang] [clang][C23] Claim N3030 Enhancements to Enumerations supported (PR #107260)
Mariya Podchishchaeva via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 16 03:49:17 PDT 2024
https://github.com/Fznamznon updated https://github.com/llvm/llvm-project/pull/107260
>From da76f2dfd3b0c8e2a03165ad1ac06b517c4af391 Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Wed, 4 Sep 2024 07:45:27 -0700
Subject: [PATCH 1/2] [clang][C23] Claim N3030 Enhancements to Enumerations
supported
Clang already implemented functionality as an extension.
---
.../clang/Basic/DiagnosticParseKinds.td | 9 +-
clang/lib/Parse/ParseDecl.cpp | 8 +-
clang/test/C/C23/n3030.c | 95 +++++++++++++++++++
clang/test/Sema/fixed-enum.c | 25 +++--
clang/www/c_status.html | 2 +-
5 files changed, 124 insertions(+), 15 deletions(-)
create mode 100644 clang/test/C/C23/n3030.c
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 0b8ab4bf092509..a1070aceea7572 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -113,9 +113,12 @@ def ext_cxx11_enum_fixed_underlying_type : Extension<
def ext_ms_c_enum_fixed_underlying_type : Extension<
"enumeration types with a fixed underlying type are a Microsoft extension">,
InGroup<MicrosoftFixedEnum>;
-def ext_clang_c_enum_fixed_underlying_type : Extension<
- "enumeration types with a fixed underlying type are a Clang extension">,
- InGroup<DiagGroup<"fixed-enum-extension">>;
+def ext_c23_enum_fixed_underlying_type : Extension<
+ "enumeration types with a fixed underlying type are a C23 extension">,
+ InGroup<C23>;
+def warn_c17_compat_enum_fixed_underlying_type : Warning<
+ "enumeration types with a fixed underlying type are incompatible with C standards before C23">,
+ DefaultIgnore, InGroup<CPre23Compat>;
def warn_cxx98_compat_enum_fixed_underlying_type : Warning<
"enumeration types with a fixed underlying type are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 78d729c5ef7d8a..b563f875c663c6 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5413,18 +5413,20 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
- if (!getLangOpts().ObjC && !getLangOpts().C23) {
+ if (!getLangOpts().ObjC) {
if (getLangOpts().CPlusPlus11)
Diag(ColonLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type)
<< BaseRange;
else if (getLangOpts().CPlusPlus)
Diag(ColonLoc, diag::ext_cxx11_enum_fixed_underlying_type)
<< BaseRange;
- else if (getLangOpts().MicrosoftExt)
+ else if (getLangOpts().MicrosoftExt && !getLangOpts().C23)
Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
<< BaseRange;
else
- Diag(ColonLoc, diag::ext_clang_c_enum_fixed_underlying_type)
+ Diag(ColonLoc, (getLangOpts().C23)
+ ? diag::warn_c17_compat_enum_fixed_underlying_type
+ : diag::ext_c23_enum_fixed_underlying_type)
<< BaseRange;
}
}
diff --git a/clang/test/C/C23/n3030.c b/clang/test/C/C23/n3030.c
new file mode 100644
index 00000000000000..82e50484fd7ebc
--- /dev/null
+++ b/clang/test/C/C23/n3030.c
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -verify -triple x86_64-unknown-linux-gnu -fsyntax-only --embed-dir=%S/Inputs -std=c23 %s -pedantic -Wall
+
+#include <limits.h>
+
+enum us : unsigned short {
+ us_max = USHRT_MAX,
+ us_violation, // expected-error {{enumerator value 65536 is not representable in the underlying type 'unsigned short'}}
+ // expected-warning at -1 {{overflow}}
+ us_violation_2 = us_max + 1, // expected-error {{enumerator value is not representable in the underlying type 'unsigned short'}}
+ us_wrap_around_to_zero = (unsigned short)(USHRT_MAX + 1) /* Okay: conversion
+ done in constant expression before conversion to
+ underlying type: unsigned semantics okay. */
+};
+
+enum ui : unsigned int {
+ ui_max = UINT_MAX,
+ ui_violation, // expected-error {{enumerator value 4294967296 is not representable in the underlying type 'unsigned int'}}
+ // expected-warning at -1 {{overflow}}
+ ui_no_violation = ui_max + 1,
+ ui_wrap_around_to_zero = (unsigned int)(UINT_MAX + 1)
+};
+
+enum E1 : short;
+enum E2 : short; // expected-note {{previous}}
+enum E3; // expected-warning {{ISO C forbids forward references to 'enum' types}}
+enum E4 : unsigned long long;
+
+enum E1 : short { m11, m12 };
+enum E1 x = m11;
+
+enum E2 : long { // expected-error {{enumeration redeclared with different underlying type 'long' (was 'short')}}
+ m21,
+ m22
+};
+
+enum E3 { // expected-note {{definition of 'enum E3' is not complete until the closing '}'}}
+ // expected-note at -1 {{previous}}
+ m31,
+ m32,
+ m33 = sizeof(enum E3) // expected-error {{invalid application of 'sizeof' to an incomplete type 'enum E3'}}
+};
+enum E3 : int; // expected-error {{enumeration previously declared with nonfixed underlying type}}
+
+enum E4 : unsigned long long {
+ m40 = sizeof(enum E4),
+ m41 = ULLONG_MAX,
+ m42 // expected-error {{enumerator value 18446744073709551616 is not representable in the underlying type 'unsigned long long'}}
+};
+
+enum E5 y; // expected-error {{tentative definition has type 'enum E5' that is never completed}}
+ // expected-warning at -1 {{ISO C forbids forward references to 'enum' types}}
+ // expected-note at -2 {{forward declaration of 'enum E5'}}
+enum E6 : long int z; // expected-error {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration; missing list of enumerators?}}
+enum E7 : long int = 0; // expected-error {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration; missing list of enumerators?}}
+ // expected-error at -1 {{expected identifier or '('}}
+
+enum underlying : unsigned char { b0 };
+
+constexpr int a = _Generic(b0, int: 2, unsigned char: 1, default: 0);
+constexpr int b = _Generic((enum underlying)b0, int: 2, unsigned char: 1, default: 0);
+static_assert(a == 1);
+static_assert(b == 1);
+
+void f1(enum a : long b); // expected-error {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration; missing list of enumerators?}}
+ // expected-warning at -1 {{declaration of 'enum a' will not be visible outside of this function}}
+void f2(enum c : long{x} d); // expected-warning {{declaration of 'enum c' will not be visible outside of this function}}
+enum e : int f3(); // expected-error {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration; missing list of enumerators?}}
+
+typedef enum t u; // expected-warning {{ISO C forbids forward references to 'enum' types}}
+typedef enum v : short W; // expected-error {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration; missing list of enumerators?}}
+typedef enum q : short { s } R;
+
+struct s1 {
+ int x;
+ enum e:int : 1; // expected-error {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration; missing list of enumerators?}}
+ int y;
+};
+
+enum forward; // expected-warning {{ISO C forbids forward references to 'enum' types}}
+extern enum forward fwd_val0; /* Constraint violation: incomplete type */
+extern enum forward *fwd_ptr0; // expected-note {{previous}}
+extern int
+ *fwd_ptr0; // expected-error {{redeclaration of 'fwd_ptr0' with a different type: 'int *' vs 'enum forward *'}}
+
+enum forward1 : int;
+extern enum forward1 fwd_val1;
+extern int fwd_val1;
+extern enum forward1 *fwd_ptr1;
+extern int *fwd_ptr1;
+
+enum ee1 : short;
+enum e : short f = 0; // expected-error {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration; missing list of enumerators?}}
+enum g : short { yyy } h = yyy;
+
+enum ee2 : typeof ((enum ee3 : short { A })0, (short)0);
diff --git a/clang/test/Sema/fixed-enum.c b/clang/test/Sema/fixed-enum.c
index 954ff8c452b80c..2b02def0e1788d 100644
--- a/clang/test/Sema/fixed-enum.c
+++ b/clang/test/Sema/fixed-enum.c
@@ -5,9 +5,9 @@
// RUN: %clang_cc1 -pedantic -std=c11 -xc -DC11 -verify %s
// RUN: %clang_cc1 -Weverything -std=c11 -xc -fms-extensions -DMS -verify %s
// RUN: %clang_cc1 -Weverything -std=c2x -xc -DC23 -verify %s
-// RUN: %clang_cc1 -pedantic -std=c2x -xc -DC23 -verify %s
+// RUN: %clang_cc1 -pedantic -std=c2x -xc -DC23 -verify -Wpre-c23-compat %s
// RUN: %clang_cc1 -Weverything -std=c23 -xc -DC23 -verify %s
-// RUN: %clang_cc1 -pedantic -std=c23 -xc -DC23 -verify %s
+// RUN: %clang_cc1 -pedantic -std=c23 -xc -DC23 -verify -Wpre-c23-compat %s
// RUN: %clang_cc1 -Weverything -std=c23 -xc -fms-extensions -DC23 -verify %s
enum X : int {e};
@@ -15,12 +15,14 @@ enum X : int {e};
// expected-warning at -2{{enumeration types with a fixed underlying type are incompatible with C++98}}
#elif defined(CXX03)
// expected-warning at -4{{enumeration types with a fixed underlying type are a C++11 extension}}
-#elif defined(OBJC) || defined(C23)
-// No diagnostic
+#elif defined(OBJC)
+// diagnostic
+#elif defined(C23)
+// expected-warning at -8{{enumeration types with a fixed underlying type are incompatible with C standards before C23}}
#elif defined(C11)
-// expected-warning at -8{{enumeration types with a fixed underlying type are a Clang extension}}
+// expected-warning at -10{{enumeration types with a fixed underlying type are a C23 extension}}
#elif defined(MS)
-// expected-warning at -10{{enumeration types with a fixed underlying type are a Microsoft extension}}
+// expected-warning at -12{{enumeration types with a fixed underlying type are a Microsoft extension}}
#endif
// Don't warn about the forward declaration in any language mode.
@@ -29,16 +31,23 @@ enum Fwd : int { e2 };
#if !defined(OBJC) && !defined(C23)
// expected-warning at -3 {{enumeration types with a fixed underlying type}}
// expected-warning at -3 {{enumeration types with a fixed underlying type}}
+#elif defined(C23)
+// expected-warning at -6 {{enumeration types with a fixed underlying type are incompatible with C standards before C23}}
+// expected-warning at -6 {{enumeration types with a fixed underlying type are incompatible with C standards before C23}}
#endif
// Always error on the incompatible redeclaration.
enum BadFwd : int;
#if !defined(OBJC) && !defined(C23)
// expected-warning at -2 {{enumeration types with a fixed underlying type}}
+#elif defined(C23)
+// expected-warning at -4 {{enumeration types with a fixed underlying type are incompatible with C standards before C23}}
#endif
-// expected-note at -4 {{previous declaration is here}}
+// expected-note at -6 {{previous declaration is here}}
enum BadFwd : char { e3 };
#if !defined(OBJC) && !defined(C23)
// expected-warning at -2 {{enumeration types with a fixed underlying type}}
+#elif defined(C23)
+// expected-warning at -4 {{enumeration types with a fixed underlying type are incompatible with C standards before C23}}
#endif
-// expected-error at -4 {{enumeration redeclared with different underlying type 'char' (was 'int')}}
+// expected-error at -6 {{enumeration redeclared with different underlying type 'char' (was 'int')}}
diff --git a/clang/www/c_status.html b/clang/www/c_status.html
index 255690cd6d34e2..47124bd91f846f 100644
--- a/clang/www/c_status.html
+++ b/clang/www/c_status.html
@@ -697,7 +697,7 @@ <h2 id="c2x">C23 implementation status</h2>
<tr>
<td>Enhanced enumerations</td>
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3030.htm">N3030</a></td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="unreleased" align="center">Clang 20</td>
</tr>
<tr>
<td>Freestanding C and IEC 60559 conformance scope reduction</td>
>From 9751d87156c67e54ce35276d79598b2b231d4b1c Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Mon, 16 Sep 2024 03:48:39 -0700
Subject: [PATCH 2/2] Add review feedback
---
clang/lib/Parse/ParseDecl.cpp | 2 +-
clang/test/C/C23/n3030.c | 4 +---
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index e4279031e06f51..a04eed9873c0d4 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5450,7 +5450,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
<< BaseRange;
else
- Diag(ColonLoc, (getLangOpts().C23)
+ Diag(ColonLoc, getLangOpts().C23
? diag::warn_c17_compat_enum_fixed_underlying_type
: diag::ext_c23_enum_fixed_underlying_type)
<< BaseRange;
diff --git a/clang/test/C/C23/n3030.c b/clang/test/C/C23/n3030.c
index 82e50484fd7ebc..9e1405a2e0e1fd 100644
--- a/clang/test/C/C23/n3030.c
+++ b/clang/test/C/C23/n3030.c
@@ -1,11 +1,10 @@
-// RUN: %clang_cc1 -verify -triple x86_64-unknown-linux-gnu -fsyntax-only --embed-dir=%S/Inputs -std=c23 %s -pedantic -Wall
+// RUN: %clang_cc1 -verify -triple x86_64-unknown-linux-gnu -fsyntax-only -std=c23 %s -pedantic -Wall
#include <limits.h>
enum us : unsigned short {
us_max = USHRT_MAX,
us_violation, // expected-error {{enumerator value 65536 is not representable in the underlying type 'unsigned short'}}
- // expected-warning at -1 {{overflow}}
us_violation_2 = us_max + 1, // expected-error {{enumerator value is not representable in the underlying type 'unsigned short'}}
us_wrap_around_to_zero = (unsigned short)(USHRT_MAX + 1) /* Okay: conversion
done in constant expression before conversion to
@@ -15,7 +14,6 @@ enum us : unsigned short {
enum ui : unsigned int {
ui_max = UINT_MAX,
ui_violation, // expected-error {{enumerator value 4294967296 is not representable in the underlying type 'unsigned int'}}
- // expected-warning at -1 {{overflow}}
ui_no_violation = ui_max + 1,
ui_wrap_around_to_zero = (unsigned int)(UINT_MAX + 1)
};
More information about the cfe-commits
mailing list