Skip to content

Commit 80ef412

Browse files
committed
[libcxx] Use runtime rather then compile-time glibc version check
glibc supports versioning, so it's possible to build against older version and run against newer version. This is sometimes relied on in practice, e.g. in Fuchsia build we build against older sysroot (equivalent to Ubuntu Trusty) to cover the broadest possible range of host systems, but that doesn't necessarily match the system that binary is going to run on which may have newer version, in which case the compile test used in curr_symbol is going to fail. Using runtime check is more reliable. This is a follow up to D56702 which addressed one instance, this patch addresses all of the remaining ones. Differential Revision: https://reviews.llvm.org/D88188
1 parent 35cb45c commit 80ef412

File tree

7 files changed

+32
-47
lines changed

7 files changed

+32
-47
lines changed

libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,9 @@ class my_facetw
5454
// this function converts the spaces in string inputs to that character if need
5555
// be.
5656
static std::wstring convert_thousands_sep(std::wstring const& in) {
57-
#ifndef TEST_GLIBC_PREREQ
58-
#define TEST_GLIBC_PREREQ(x, y) 0
59-
#endif
60-
#if TEST_GLIBC_PREREQ(2,27)
57+
#if defined(_CS_GNU_LIBC_VERSION)
58+
if (glibc_version_less_than("2.27"))
59+
return in;
6160
std::wstring out;
6261
unsigned I = 0;
6362
bool seen_decimal = false;

libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,9 @@ class my_facetw
5454
// this function converts the spaces in string inputs to that character if need
5555
// be.
5656
static std::wstring convert_thousands_sep(std::wstring const& in) {
57-
#ifndef TEST_GLIBC_PREREQ
58-
#define TEST_GLIBC_PREREQ(x, y) 0
59-
#endif
60-
#if TEST_GLIBC_PREREQ(2,27)
57+
#if defined(_CS_GNU_LIBC_VERSION)
58+
if (glibc_version_less_than("2.27"))
59+
return in;
6160
std::wstring out;
6261
unsigned I = 0;
6362
bool seen_num_start = false;

libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,20 +61,6 @@ class Fwt
6161
: std::moneypunct_byname<wchar_t, true>(nm, refs) {}
6262
};
6363

64-
#if defined(_CS_GNU_LIBC_VERSION)
65-
static bool glibc_version_less_than(char const* version) {
66-
std::string test_version = std::string("glibc ") + version;
67-
68-
size_t n = confstr(_CS_GNU_LIBC_VERSION, nullptr, (size_t)0);
69-
char *current_version = new char[n];
70-
confstr(_CS_GNU_LIBC_VERSION, current_version, n);
71-
72-
bool result = strverscmp(current_version, test_version.c_str()) < 0;
73-
delete[] current_version;
74-
return result;
75-
}
76-
#endif
77-
7864
int main(int, char**)
7965
{
8066
{

libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,12 @@ int main(int, char**)
110110
}
111111
// GLIBC 2.23 uses '.' as the decimal point while other C libraries use ','
112112
// GLIBC 2.27 corrects this
113-
#ifndef TEST_GLIBC_PREREQ
114-
#define TEST_GLIBC_PREREQ(x, y) 0
115-
#endif
116-
#if !defined(TEST_HAS_GLIBC) || TEST_GLIBC_PREREQ(2, 27)
113+
#if defined(_CS_GNU_LIBC_VERSION)
114+
const char sep = glibc_version_less_than("2.27") ? '.' : ',';
115+
const wchar_t wsep = glibc_version_less_than("2.27") ? L'.' : L',';
116+
#else
117117
const char sep = ',';
118118
const wchar_t wsep = L',';
119-
#else
120-
const char sep = '.';
121-
const wchar_t wsep = L'.';
122119
#endif
123120
{
124121
Fnf f(LOCALE_ru_RU_UTF_8, 1);

libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,8 @@ int main(int, char**)
103103
assert(f.thousands_sep() == ' ');
104104
}
105105
// The below tests work around GLIBC's use of U202F as mon_thousands_sep.
106-
#ifndef TEST_GLIBC_PREREQ
107-
#define TEST_GLIBC_PREREQ(x, y) 0
108-
#endif
109-
#if defined(TEST_HAS_GLIBC) && TEST_GLIBC_PREREQ(2, 27)
110-
const wchar_t fr_sep = L'\u202F';
106+
#if defined(_CS_GNU_LIBC_VERSION)
107+
const wchar_t fr_sep = glibc_version_less_than("2.27") ? L' ' : L'\u202F';
111108
#else
112109
const wchar_t fr_sep = L' ';
113110
#endif
@@ -123,18 +120,15 @@ int main(int, char**)
123120
// and U002E as mon_decimal_point.
124121
// TODO: Fix thousands_sep for 'char'.
125122
// related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=16006
126-
#ifndef TEST_HAS_GLIBC
123+
#if defined(_CS_GNU_LIBC_VERSION)
127124
const char sep = ' ';
128-
const wchar_t wsep = L' ';
129-
#elif TEST_GLIBC_PREREQ(2, 27)
130125
// FIXME libc++ specifically works around \u00A0 by translating it into
131126
// a regular space.
132-
const char sep = ' ';
133-
const wchar_t wsep = L'\u202F';
127+
const wchar_t wsep = glibc_version_less_than("2.27") ? L'\u00A0' : L'\u202F';
134128
#else
129+
const char sep = ' ';
135130
// FIXME libc++ specifically works around \u00A0 by translating it into
136131
// a regular space.
137-
const char sep = ' ';
138132
const wchar_t wsep = L'\u00A0';
139133
#endif
140134
{

libcxx/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,10 @@ int main(int, char**)
5656
}
5757
{
5858
std::locale l(LOCALE_fr_FR_UTF_8);
59-
#if defined(TEST_HAS_GLIBC)
60-
const char sep = ' ';
6159
// The below tests work around GLIBC's use of U202F as LC_NUMERIC thousands_sep.
62-
# if TEST_GLIBC_PREREQ(2, 27)
63-
const wchar_t wsep = L'\u202f';
64-
# else
65-
const wchar_t wsep = L' ';
66-
# endif
60+
#if defined(_CS_GNU_LIBC_VERSION)
61+
const char sep = ' ';
62+
const wchar_t wsep = glibc_version_less_than("2.27") ? L' ' : L'\u202f';
6763
#else
6864
const char sep = ',';
6965
const wchar_t wsep = L',';

libcxx/test/support/platform_support.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,18 @@ std::wstring get_wide_temp_file_name()
110110

111111
#endif // __CloudABI__
112112

113+
#if defined(_CS_GNU_LIBC_VERSION)
114+
inline bool glibc_version_less_than(char const* version) {
115+
std::string test_version = std::string("glibc ") + version;
116+
117+
size_t n = confstr(_CS_GNU_LIBC_VERSION, nullptr, (size_t)0);
118+
char *current_version = new char[n];
119+
confstr(_CS_GNU_LIBC_VERSION, current_version, n);
120+
121+
bool result = strverscmp(current_version, test_version.c_str()) < 0;
122+
delete[] current_version;
123+
return result;
124+
}
125+
#endif // _CS_GNU_LIBC_VERSION
126+
113127
#endif // PLATFORM_SUPPORT_H

0 commit comments

Comments
 (0)