aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2022-10-20 10:30:31 -0400
committerPatrick Palka <ppalka@redhat.com>2022-10-20 10:30:31 -0400
commit7bf3a4d36a8e59297ea65dd479ffe696f0974303 (patch)
treea56d379e4b7cd8a4cde3a28807e3ce3e751c18cd
parentf4fda3eec408e1eb12cc966f55f0de396be71597 (diff)
downloadgcc-7bf3a4d36a8e59297ea65dd479ffe696f0974303.zip
gcc-7bf3a4d36a8e59297ea65dd479ffe696f0974303.tar.gz
gcc-7bf3a4d36a8e59297ea65dd479ffe696f0974303.tar.bz2
libstdc++: Redefine __from_chars_alnum_to_val's table
After the C++23 constexpr <charconv> patch r13-3313-g378a0f1840e694 we have some modules testsuite regressions: FAIL: g++.dg/modules/xtreme-header-4_b.C -std=c++2b (test for excess errors) FAIL: g++.dg/modules/xtreme-header_b.C -std=c++2b (test for excess errors) Like with PR105297, the cause seems to be the deduced type of __table resolving ahead of time to a local class type, which trips up modules. And unfortunately that PR's minimal workaround of making __tables's initializer value dependent doesn't help in this case. So this patch works around this by avoiding using a local class for the table type. And I suppose we should use a static data member to define the table once for all dialects (including C++14) instead of having to define it twice in C++23 mode (once as a static local variable and again as a variable template for sake of constexpr evaluation). libstdc++-v3/ChangeLog: * include/std/charconv (__detail::__from_chars_alnum_to_val_table): Redefine as a class template containing the members type, value and _S_make_table. Don't use a local class as the table type. (__detail::__table): Remove. (__detail::__from_chars_alnum_to_val): Adjust after the above.
-rw-r--r--libstdc++-v3/include/std/charconv59
1 files changed, 28 insertions, 31 deletions
diff --git a/libstdc++-v3/include/std/charconv b/libstdc++-v3/include/std/charconv
index 7aefdd3..a65fbed 100644
--- a/libstdc++-v3/include/std/charconv
+++ b/libstdc++-v3/include/std/charconv
@@ -413,30 +413,36 @@ namespace __detail
return true;
}
- // Construct and return a lookup table that maps 0-9, A-Z and a-z to their
- // corresponding base-36 value and maps all other characters to 127.
- constexpr auto
- __from_chars_alnum_to_val_table()
- {
- constexpr unsigned char __lower_letters[27] = "abcdefghijklmnopqrstuvwxyz";
- constexpr unsigned char __upper_letters[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- struct { unsigned char __data[1u << __CHAR_BIT__] = {}; } __table;
- for (auto& __entry : __table.__data)
- __entry = 127;
- for (int __i = 0; __i < 10; ++__i)
- __table.__data['0' + __i] = __i;
- for (int __i = 0; __i < 26; ++__i)
+ template<bool _DecOnly>
+ struct __from_chars_alnum_to_val_table
+ {
+ struct type { unsigned char __data[1u << __CHAR_BIT__] = {}; };
+
+ // Construct and return a lookup table that maps 0-9, A-Z and a-z to their
+ // corresponding base-36 value and maps all other characters to 127.
+ static constexpr type
+ _S_make_table()
{
- __table.__data[__lower_letters[__i]] = 10 + __i;
- __table.__data[__upper_letters[__i]] = 10 + __i;
+ constexpr unsigned char __lower_letters[27] = "abcdefghijklmnopqrstuvwxyz";
+ constexpr unsigned char __upper_letters[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ type __table;
+ for (auto& __entry : __table.__data)
+ __entry = 127;
+ for (int __i = 0; __i < 10; ++__i)
+ __table.__data['0' + __i] = __i;
+ for (int __i = 0; __i < 26; ++__i)
+ {
+ __table.__data[__lower_letters[__i]] = 10 + __i;
+ __table.__data[__upper_letters[__i]] = 10 + __i;
+ }
+ return __table;
}
- return __table;
- }
-#if __cpp_lib_constexpr_charconv
- template<bool _DecOnly>
- inline constexpr auto __table = __from_chars_alnum_to_val_table();
-#endif
+ // This initializer is made superficially dependent in order
+ // to prevent the compiler from wastefully constructing the
+ // table ahead of time when it's not needed.
+ static constexpr type value = (_DecOnly, _S_make_table());
+ };
// If _DecOnly is true: if the character is a decimal digit, then
// return its corresponding base-10 value, otherwise return a value >= 127.
@@ -449,16 +455,7 @@ namespace __detail
if _GLIBCXX17_CONSTEXPR (_DecOnly)
return static_cast<unsigned char>(__c - '0');
else
- {
-#if __cpp_lib_constexpr_charconv
- if (std::__is_constant_evaluated())
- return __table<_DecOnly>.__data[__c];
-#endif
- // This initializer is deliberately made dependent in order to work
- // around modules bug PR105322.
- static constexpr auto __table = (_DecOnly, __from_chars_alnum_to_val_table());
- return __table.__data[__c];
- }
+ return __from_chars_alnum_to_val_table<_DecOnly>::value.__data[__c];
}
/// std::from_chars implementation for integers in a power-of-two base.