Skip to content

Commit

Permalink
[C2x] Support -std=c23 and -std=gnu23
Browse files Browse the repository at this point in the history
C2x was finalized at the June 2023 WG14 meeting. The DIS is out for
balloting and the comment period for that closes later this year/early
next year. While that does leave an opportunity for more changes to the
standard during the DIS ballot resolution process, only editorial
changes are anticipated and as a result, the C committee considers C2x
to be final. The committee took a straw poll on what we'd prefer the
informal name of the standard be, and we decided it should be called
C23 regardless of what year ISO publishes it.

However, because the final publication is not out, this patch does not
add the language standard alias for the -std=iso9899:<year> spelling of
the standard mode; that will be added once ISO finally publishes the
document and the year chosen will match the publication date.

This also changes the value of __STDC_VERSION__ from the placeholder
value 202000L to the final value 202311L.

Subsequent patches will start renaming things from c2x to c23, cleaning
up documentation, etc.

Differential Revision: https://reviews.llvm.org/D157606
  • Loading branch information
AaronBallman committed Aug 10, 2023
1 parent 69a337e commit 13629b1
Show file tree
Hide file tree
Showing 23 changed files with 98 additions and 137 deletions.
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/index/StdLib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ LangStandard::Kind standardFromOpts(const LangOptions &LO) {
return LangStandard::lang_cxx98;
}
if (LO.C2x)
return LangStandard::lang_c2x;
return LangStandard::lang_c23;
// C17 has no new features, so treat {C11,C17} as C17.
if (LO.C11)
return LangStandard::lang_c17;
Expand Down
4 changes: 4 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ C Language Changes

C2x Feature Support
^^^^^^^^^^^^^^^^^^^
- Clang now accepts ``-std=c23`` and ``-std=gnu23`` as language standard modes,
and the ``__STDC_VERSION__`` macro now expands to ``202311L`` instead of its
previous placeholder value. Clang continues to accept ``-std=c2x`` and
``-std=gnu2x`` as aliases for C23 and GNU C23, respectively.

Non-comprehensive list of changes in this release
-------------------------------------------------
Expand Down
14 changes: 9 additions & 5 deletions clang/include/clang/Basic/LangStandards.def
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,17 @@ LANGSTANDARD(gnu17, "gnu17",
LineComment | C99 | C11 | C17 | Digraphs | GNUMode | HexFloat)
LANGSTANDARD_ALIAS(gnu17, "gnu18")

