diff options
author | timshen <timshen@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-10-02 16:50:39 +0000 |
---|---|---|
committer | timshen <timshen@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-10-02 16:50:39 +0000 |
commit | 1a46491220ef9e8537ab60d7043b89f7ca4781eb (patch) | |
tree | b6da01cc7750f9a33ed063edd4852f1695514a4a /libstdc++-v3 | |
parent | bfb876eadabf410726fe17c9831c04dbc7b51604 (diff) | |
download | ppe42-gcc-1a46491220ef9e8537ab60d7043b89f7ca4781eb.tar.gz ppe42-gcc-1a46491220ef9e8537ab60d7043b89f7ca4781eb.zip |
PR libstdc++/63199
* include/bits/regex.h (basic_regex::basic_regex, basic_regex::assign,
basic_regex::swap): Fix dangling _M_traits reference problem.
* testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/63199.cc:
New test case.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@215805 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 8 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/regex.h | 44 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/63199.cc | 69 |
3 files changed, 107 insertions, 14 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b6d665b0b30..90feb44e0a5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2014-10-02 Tim Shen <timshen@google.com> + + PR libstdc++/63199 + * include/bits/regex.h (basic_regex::basic_regex, basic_regex::assign, + basic_regex::swap): Fix dangling _M_traits reference problem. + * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/63199.cc: + New test case. + 2014-10-01 Jonathan Wakely <jwakely@redhat.com> * doc/xml/manual/status_cxx2011.xml: Corrections. diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h index 9dc83fda562..772a209f2bd 100644 --- a/libstdc++-v3/include/bits/regex.h +++ b/libstdc++-v3/include/bits/regex.h @@ -474,17 +474,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * @param __rhs A @p regex object. */ - basic_regex(const basic_regex& __rhs) = default; + basic_regex(const basic_regex& __rhs) + : _M_flags(__rhs._M_flags), _M_original_str(__rhs._M_original_str) + { this->imbue(__rhs.getloc()); } /** * @brief Move-constructs a basic regular expression. * * @param __rhs A @p regex object. + * + * The implementation is a workaround concerning ABI compatibility. See: + * https://gcc.gnu.org/ml/libstdc++/2014-09/msg00067.html */ - basic_regex(const basic_regex&& __rhs) noexcept - : _M_flags(__rhs._M_flags), _M_traits(__rhs._M_traits), - _M_automaton(std::move(__rhs._M_automaton)) - { } + basic_regex(basic_regex&& __rhs) + : _M_flags(__rhs._M_flags), + _M_original_str(std::move(__rhs._M_original_str)) + { + this->imbue(__rhs.getloc()); + __rhs._M_automaton.reset(); + } /** * @brief Constructs a basic regular expression from the string @@ -555,9 +563,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Move-assigns one regular expression to another. + * + * The implementation is a workaround concerning ABI compatibility. See: + * https://gcc.gnu.org/ml/libstdc++/2014-09/msg00067.html */ basic_regex& - operator=(basic_regex&& __rhs) noexcept + operator=(basic_regex&& __rhs) { return this->assign(std::move(__rhs)); } /** @@ -591,8 +602,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_regex& assign(const basic_regex& __rhs) { - basic_regex __tmp(__rhs); - this->swap(__tmp); + _M_flags = __rhs._M_flags; + _M_original_str = __rhs._M_original_str; + this->imbue(__rhs.getloc()); return *this; } @@ -600,13 +612,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @brief The move-assignment operator. * * @param __rhs Another regular expression object. + * + * The implementation is a workaround concerning ABI compatibility. See: + * https://gcc.gnu.org/ml/libstdc++/2014-09/msg00067.html */ basic_regex& - assign(basic_regex&& __rhs) noexcept + assign(basic_regex&& __rhs) { - basic_regex __tmp(std::move(__rhs)); - this->swap(__tmp); - return *this; + _M_flags = __rhs._M_flags; + _M_original_str = std::move(__rhs._M_original_str); + __rhs._M_automaton.reset(); + this->imbue(__rhs.getloc()); } /** @@ -751,8 +767,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION swap(basic_regex& __rhs) { std::swap(_M_flags, __rhs._M_flags); - std::swap(_M_traits, __rhs._M_traits); - std::swap(_M_automaton, __rhs._M_automaton); + std::swap(_M_original_str, __rhs._M_original_str); + this->imbue(__rhs.imbue(this->getloc())); } #ifdef _GLIBCXX_DEBUG diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/63199.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/63199.cc new file mode 100644 index 00000000000..cbb23f7de53 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/63199.cc @@ -0,0 +1,69 @@ +// { dg-options "-std=gnu++11" } + +// +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <regex> +#include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; + +// libstdc++/63199 +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::setlocale(LC_ALL, ""); + + std::wstring current_token(L"II."); + + std::vector<std::wregex> regex_vector; + + for (int i = 0; i < 4; ++i) + { + std::regex_constants::syntax_option_type flag; + flag = std::regex_constants::ECMAScript | std::regex_constants::icase; + + std::wregex reg; + reg.imbue(std::locale("")); + reg.assign(L"^(M*(?:CM|DC{1,3}|D|CD|C{1,3}){0,1}(?:XC|LX{1,3}|L|XL|X{1,3}){0,1}(?:IX|VI{0,3}|IV|I{1,3}){0,1}\\.)$", flag); + + regex_vector.emplace_back(reg); + } + + for (auto cit = regex_vector.cbegin(); cit != regex_vector.cend(); ++cit) + { + std::wstring::const_iterator it1 = current_token.begin(); + std::wstring::const_iterator it2 = current_token.end(); + std::wsmatch current_token_match; + + regex_match_debug(it1, it2, current_token_match, *cit); + VERIFY(current_token_match[0] == current_token); + VERIFY(current_token_match[1] == current_token); + } +} + +int +main() +{ + test01(); + return 0; +} |