[clang] a9d9b0a - [clang][C23] Claim N3030 Enhancements to Enumerations supported (#107260)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 18 07:05:30 PDT 2024
Author: Mariya Podchishchaeva
Date: 2024-09-18T16:05:23+02:00
New Revision: a9d9b0a03daf7ca986182477a0866df525cfceff
URL: https://github.com/llvm/llvm-project/commit/a9d9b0a03daf7ca986182477a0866df525cfceff
DIFF: https://github.com/llvm/llvm-project/commit/a9d9b0a03daf7ca986182477a0866df525cfceff.diff
LOG: [clang][C23] Claim N3030 Enhancements to Enumerations supported (#107260)
Clang already implemented functionality as an extension.
Added:
clang/test/C/C23/n3030.c
Modified:
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/lib/Parse/ParseDecl.cpp
clang/test/Sema/fixed-enum.c
clang/www/c_status.html
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 1afadb3bff750d..78510e61a639fa 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 1f56884be392d6..a04eed9873c0d4 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5439,18 +5439,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..9e1405a2e0e1fd
--- /dev/null
+++ b/clang/test/C/C23/n3030.c
@@ -0,0 +1,93 @@
+// 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'}}
+ 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'}}
+ 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
diff erent 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
diff erent 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
diff erent underlying type 'char' (was 'int')}}
+// expected-error at -6 {{enumeration redeclared with
diff erent underlying type 'char' (was 'int')}}
diff --git a/clang/www/c_status.html b/clang/www/c_status.html
index 148405ec31a9ba..e5da7f3c87a519 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>
More information about the cfe-commits
mailing list