aboutsummaryrefslogtreecommitdiff
path: root/build2/test/script
diff options
context:
space:
mode:
Diffstat (limited to 'build2/test/script')
-rw-r--r--build2/test/script/regex.cxx35
-rw-r--r--build2/test/script/regex.hxx7
-rw-r--r--build2/test/script/regex.test.cxx3
3 files changed, 42 insertions, 3 deletions
diff --git a/build2/test/script/regex.cxx b/build2/test/script/regex.cxx
index 6b15266..bbd1738 100644
--- a/build2/test/script/regex.cxx
+++ b/build2/test/script/regex.cxx
@@ -2,6 +2,8 @@
// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <locale>
+
#include <build2/test/script/regex.hxx>
using namespace std;
@@ -163,11 +165,40 @@ namespace build2
// line_char_locale
//
+
+ // An exemplar locale with the std::ctype<line_char> facet. It is
+ // used for the subsequent line char locale objects creation (see
+ // below) which normally ends up with a shallow copy of a reference-
+ // counted object.
+ //
+ // Note that creating the line char locales from the exemplar is not
+ // merely an optimization: there is a data race in the libstdc++ (at
+ // least as of GCC 9.1) implementation of the locale(const locale&,
+ // Facet*) constructor (bug #91057).
+ //
+ // Also note that we install the facet in init() rather than during
+ // the object creation to avoid a race with the std::locale-related
+ // global variables initialization.
+ //
+ static locale line_char_locale_exemplar;
+
+ void
+ init ()
+ {
+ line_char_locale_exemplar =
+ locale (locale (),
+ new std::ctype<line_char> ()); // Hidden by ctype bitmask.
+ }
+
line_char_locale::
line_char_locale ()
- : locale (locale (),
- new std::ctype<line_char> ()) // Hidden by ctype bitmask.
+ : locale (line_char_locale_exemplar)
{
+ // Make sure init() has been called.
+ //
+ // Note: has_facet() is hidden by a private function in libc++.
+ //
+ assert (std::has_facet<std::ctype<line_char>> (*this));
}
// char_regex
diff --git a/build2/test/script/regex.hxx b/build2/test/script/regex.hxx
index 500c21b..33a4cba 100644
--- a/build2/test/script/regex.hxx
+++ b/build2/test/script/regex.hxx
@@ -344,6 +344,13 @@ namespace build2
//
line_char_locale ();
};
+
+ // Initialize the testscript regex global state. Should be called once
+ // prior to creating objects of types from this namespace. Note: not
+ // thread-safe.
+ //
+ void
+ init ();
}
}
}
diff --git a/build2/test/script/regex.test.cxx b/build2/test/script/regex.test.cxx
index 7b89e4d..1e48f97 100644
--- a/build2/test/script/regex.test.cxx
+++ b/build2/test/script/regex.test.cxx
@@ -19,6 +19,8 @@ main ()
using cf = char_flags;
using cr = char_regex;
+ init (); // Initializes the testscript regex global state.
+
// Test line_char.
//
{
@@ -183,7 +185,6 @@ main ()
using ct = ctype<lc>;
line_char_locale l;
- assert (has_facet<ct> (l));
// It is better not to create q facet on stack as it is
// reference-countable.