// C2x modes
LANGSTANDARD(c2x, "c2x",
C, "Working Draft for ISO C2x",
// C23 modes
LANGSTANDARD(c23, "c23",
C, "Working Draft for ISO C23",
LineComment | C99 | C11 | C17 | C2x | Digraphs | HexFloat)
LANGSTANDARD(gnu2x, "gnu2x",
C, "Working Draft for ISO C2x with GNU extensions",
LANGSTANDARD_ALIAS_DEPR(c23, "c2x")
LANGSTANDARD(gnu23, "gnu23",
C, "Working Draft for ISO C23 with GNU extensions",
LineComment | C99 | C11 | C17 | C2x | Digraphs | GNUMode | HexFloat)
LANGSTANDARD_ALIAS_DEPR(gnu23, "gnu2x")
// FIXME: Add the alias for iso9899:202* once we know the year ISO publishes
// the document (expected to be 2024).

// C++ modes
LANGSTANDARD(cxx98, "c++98",
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/Frontend/InitPreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,9 +438,8 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
// value is, are implementation-defined.
// (Removed in C++20.)
if (!LangOpts.CPlusPlus) {
// FIXME: Use correct value for C23.
if (LangOpts.C2x)
Builder.defineMacro("__STDC_VERSION__", "202000L");
Builder.defineMacro("__STDC_VERSION__", "202311L");
else if (LangOpts.C17)
Builder.defineMacro("__STDC_VERSION__", "201710L");
else if (LangOpts.C11)
Expand Down
4 changes: 1 addition & 3 deletions clang/lib/Headers/limits.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@
#define CHAR_BIT __CHAR_BIT__

/* C2x 5.2.4.2.1 */
/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
#define BOOL_WIDTH __BOOL_WIDTH__
#define CHAR_WIDTH CHAR_BIT
#define SCHAR_WIDTH CHAR_BIT
Expand Down
4 changes: 1 addition & 3 deletions clang/lib/Headers/stdalign.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
#ifndef __STDALIGN_H
#define __STDALIGN_H

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__cplusplus) || \
(defined(__STDC_VERSION__) && __STDC_VERSION__ < 202000L)
(defined(__STDC_VERSION__) && __STDC_VERSION__ < 202311L)
#ifndef __cplusplus
#define alignas _Alignas
#define alignof _Alignof
Expand Down
8 changes: 3 additions & 5 deletions clang/lib/Headers/stdarg.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ typedef __builtin_va_list va_list;
#define _VA_LIST
#endif

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
/* C2x does not require the second parameter for va_start. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
/* C23 does not require the second parameter for va_start. */
#define va_start(ap, ...) __builtin_va_start(ap, 0)
#else
/* Versions before C2x do require the second parameter. */
/* Versions before C23 do require the second parameter. */
#define va_start(ap, param) __builtin_va_start(ap, param)
#endif
#define va_end(ap) __builtin_va_end(ap)
Expand Down
8 changes: 3 additions & 5 deletions clang/lib/Headers/stdatomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,14 @@ extern "C" {
#define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE

/* 7.17.2 Initialization */
/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ < 202000L) || \
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ < 202311L) || \
defined(__cplusplus)
/* ATOMIC_VAR_INIT was removed in C2x, but still remains in C++23. */
/* ATOMIC_VAR_INIT was removed in C23, but still remains in C++23. */
#define ATOMIC_VAR_INIT(value) (value)
#endif

#if ((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201710L && \
__STDC_VERSION__ < 202000L) || \
__STDC_VERSION__ < 202311L) || \
(defined(__cplusplus) && __cplusplus >= 202002L)) && \
!defined(_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS)
/* ATOMIC_VAR_INIT was deprecated in C17 and C++20. */
Expand Down
8 changes: 3 additions & 5 deletions clang/lib/Headers/stddef.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,12 @@ using ::std::nullptr_t;
#undef __need_NULL
#endif /* defined(__need_NULL) */

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
typedef typeof(nullptr) nullptr_t;
#endif /* defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L */
#endif /* defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L */

#if defined(__need_STDDEF_H_misc) && defined(__STDC_VERSION__) && \
__STDC_VERSION__ >= 202000L
__STDC_VERSION__ >= 202311L
#define unreachable() __builtin_unreachable()
#endif /* defined(__need_STDDEF_H_misc) && >= C23 */

Expand Down
61 changes: 16 additions & 45 deletions clang/lib/Headers/stdint.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,9 +499,8 @@ typedef __UINTMAX_TYPE__ uintmax_t;
# define INT64_MAX INT64_C( 9223372036854775807)
# define INT64_MIN (-INT64_C( 9223372036854775807)-1)
# define UINT64_MAX UINT64_C(18446744073709551615)
/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# define UINT64_WIDTH 64
# define INT64_WIDTH UINT64_WIDTH

