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.podchishcha...@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@-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@-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@-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@-1 {{ISO C forbids forward references to 'enum' types}} + // expected-note@-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@-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@-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@-2{{enumeration types with a fixed underlying type are incompatible with C++98}} #elif defined(CXX03) // expected-warning@-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@-8{{enumeration types with a fixed underlying type are incompatible with C standards before C23}} #elif defined(C11) -// expected-warning@-8{{enumeration types with a fixed underlying type are a Clang extension}} +// expected-warning@-10{{enumeration types with a fixed underlying type are a C23 extension}} #elif defined(MS) -// expected-warning@-10{{enumeration types with a fixed underlying type are a Microsoft extension}} +// expected-warning@-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@-3 {{enumeration types with a fixed underlying type}} // expected-warning@-3 {{enumeration types with a fixed underlying type}} +#elif defined(C23) +// expected-warning@-6 {{enumeration types with a fixed underlying type are incompatible with C standards before C23}} +// expected-warning@-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@-2 {{enumeration types with a fixed underlying type}} +#elif defined(C23) +// expected-warning@-4 {{enumeration types with a fixed underlying type are incompatible with C standards before C23}} #endif -// expected-note@-4 {{previous declaration is here}} +// expected-note@-6 {{previous declaration is here}} enum BadFwd : char { e3 }; #if !defined(OBJC) && !defined(C23) // expected-warning@-2 {{enumeration types with a fixed underlying type}} +#elif defined(C23) +// expected-warning@-4 {{enumeration types with a fixed underlying type are incompatible with C standards before C23}} #endif -// expected-error@-4 {{enumeration redeclared with different underlying type 'char' (was 'int')}} +// expected-error@-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.podchishcha...@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@-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@-1 {{overflow}} ui_no_violation = ui_max + 1, ui_wrap_around_to_zero = (unsigned int)(UINT_MAX + 1) }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits