From e4c0595ec4ed3cd2f6fb471081a9d2d3960e1672 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <jakub@redhat.com> Date: Mon, 7 Oct 2024 21:25:22 +0200 Subject: [PATCH] libcpp: Use constexpr for _cpp_trigraph_map initialization for C++14 The _cpp_trigraph_map initialization used to be done for C99+ using designated initializers, but can't be done that way for C++ because the designated initializer support in C++ as array designators are just an extension there and don't allow skipping anything nor going backwards. But, we can get the same effect using C++14 constexpr constructor. With the following patch we get rid of the runtime initialization and the array can be in .rodata. 2024-10-07 Jakub Jelinek <jakub@redhat.com> * internal.h (_cpp_trigraph_map_s): New type for C++14 or later. (_cpp_trigraph_map_d): New variable for C++14 or later. (_cpp_trigraph_map): Define to _cpp_trigraph_map_d.map for C++14 or later. * init.cc (init_trigraph_map): Define to nothing for C++14 or later. (TRIGRAPH_MAP, END, s): Define differently for C++14 or later. --- libcpp/init.cc | 13 +++++++++++-- libcpp/internal.h | 6 ++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/libcpp/init.cc b/libcpp/init.cc index 2c80d63a491d..3e4a2bc0ae79 100644 --- a/libcpp/init.cc +++ b/libcpp/init.cc @@ -41,8 +41,8 @@ static void read_original_directory (cpp_reader *); static void post_options (cpp_reader *); /* If we have designated initializers (GCC >2.7) these tables can be - initialized, constant data. Otherwise, they have to be filled in at - runtime. */ + initialized, constant data. Similarly for C++14 and later. + Otherwise, they have to be filled in at runtime. */ #if HAVE_DESIGNATED_INITIALIZERS #define init_trigraph_map() /* Nothing. */ @@ -52,6 +52,15 @@ __extension__ const uchar _cpp_trigraph_map[UCHAR_MAX + 1] = { #define END }; #define s(p, v) [p] = v, +#elif __cpp_constexpr >= 201304L + +#define init_trigraph_map() /* Nothing. */ +#define TRIGRAPH_MAP \ +constexpr _cpp_trigraph_map_s::_cpp_trigraph_map_s () : map {} { +#define END } \ +constexpr _cpp_trigraph_map_s _cpp_trigraph_map_d; +#define s(p, v) map[p] = v; + #else #define TRIGRAPH_MAP uchar _cpp_trigraph_map[UCHAR_MAX + 1] = { 0 }; \ diff --git a/libcpp/internal.h b/libcpp/internal.h index b69a0377f024..2379fbba8996 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -668,6 +668,12 @@ struct cpp_embed_params compiler that supports C99. */ #if HAVE_DESIGNATED_INITIALIZERS extern const unsigned char _cpp_trigraph_map[UCHAR_MAX + 1]; +#elif __cpp_constexpr >= 201304L +extern const struct _cpp_trigraph_map_s { + unsigned char map[UCHAR_MAX + 1]; + constexpr _cpp_trigraph_map_s (); +} _cpp_trigraph_map_d; +#define _cpp_trigraph_map _cpp_trigraph_map_d.map #else extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1]; #endif -- GitLab