diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2020-01-10 15:27:39 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2020-01-10 15:27:39 +0000 |
commit | 7918cb93f6f752cec468f107eb944dc0da61ec6b (patch) | |
tree | c28d83e2ee9e985e1032aeb5deeeae5013195255 | |
parent | d5c23c6ceacf666f218676b648801379044e326a (diff) | |
download | gcc-7918cb93f6f752cec468f107eb944dc0da61ec6b.zip gcc-7918cb93f6f752cec468f107eb944dc0da61ec6b.tar.gz gcc-7918cb93f6f752cec468f107eb944dc0da61ec6b.tar.bz2 |
libstdc++: Make istreambuf_iterator base class consistent (PR92285)
Since LWG 445 was implemented for GCC 4.7, the std::iterator base class
of std::istreambuf_iterator changes type depending on the -std mode
used. This creates an ABI incompatibility between different -std modes.
This change ensures the base class always has the same type. This makes
layout for C++98 compatible with the current -std=gnu++14 default, but
no longer compatible with C++98 code from previous releases. In practice
this is unlikely to cause real problems, because it only affects the
layout of types with two std::iterator base classes, one of which comes
from std::istreambuf_iterator. Such types are expected to be vanishingly
rare.
PR libstdc++/92285
* include/bits/streambuf_iterator.h (istreambuf_iterator): Make type
of base class independent of __cplusplus value.
[__cplusplus < 201103L] (istreambuf_iterator::reference): Override the
type defined in the base class
* testsuite/24_iterators/istreambuf_iterator/92285.cc: New test.
* testsuite/24_iterators/istreambuf_iterator/requirements/
base_classes.cc: Adjust expected base class for C++98.
From-SVN: r280116
4 files changed, 69 insertions, 14 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 536eb74..d1392c9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,14 @@ +2020-01-10 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/92285 + * include/bits/streambuf_iterator.h (istreambuf_iterator): Make type + of base class independent of __cplusplus value. + [__cplusplus < 201103L] (istreambuf_iterator::reference): Override the + type defined in the base class + * testsuite/24_iterators/istreambuf_iterator/92285.cc: New test. + * testsuite/24_iterators/istreambuf_iterator/requirements/ + base_classes.cc: Adjust expected base class for C++98. + 2020-01-09 Olivier Hainque <hainque@adacore.com> * doc/xml/manual/appendix_contributing.xml: Document _C2 diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index 67dc386..fe612f3 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -49,23 +49,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits> class istreambuf_iterator : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type, - _CharT*, -#if __cplusplus >= 201103L - // LWG 445. - _CharT> -#else - _CharT&> -#endif + _CharT*, _CharT> { public: // Types: //@{ /// Public typedefs -#if __cplusplus > 201703L +#if __cplusplus < 201103L + typedef _CharT& reference; // Changed to _CharT by LWG 445 +#elif __cplusplus > 201703L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3188. istreambuf_iterator::pointer should not be unspecified using pointer = void; #endif + typedef _CharT char_type; typedef _Traits traits_type; typedef typename _Traits::int_type int_type; diff --git a/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/92285.cc b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/92285.cc new file mode 100644 index 0000000..68b4841 --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/92285.cc @@ -0,0 +1,51 @@ +// Copyright (C) 2020 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 <iterator> +#include <iostream> +#include <testsuite_hooks.h> + +// PR libstdc++/92285 +// See https://gcc.gnu.org/ml/libstdc++/2019-10/msg00129.html + +typedef std::input_iterator_tag category; +typedef std::char_traits<char>::off_type off_type; +typedef std::iterator<category, char, off_type, char*, char> good; +typedef std::iterator<category, char, off_type, char*, char&> bad; + +bool check(good&) { return true; } +void check(bad&) { } + +void +test01() +{ + typedef std::istreambuf_iterator<char> I; + I it; + VERIFY( check(it) ); +#if __cplusplus < 201103L + char c = 'c'; + I::reference r = c; + VERIFY( &r == &c ); +#else + static_assert( std::is_same<I::reference, char>::value, "LWG 445" ); +#endif +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/requirements/base_classes.cc b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/requirements/base_classes.cc index 07b0a44..947b772 100644 --- a/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/requirements/base_classes.cc +++ b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/requirements/base_classes.cc @@ -32,12 +32,8 @@ void test01() typedef istreambuf_iterator<char> test_iterator; typedef char_traits<char>::off_type off_type; - typedef iterator<input_iterator_tag, char, off_type, char*, -#if __cplusplus >= 201103L - char> -#else - char&> -#endif + // This is the base class required since LWG 445, which differs from C++03: + typedef iterator<input_iterator_tag, char, off_type, char*, char> base_iterator; istringstream isstream("this tag"); |