Expand Down Expand Up @@ -545,9 +544,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
# define INT_FAST64_MAX __INT_LEAST64_MAX
# define UINT_FAST64_MAX __UINT_LEAST64_MAX

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# define UINT_LEAST64_WIDTH __UINT_LEAST64_WIDTH
# define INT_LEAST64_WIDTH UINT_LEAST64_WIDTH
# define UINT_FAST64_WIDTH __UINT_LEAST64_WIDTH
Expand Down Expand Up @@ -586,9 +583,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
# undef __UINT_LEAST8_MAX
# define __UINT_LEAST8_MAX UINT56_MAX

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# define UINT56_WIDTH 56
# define INT56_WIDTH UINT56_WIDTH
# define UINT_LEAST56_WIDTH UINT56_WIDTH
Expand Down Expand Up @@ -635,9 +630,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
# undef __UINT_LEAST8_MAX
# define __UINT_LEAST8_MAX UINT48_MAX

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
#define UINT48_WIDTH 48
#define INT48_WIDTH UINT48_WIDTH
#define UINT_LEAST48_WIDTH UINT48_WIDTH
Expand Down Expand Up @@ -684,9 +677,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
# undef __UINT_LEAST8_MAX
# define __UINT_LEAST8_MAX UINT40_MAX

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# define UINT40_WIDTH 40
# define INT40_WIDTH UINT40_WIDTH
# define UINT_LEAST40_WIDTH UINT40_WIDTH
Expand Down Expand Up @@ -727,9 +718,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
# undef __UINT_LEAST8_MAX
# define __UINT_LEAST8_MAX UINT32_MAX

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# define UINT32_WIDTH 32
# define INT32_WIDTH UINT32_WIDTH
# undef __UINT_LEAST32_WIDTH
Expand All @@ -749,9 +738,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
# define INT_FAST32_MAX __INT_LEAST32_MAX
# define UINT_FAST32_MAX __UINT_LEAST32_MAX

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# define UINT_LEAST32_WIDTH __UINT_LEAST32_WIDTH
# define INT_LEAST32_WIDTH UINT_LEAST32_WIDTH
# define UINT_FAST32_WIDTH __UINT_LEAST32_WIDTH
Expand Down Expand Up @@ -784,9 +771,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
# undef __UINT_LEAST8_MAX
# define __UINT_LEAST8_MAX UINT24_MAX

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# define UINT24_WIDTH 24
# define INT24_WIDTH UINT24_WIDTH
# define UINT_LEAST24_WIDTH UINT24_WIDTH
Expand Down Expand Up @@ -819,9 +804,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
# undef __UINT_LEAST8_MAX
# define __UINT_LEAST8_MAX UINT16_MAX

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# define UINT16_WIDTH 16
# define INT16_WIDTH UINT16_WIDTH
# undef __UINT_LEAST16_WIDTH
Expand All @@ -839,9 +822,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
# define INT_FAST16_MAX __INT_LEAST16_MAX
# define UINT_FAST16_MAX __UINT_LEAST16_MAX

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# define UINT_LEAST16_WIDTH __UINT_LEAST16_WIDTH
# define INT_LEAST16_WIDTH UINT_LEAST16_WIDTH
# define UINT_FAST16_WIDTH __UINT_LEAST16_WIDTH
Expand All @@ -862,9 +843,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
# undef __UINT_LEAST8_MAX
# define __UINT_LEAST8_MAX UINT8_MAX

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# define UINT8_WIDTH 8
# define INT8_WIDTH UINT8_WIDTH
# undef __UINT_LEAST8_WIDTH
Expand All @@ -880,9 +859,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
# define INT_FAST8_MAX __INT_LEAST8_MAX
# define UINT_FAST8_MAX __UINT_LEAST8_MAX

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# define UINT_LEAST8_WIDTH __UINT_LEAST8_WIDTH
# define INT_LEAST8_WIDTH UINT_LEAST8_WIDTH
# define UINT_FAST8_WIDTH __UINT_LEAST8_WIDTH
Expand All @@ -908,9 +885,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
#define SIZE_MAX __SIZE_MAX__

/* C2x 7.20.2.4 Width of integer types capable of holding object pointers. */
/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
/* NB: The C standard requires that these be the same value, but the compiler
exposes separate internal width macros. */
#define INTPTR_WIDTH __INTPTR_WIDTH__
Expand All @@ -929,9 +904,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
#define UINTMAX_MAX __UINTMAX_MAX__

/* C2x 7.20.2.5 Width of greatest-width integer types. */
/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
/* NB: The C standard requires that these be the same value, but the compiler
exposes separate internal width macros. */
#define INTMAX_WIDTH __INTMAX_WIDTH__
Expand Down Expand Up @@ -965,9 +938,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
#define UINTMAX_C(v) __int_c(v, __UINTMAX_C_SUFFIX__)

