From dcd599757f215fa8eba3b5e40d4b1c52eb5b3919 Mon Sep 17 00:00:00 2001
From: Raul Tambre <raul@tambre.ee>
Date: Sat, 6 Feb 2021 18:59:23 +0200
Subject: [PATCH] C23 support

---
 Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst         | 3 +++
 Help/prop_tgt/C_STANDARD.rst                     | 2 +-
 Help/release/dev/c-std.rst                       | 2 +-
 Modules/CMakeCCompiler.cmake.in                  | 1 +
 Modules/CMakeCCompilerId.c.in                    | 2 ++
 Modules/CMakeDetermineCompileFeatures.cmake      | 6 ++++++
 Modules/Compiler/CMakeCommonCompilerMacros.cmake | 3 +++
 Source/cmStandardLevelResolver.cxx               | 4 ++--
 Source/cmake.h                                   | 1 +
 Tests/CompileFeatures/CMakeLists.txt             | 1 +
 Tests/CompileFeatures/default_dialect.c          | 6 +++++-
 11 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst
index 9ea63faea2..2bd0febeaa 100644
--- a/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst
+++ b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst
@@ -27,6 +27,9 @@ The features known to this version of CMake are:
 ``c_std_17``
   Compiler mode is at least C 17.
 
+``c_std_23``
+  Compiler mode is at least C 23.
+
 ``c_function_prototypes``
   Function prototypes, as defined in ``ISO/IEC 9899:1990``.
 
diff --git a/Help/prop_tgt/C_STANDARD.rst b/Help/prop_tgt/C_STANDARD.rst
index 4fbde3586b..e22b775d13 100644
--- a/Help/prop_tgt/C_STANDARD.rst
+++ b/Help/prop_tgt/C_STANDARD.rst
@@ -11,7 +11,7 @@ flag such as ``-std=gnu11`` to the compile line.  For compilers that
 have no notion of a C standard level, such as Microsoft Visual C++ before
 VS 16.7, this property has no effect.
 
-Supported values are ``90``, ``99``, ``11``, ``17``.
+Supported values are ``90``, ``99``, ``11``, ``17``, ``23``.
 
 If the value requested does not result in a compile flag being added for
 the compiler in use, a previous standard flag will be added instead.  This
diff --git a/Help/release/dev/c-std.rst b/Help/release/dev/c-std.rst
index 475a4e4959..44daa85cd4 100644
--- a/Help/release/dev/c-std.rst
+++ b/Help/release/dev/c-std.rst
@@ -3,4 +3,4 @@ c-std
 
 * :prop_tgt:`C_STANDARD` and the
   :manual:`Compile Features <cmake-compile-features(7)>` functionality gained
-  support for C17.
+  support for C17 and C23.
diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in
index 74487d1966..754f235bae 100644
--- a/Modules/CMakeCCompiler.cmake.in
+++ b/Modules/CMakeCCompiler.cmake.in
@@ -10,6 +10,7 @@ set(CMAKE_C90_COMPILE_FEATURES "@CMAKE_C90_COMPILE_FEATURES@")
 set(CMAKE_C99_COMPILE_FEATURES "@CMAKE_C99_COMPILE_FEATURES@")
 set(CMAKE_C11_COMPILE_FEATURES "@CMAKE_C11_COMPILE_FEATURES@")
 set(CMAKE_C17_COMPILE_FEATURES "@CMAKE_C17_COMPILE_FEATURES@")
+set(CMAKE_C23_COMPILE_FEATURES "@CMAKE_C23_COMPILE_FEATURES@")
 
 set(CMAKE_C_PLATFORM_ID "@CMAKE_C_PLATFORM_ID@")
 set(CMAKE_C_SIMULATE_ID "@CMAKE_C_SIMULATE_ID@")
diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in
index f1175f4e9f..716b9757bc 100644
--- a/Modules/CMakeCCompilerId.c.in
+++ b/Modules/CMakeCCompilerId.c.in
@@ -39,6 +39,8 @@ char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
 # else
 #  define C_DIALECT
 # endif
+#elif __STDC_VERSION__ > 201710L
+# define C_DIALECT "23"
 #elif __STDC_VERSION__ >= 201710L
 # define C_DIALECT "17"
 #elif __STDC_VERSION__ >= 201000L
diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake
index 49b8169f53..f767847936 100644
--- a/Modules/CMakeDetermineCompileFeatures.cmake
+++ b/Modules/CMakeDetermineCompileFeatures.cmake
@@ -11,6 +11,7 @@ function(cmake_determine_compile_features lang)
     set(CMAKE_C99_COMPILE_FEATURES)
     set(CMAKE_C11_COMPILE_FEATURES)
     set(CMAKE_C17_COMPILE_FEATURES)
+    set(CMAKE_C23_COMPILE_FEATURES)
 
     include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
 
@@ -21,6 +22,9 @@ function(cmake_determine_compile_features lang)
       return()
     endif()
 
