From 7918cb93f6f752cec468f107eb944dc0da61ec6b Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 10 Jan 2020 15:27:39 +0000 Subject: [PATCH] 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 --- libstdc++-v3/ChangeLog | 11 +++++ libstdc++-v3/include/bits/streambuf_iterator.h | 13 +++--- .../24_iterators/istreambuf_iterator/92285.cc | 51 ++++++++++++++++++++++ .../requirements/base_classes.cc | 8 +--- 4 files changed, 69 insertions(+), 14 deletions(-) create mode 100644 libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/92285.cc 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 + + 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 * 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 class istreambuf_iterator : public iterator= 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 +// . + +#include +#include +#include + +// PR libstdc++/92285 +// See https://gcc.gnu.org/ml/libstdc++/2019-10/msg00129.html + +typedef std::input_iterator_tag category; +typedef std::char_traits::off_type off_type; +typedef std::iterator good; +typedef std::iterator bad; + +bool check(good&) { return true; } +void check(bad&) { } + +void +test01() +{ + typedef std::istreambuf_iterator 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::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 test_iterator; typedef char_traits::off_type off_type; - typedef iterator= 201103L - char> -#else - char&> -#endif + // This is the base class required since LWG 445, which differs from C++03: + typedef iterator base_iterator; istringstream isstream("this tag"); -- 2.7.4