/* C2x 7.20.3.x Width of other integer types. */
/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
#define PTRDIFF_WIDTH __PTRDIFF_WIDTH__
#define SIG_ATOMIC_WIDTH __SIG_ATOMIC_WIDTH__
#define SIZE_WIDTH __SIZE_WIDTH__
Expand Down
4 changes: 1 addition & 3 deletions clang/test/C/C11/n1330.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ void test(void) {
_Static_assert(1.0f, "this should not compile"); // expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
}

// FIXME: This is using the placeholder date Clang produces for the macro in
// C2x mode; switch to the correct value once it's been published.
#if __STDC_VERSION__ < 202000L
#if __STDC_VERSION__ < 202311L
// The use of a _Static_assert in a K&R C function definition is prohibited per
// 6.9.1p6 requiring each declaration to have a declarator (which a static
// assertion does not have) and only declare identifiers from the identifier
Expand Down
12 changes: 6 additions & 6 deletions clang/test/C/drs/dr0xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ void dr031(int i) {
*/
int dr032 = (1, 2); /* expected-warning {{left operand of comma operator has no effect}} */

#if __STDC_VERSION__ < 202000L
#if __STDC_VERSION__ < 202311L
/* WG14 DR035: partial
* Questions about definition of functions without a prototype
*/
Expand All @@ -251,7 +251,7 @@ void dr035_2(c) /* expected-warning {{a function definition without a prototype
*/
int test = q; /* expected-error {{use of undeclared identifier 'q'}} */
}
#endif /* __STDC_VERSION__ < 202000L */
#endif /* __STDC_VERSION__ < 202311L */

/* WG14 DR038: yes
* Questions about argument substitution during macro expansion
Expand Down Expand Up @@ -339,7 +339,7 @@ void dr050(void) {
(void)NULL; /* expected-error {{use of undeclared identifier 'NULL'}} */
}

#if __STDC_VERSION__ < 202000L
#if __STDC_VERSION__ < 202311L
/* WG14 DR053: yes
* Accessing a pointer to a function with a prototype through a pointer to
* pointer to function without a prototype
Expand All @@ -356,7 +356,7 @@ void dr053(void) {
fpp = &fp1;
(**fpp)(3); /* expected-warning {{passing arguments to a function without a prototype is deprecated in all versions of C and is not supported in C2x}} */
}
#endif /* __STDC_VERSION__ < 202000L */
#endif /* __STDC_VERSION__ < 202311L */

/* WG14 DR064: yes
* Null pointer constants
Expand Down Expand Up @@ -385,7 +385,7 @@ void dr068(void) {
#endif
}

#if __STDC_VERSION__ < 202000L
#if __STDC_VERSION__ < 202311L
/* WG14: DR070: yes
* Interchangeability of function arguments
*
Expand All @@ -406,7 +406,7 @@ void dr070_2(void) {
dr070_1(6);
dr070_1(6U); /* Pedantically UB */
}
#endif /* __STDC_VERSION__ < 202000L */
#endif /* __STDC_VERSION__ < 202311L */

/* WG14 DR071: yes
* Enumerated types
Expand Down
4 changes: 2 additions & 2 deletions clang/test/C/drs/dr2xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ void dr251(void) {
struct dr251_fred *ptr; /* expected-error {{use of 'dr251_fred' with tag type that does not match previous declaration}} */
}

#if __STDC_VERSION__ < 202000L
#if __STDC_VERSION__ < 202311L
/* WG14 DR252: yes
* Incomplete argument types when calling non-prototyped functions
*/
Expand All @@ -250,7 +250,7 @@ void dr252(void) {
expected-warning {{passing arguments to 'dr252_no_proto' without a prototype is deprecated in all versions of C and is not supported in C2x}}
*/
}
#endif /* __STDC_VERSION__ < 202000L */
#endif /* __STDC_VERSION__ < 202311L */

/* WG14 DR258: yes
* Ordering of "defined" and macro replacement
Expand Down
Loading

0 comments on commit 13629b1

Please sign in to comment.