+    if (CMAKE_C17_COMPILE_FEATURES AND CMAKE_C23_COMPILE_FEATURES)
+      list(REMOVE_ITEM CMAKE_C23_COMPILE_FEATURES ${CMAKE_C17_COMPILE_FEATURES})
+    endif()
     if (CMAKE_C11_COMPILE_FEATURES AND CMAKE_C17_COMPILE_FEATURES)
       list(REMOVE_ITEM CMAKE_C17_COMPILE_FEATURES ${CMAKE_C11_COMPILE_FEATURES})
     endif()
@@ -37,6 +41,7 @@ function(cmake_determine_compile_features lang)
         ${CMAKE_C99_COMPILE_FEATURES}
         ${CMAKE_C11_COMPILE_FEATURES}
         ${CMAKE_C17_COMPILE_FEATURES}
+        ${CMAKE_C23_COMPILE_FEATURES}
       )
     endif()
 
@@ -45,6 +50,7 @@ function(cmake_determine_compile_features lang)
     set(CMAKE_C99_COMPILE_FEATURES ${CMAKE_C99_COMPILE_FEATURES} PARENT_SCOPE)
     set(CMAKE_C11_COMPILE_FEATURES ${CMAKE_C11_COMPILE_FEATURES} PARENT_SCOPE)
     set(CMAKE_C17_COMPILE_FEATURES ${CMAKE_C17_COMPILE_FEATURES} PARENT_SCOPE)
+    set(CMAKE_C23_COMPILE_FEATURES ${CMAKE_C23_COMPILE_FEATURES} PARENT_SCOPE)
 
     message(CHECK_PASS "done")
 
diff --git a/Modules/Compiler/CMakeCommonCompilerMacros.cmake b/Modules/Compiler/CMakeCommonCompilerMacros.cmake
index ac20d5f6eb..29e673004c 100644
--- a/Modules/Compiler/CMakeCommonCompilerMacros.cmake
+++ b/Modules/Compiler/CMakeCommonCompilerMacros.cmake
@@ -64,6 +64,9 @@ endmacro()
 # Define to allow compile features to be automatically determined
 macro(cmake_record_c_compile_features)
   set(_result 0)
+  if(_result EQUAL 0 AND DEFINED CMAKE_C23_STANDARD_COMPILE_OPTION)
+    _has_compiler_features_c(23)
+  endif()
   if(_result EQUAL 0 AND DEFINED CMAKE_C17_STANDARD_COMPILE_OPTION)
     _has_compiler_features_c(17)
   endif()
diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx
index e290663dfd..280e508d66 100644
--- a/Source/cmStandardLevelResolver.cxx
+++ b/Source/cmStandardLevelResolver.cxx
@@ -309,8 +309,8 @@ std::unordered_map<std::string, StanardLevelComputer> StandardComputerMapping =
   {
     { "C",
       StanardLevelComputer{
-        "C", std::vector<int>{ 90, 99, 11, 17 },
-        std::vector<std::string>{ "90", "99", "11", "17" } } },
+        "C", std::vector<int>{ 90, 99, 11, 17, 23 },
+        std::vector<std::string>{ "90", "99", "11", "17", "23" } } },
     { "CXX",
       StanardLevelComputer{
         "CXX", std::vector<int>{ 98, 11, 14, 17, 20, 23 },
diff --git a/Source/cmake.h b/Source/cmake.h
index 95eb113604..d6d129ff16 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -740,6 +740,7 @@ private:
   F(c_std_99)                                                                 \
   F(c_std_11)                                                                 \
   F(c_std_17)                                                                 \
+  F(c_std_23)                                                                 \
   FOR_EACH_C90_FEATURE(F)                                                     \
   FOR_EACH_C99_FEATURE(F)                                                     \
   FOR_EACH_C11_FEATURE(F)
diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt
index 046b858c77..7771967a12 100644
--- a/Tests/CompileFeatures/CMakeLists.txt
+++ b/Tests/CompileFeatures/CMakeLists.txt
@@ -237,6 +237,7 @@ if (C_expected_features)
     if (std_flag_idx EQUAL -1)
       add_executable(default_dialect_C default_dialect.c)
       target_compile_definitions(default_dialect_C PRIVATE
+        DEFAULT_C23=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},23>
         DEFAULT_C17=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},17>
         DEFAULT_C11=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},11>
         DEFAULT_C99=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},99>
diff --git a/Tests/CompileFeatures/default_dialect.c b/Tests/CompileFeatures/default_dialect.c
index e0900676f3..b990e53258 100644
--- a/Tests/CompileFeatures/default_dialect.c
+++ b/Tests/CompileFeatures/default_dialect.c
@@ -1,5 +1,9 @@
 
-#if DEFAULT_C17
+#if DEFAULT_C23
+#  if __STDC_VERSION__ <= 201710L
+#    error Unexpected value for __STDC_VERSION__.
+#  endif
+#elif DEFAULT_C17
 #  if __STDC_VERSION__ < 201710L
 #    error Unexpected value for __STDC_VERSION__.
 #  endif
-- 
GitLab