Re: [PING^3] [PATCH] Remove CANADIAN, that break compilation for foreign target

2018-01-30 Thread Petr Ovtchenkov
On Tue, 30 Jan 2018 12:54:21 +
Jonathan Wakely  wrote:

> On 30/01/18 10:19 +0300, Petr Ovtchenkov wrote:
> >On Tue, 19 Dec 2017 11:37:43 +0300
> >Petr Ovtchenkov  wrote:
> >
> >ping^3
> 
> 
> I don't fully understand the consequences (or need) for this patch.
> 
> I asked some other people to look at it, and didn't get confirmation
> it's OK. So I'm reluctant to make the change. Especially this late in
> the GCC 8 cycle.

Hmm, almost two years for this words. Do you really think that
-I/usr/include may be correct in build of cross of some kind
(CANADIAN is just variant of cross)? Of cause, I don't consider
case with rolling target headers in /usr/include.


> 
> 
> >> On Thu, 16 Nov 2017 20:55:37 +0300
> >> Petr Ovtchenkov  wrote:
> >>
> >> > On Wed, 20 Sep 2017 13:44:59 +0300
> >> > Petr Ovtchenkov  wrote:
> >> >
> >> > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71212
> >> > >
> >> > > On Fri, 20 May 2016 16:10:50 +0300
> >> > > Petr Ovtchenkov  wrote:
> >> > >
> >> > > > Some old ad-hoc (adding -I/usr/include to compiler
> >> > > > flags) break compilation of libstdc++ for foreign
> >> > > > target architecture (due to compiler see includes
> >> > > > of native).
> >> >
> >> > Reference for terms:
> >> >
> >> > https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html
> >> >
> >> > Present of "CANADIAN=yes" lead to inclusion of
> >> > headers from build (-I/usr/include). "CANADIAN=yes" used _only_
> >> > to set "-I/usr/include".
> >> >
> >> > Inclusion of build headers in cross-compilation
> >> > process is not a mistake only in case of native (i.e. it is mistake
> >> > for cross, for canadian, for crossed native and for crossback),
> >> > but sometimes give "success".
> >> >
> >> > Note, that build/host/target may be different not only due to
> >> > different architectures, but due to different sysroots
> >> > (libc, kernel, binutils, etc.).
> >> >
> >> > CANADIAN is set to "yes" by code
> >> >
> >> > -  # If Canadian cross, then don't pick up tools from the build 
> >> > directory.
> >> > -  # Used only in GLIBCXX_EXPORT_INCLUDES.
> >> > -  if test -n "$with_cross_host" &&
> >> > - test x"$build_alias" != x"$with_cross_host" &&
> >> > - test x"$build" != x"$target";
> >> > -  then
> >> > -CANADIAN=yes
> >> > -  else
> >> > -CANADIAN=no
> >> > -  fi
> >> >
> >> > and it add "-I/usr/include" to compiler flags for building libstdc++.
> >> > This is wrong.
> >> >
> >> > Reference to patch:
> >> > https://gcc.gnu.org/ml/gcc-patches/2017-09/msg01332.html


Re: [PING^3] [PATCH] Remove CANADIAN, that break compilation for foreign target

2018-01-29 Thread Petr Ovtchenkov
On Tue, 19 Dec 2017 11:37:43 +0300
Petr Ovtchenkov  wrote:

ping^3

> On Thu, 16 Nov 2017 20:55:37 +0300
> Petr Ovtchenkov  wrote:
> 
> > On Wed, 20 Sep 2017 13:44:59 +0300
> > Petr Ovtchenkov  wrote:
> > 
> > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71212
> > > 
> > > On Fri, 20 May 2016 16:10:50 +0300
> > > Petr Ovtchenkov  wrote:
> > > 
> > > > Some old ad-hoc (adding -I/usr/include to compiler
> > > > flags) break compilation of libstdc++ for foreign
> > > > target architecture (due to compiler see includes
> > > > of native).
> > 
> > Reference for terms:
> > 
> > https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html
> > 
> > Present of "CANADIAN=yes" lead to inclusion of
> > headers from build (-I/usr/include). "CANADIAN=yes" used _only_
> > to set "-I/usr/include".
> > 
> > Inclusion of build headers in cross-compilation
> > process is not a mistake only in case of native (i.e. it is mistake
> > for cross, for canadian, for crossed native and for crossback),
> > but sometimes give "success".
> > 
> > Note, that build/host/target may be different not only due to
> > different architectures, but due to different sysroots
> > (libc, kernel, binutils, etc.).
> > 
> > CANADIAN is set to "yes" by code
> > 
> > -  # If Canadian cross, then don't pick up tools from the build directory.
> > -  # Used only in GLIBCXX_EXPORT_INCLUDES.
> > -  if test -n "$with_cross_host" &&
> > - test x"$build_alias" != x"$with_cross_host" &&
> > - test x"$build" != x"$target";
> > -  then
> > -CANADIAN=yes
> > -  else
> > -CANADIAN=no
> > -  fi
> > 
> > and it add "-I/usr/include" to compiler flags for building libstdc++.
> > This is wrong.
> > 
> > Reference to patch:
> > https://gcc.gnu.org/ml/gcc-patches/2017-09/msg01332.html


Re: New istreambuf_iterator debug check

2018-01-24 Thread Petr Ovtchenkov
On Wed, 24 Jan 2018 21:34:48 +0100
François Dumont  wrote:

> On 24/01/2018 18:53, Petr Ovtchenkov wrote:
> > On Wed, 24 Jan 2018 17:39:59 +0100
> > François Dumont  wrote:
> >
> >> Hi
> >>
> >>       I'd like to propose this new debug check. Comparing with non-eos
> >> istreambuf_iterator sounds like an obvious coding mistake.
> >>
> >>       I propose it despite the stage 1 as it is just a new debug check,
> >> it doesn't impact the lib in normal mode.
> >>
> >>       Tested under Linux x86_64, ok to commit ?
> >>
> >> François
> >>
> > bool
> > equal(const istreambuf_iterator& __b) const
> > -  { return _M_at_eof() == __b._M_at_eof(); }
> > +  {
> > +   bool __this_at_eof = _M_at_eof();
> > +   bool __b_at_eof = __b._M_at_eof();
> > +
> > +   __glibcxx_requires_cond(__this_at_eof || __b_at_eof, _M_message(
> > + "Abnormal comparison to non-end-of-stream istreambuf_iterator"));
> > +   return __this_at_eof == __b_at_eof;
> > +  }
> >
> > Looks strange for me. It is legal and possible that istreambuf_iterator
> > will be in EOF state.
> >
> Sure, but consider rather the associated 3_neg.cc showing the debug 
> check purpose:
> 
>    cistreambuf_iter it1(istrs), it2(istrs);
>    it1 == it2; // No sens
> 

This is what author want to say.

Neveretheless, __glibcxx_requires_cond(__this_at_eof || __b_at_eof, ...
in equal looks bogus for me.

--

  - ptr


Re: New istreambuf_iterator debug check

2018-01-24 Thread Petr Ovtchenkov
On Wed, 24 Jan 2018 17:39:59 +0100
François Dumont  wrote:

> Hi
> 
>      I'd like to propose this new debug check. Comparing with non-eos 
> istreambuf_iterator sounds like an obvious coding mistake.
> 
>      I propose it despite the stage 1 as it is just a new debug check, 
> it doesn't impact the lib in normal mode.
> 
>      Tested under Linux x86_64, ok to commit ?
> 
> François
> 

   bool
   equal(const istreambuf_iterator& __b) const
-  { return _M_at_eof() == __b._M_at_eof(); }
+  {
+   bool __this_at_eof = _M_at_eof();
+   bool __b_at_eof = __b._M_at_eof();
+
+   __glibcxx_requires_cond(__this_at_eof || __b_at_eof, _M_message(
+ "Abnormal comparison to non-end-of-stream istreambuf_iterator"));
+   return __this_at_eof == __b_at_eof;
+  }

Looks strange for me. It is legal and possible that istreambuf_iterator
will be in EOF state.

--

  - ptr


Re: [PING^2] [PATCH] Remove CANADIAN, that break compilation for foreign target

2017-12-19 Thread Petr Ovtchenkov
On Thu, 16 Nov 2017 20:55:37 +0300
Petr Ovtchenkov  wrote:

> On Wed, 20 Sep 2017 13:44:59 +0300
> Petr Ovtchenkov  wrote:
> 
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71212
> > 
> > On Fri, 20 May 2016 16:10:50 +0300
> > Petr Ovtchenkov  wrote:
> > 
> > > Some old ad-hoc (adding -I/usr/include to compiler
> > > flags) break compilation of libstdc++ for foreign
> > > target architecture (due to compiler see includes
> > > of native).
> 
> Reference for terms:
> 
> https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html
> 
> Present of "CANADIAN=yes" lead to inclusion of
> headers from build (-I/usr/include). "CANADIAN=yes" used _only_
> to set "-I/usr/include".
> 
> Inclusion of build headers in cross-compilation
> process is not a mistake only in case of native (i.e. it is mistake
> for cross, for canadian, for crossed native and for crossback),
> but sometimes give "success".
> 
> Note, that build/host/target may be different not only due to
> different architectures, but due to different sysroots
> (libc, kernel, binutils, etc.).
> 
> CANADIAN is set to "yes" by code
> 
> -  # If Canadian cross, then don't pick up tools from the build directory.
> -  # Used only in GLIBCXX_EXPORT_INCLUDES.
> -  if test -n "$with_cross_host" &&
> - test x"$build_alias" != x"$with_cross_host" &&
> - test x"$build" != x"$target";
> -  then
> -CANADIAN=yes
> -  else
> -CANADIAN=no
> -  fi
> 
> and it add "-I/usr/include" to compiler flags for building libstdc++.
> This is wrong.
> 
> Reference to patch:
> https://gcc.gnu.org/ml/gcc-patches/2017-09/msg01332.html


Re: Make istreambuf_iterator::_M_sbuf immutable and add debug checks

2017-11-16 Thread Petr Ovtchenkov
On Thu, 16 Nov 2017 18:40:08 +0100
François Dumont  wrote:

> On 16/11/2017 12:46, Jonathan Wakely wrote:
> > On 16/11/17 10:57 +, Jonathan Wakely wrote:
> >> On 16/11/17 08:51 +0300, Petr Ovtchenkov wrote:
> >>> On Mon, 6 Nov 2017 22:19:22 +0100
> >>> François Dumont  wrote:
> >>>
> >>>> Hi
> >>>>
> >>>>     Any final decision regarding this patch ?
> >>>>
> >>>> François
> >>>
> >>> https://gcc.gnu.org/ml/libstdc++/2017-11/msg00036.html
> >>> https://gcc.gnu.org/ml/libstdc++/2017-11/msg00035.html
> >>> https://gcc.gnu.org/ml/libstdc++/2017-11/msg00037.html
> >>> https://gcc.gnu.org/ml/libstdc++/2017-11/msg00034.html
> >>
> >> It would be helpful if you two could collaborate and come up with a
> >> good solution, or at least discuss the pros and cons, instead of just
> >> sending competing patches.
> >
> >
> > Let me be more clear: I'm not going to review further patches in this
> > area while you two are proposing different alternatives, without
> > commenting on each other's approach.
> >
> > If you think your solution is better than François's solution, you
> > should explain why, not just send a different patch. If François
> > thinks his solution is better than yours, he should state why, not
> > just send a different patch.
> >
> > I don't have time to infer all that from just your patches, so I'm not
> > going to bother.
> >
> >
> Proposing to revert my patch doesn't sound to me like a friendly action 
> to start a collaboration.

I'm already say that this is technical issue: this patch present only in
trunk yet. Series is more useful for applying in different branches.
BTW, https://gcc.gnu.org/ml/libstdc++/2017-11/msg00037.html
was inspired by you https://gcc.gnu.org/ml/libstdc++/2017-10/msg00029.html

> 
> My only concern has always been the Debug mode impact which is now fixed.

I hope I'm suggest identical behaviour for Debug and non-Debug mode
(no difference in interaction with associated streambuf).

> 
> I already said that I disagree with Petr's main goal to keep eof 
> iterator linked to the underlying stream.

Ok.

> So current implementation is 
> just fine to me and I'll let Petr argument for any change.

Please, clear for me: what is the "current implementation"?
Is it what we see now in trunk?

> @Jonathan, 
> You can ignore my last request to remove mutable keywork on _M_sbuf.
> 
> François
> 
> 

--

   - ptr


Re: [PING] [PATCH] Remove CANADIAN, that break compilation for foreign target

2017-11-16 Thread Petr Ovtchenkov
On Wed, 20 Sep 2017 13:44:59 +0300
Petr Ovtchenkov  wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71212
> 
> On Fri, 20 May 2016 16:10:50 +0300
> Petr Ovtchenkov  wrote:
> 
> > Some old ad-hoc (adding -I/usr/include to compiler
> > flags) break compilation of libstdc++ for foreign
> > target architecture (due to compiler see includes
> > of native).

Reference for terms:

https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html

Present of "CANADIAN=yes" lead to inclusion of
headers from build (-I/usr/include). "CANADIAN=yes" used _only_
to set "-I/usr/include".

Inclusion of build headers in cross-compilation
process is not a mistake only in case of native (i.e. it is mistake
for cross, for canadian, for crossed native and for crossback),
but sometimes give "success".

Note, that build/host/target may be different not only due to
different architectures, but due to different sysroots
(libc, kernel, binutils, etc.).

CANADIAN is set to "yes" by code

-  # If Canadian cross, then don't pick up tools from the build directory.
-  # Used only in GLIBCXX_EXPORT_INCLUDES.
-  if test -n "$with_cross_host" &&
- test x"$build_alias" != x"$with_cross_host" &&
- test x"$build" != x"$target";
-  then
-CANADIAN=yes
-  else
-CANADIAN=no
-  fi

and it add "-I/usr/include" to compiler flags for building libstdc++.
This is wrong.

Reference to patch:
https://gcc.gnu.org/ml/gcc-patches/2017-09/msg01332.html


Re: Make istreambuf_iterator::_M_sbuf immutable and add debug checks

2017-11-16 Thread Petr Ovtchenkov
On Thu, 16 Nov 2017 11:46:48 +
Jonathan Wakely  wrote:

> On 16/11/17 10:57 +, Jonathan Wakely wrote:
> >On 16/11/17 08:51 +0300, Petr Ovtchenkov wrote:
> >>On Mon, 6 Nov 2017 22:19:22 +0100
> >>François Dumont  wrote:
> >>
> >>>Hi
> >>>
> >>>     Any final decision regarding this patch ?
> >>>
> >>>François
> >>
> >>https://gcc.gnu.org/ml/libstdc++/2017-11/msg00036.html
> >>https://gcc.gnu.org/ml/libstdc++/2017-11/msg00035.html
> >>https://gcc.gnu.org/ml/libstdc++/2017-11/msg00037.html
> >>https://gcc.gnu.org/ml/libstdc++/2017-11/msg00034.html
> >
> >It would be helpful if you two could collaborate and come up with a
> >good solution, or at least discuss the pros and cons, instead of just
> >sending competing patches.
> 
> 
> Let me be more clear: I'm not going to review further patches in this
> area while you two are proposing different alternatives, without
> commenting on each other's approach.
> 
> If you think your solution is better than François's solution, you
> should explain why, not just send a different patch. If François
> thinks his solution is better than yours, he should state why, not
> just send a different patch.
> 
> I don't have time to infer all that from just your patches, so I'm not
> going to bother.
> 

References here is a notification that

   - there is another opinion;
   - discussion is in another thread.

Nothing more.


Re: [PATCH 1/4] Revert "2017-10-04 Petr Ovtchenkov "

2017-11-16 Thread Petr Ovtchenkov
On Thu, 16 Nov 2017 11:39:30 +
Jonathan Wakely  wrote:

> On 16/11/17 14:35 +0300, Petr Ovtchenkov wrote:
> >On Thu, 16 Nov 2017 10:56:29 +
> >Jonathan Wakely  wrote:
> >
> >> On 10/10/17 22:55 +0300, Petr Ovtchenkov wrote:
> >> >This reverts commit 0dfbafdf338cc6899d146add5161e52efb02c067
> >> >(svn r253417).
> >>
> >> I'm not even going to bother to review patches sent without any
> >> explanation or rationale for the change.
> >
> >https://gcc.gnu.org/ml/libstdc++/2017-11/msg00044.html
> >
> >Along with "violate principles of C++ objects life cycle",
> >the side-effect is
> >
> >  - Make istreambuf_iterator::_M_sbuf immutable
> >  - streambuf_iterator: avoid debug-dependent behaviour
> >
> >I should underline, that "_M_sbuf = 0" when istreambuf_iterator
> >see eof, lead to cripple lifecycle of istreambuf_iterator
> >object and [almost] block usage of istreambuf_iterator
> >for entities other then immutable files.
> >
> >All tests from 24_iterators and 25_algorithms passed,
> >so I expect it conform to Standard.
> >
> >This is series of patches, not single patch because
> >I keep in mind technology aspect---easy transfer
> >to branches other then trunk.
> >
> >>
> >> I will repeat what Paolo said: changing the ABI is not acceptable.
> >
> >I will repeat special for you:
> >
> >
> >Is we really worry about frozen sizeof of instantiated template?
> >(Removed private template member).
> >
> >If yes, than
> >
> >   int_type __dummy;
> >
> >is our all.
> >
> >
> >I.e. problem can be easy resolved---i.e. ABI will not suffer, if we will
> 
> What about other translation units which have inlined the old
> definition of the template, and expect to find a buffered character in
> that member?

I can say that I can write

  int_type _M_c;

but you see, this is a _private_ member of template, so we should (may?) worry 
only
about size of object.

Just for clarification: Do you made accent on "buffered" or on "character" 
("symbol" in ELF)?

> 
> >reach some consensus on the main issue.
> 
> We don't have any consensus, in fact I don't see anybody agreeing with
> you, and I've previously stated I don't want to support your use case:
> https://gcc.gnu.org/ml/libstdc++/2017-09/msg00100.html
> 


Re: [PATCH 3/4] libstdc++: avoid character accumulation in istreambuf_iterator

2017-11-16 Thread Petr Ovtchenkov
On Thu, 16 Nov 2017 12:29:37 +0100
Paolo Carlini  wrote:

> Hi,
> 
> On 16/11/2017 12:03, Petr Ovtchenkov wrote:
> > On Thu, 16 Nov 2017 10:39:02 +0100
> > Paolo Carlini  wrote:
> >
> >> Hi,
> >>
> >> On 16/11/2017 06:31, Petr Ovtchenkov wrote:
> >>> Is we really worry about frozen sizeof of instantiated template?
> >> Yes we do. See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
> >> under "Prohibited Changes", point 8.
> >>
> >> Of course removing the buffering has performance implications too -
> >> that's why it's there in the first place!
> > "buffering" here is a secondary buffering (after streambuf).
> > No relation to performance, but place for incoherence with
> > state of attached streambuf.
> It depends, we may be dealing with an unbuffered stream. For sure at the 
> time we measured a performance impact in some cases, likewise whoever 
> implemented it in the first place (not me) otherwise, again, why bothering?

This part of code is from SGI, so I suspect that nobody here really 
measure performance difference between "bufferred" and "non-buffered"
implementations. Just because we have only implementation
with _M_c in isreambuf_iterator.

> 
> Paolo.
> 

--

   - ptr


Re: [PATCH 1/4] Revert "2017-10-04 Petr Ovtchenkov "

2017-11-16 Thread Petr Ovtchenkov
On Thu, 16 Nov 2017 10:56:29 +
Jonathan Wakely  wrote:

> On 10/10/17 22:55 +0300, Petr Ovtchenkov wrote:
> >This reverts commit 0dfbafdf338cc6899d146add5161e52efb02c067
> >(svn r253417).
> 
> I'm not even going to bother to review patches sent without any
> explanation or rationale for the change.

https://gcc.gnu.org/ml/libstdc++/2017-11/msg00044.html

Along with "violate principles of C++ objects life cycle",
the side-effect is

  - Make istreambuf_iterator::_M_sbuf immutable
  - streambuf_iterator: avoid debug-dependent behaviour

I should underline, that "_M_sbuf = 0" when istreambuf_iterator
see eof, lead to cripple lifecycle of istreambuf_iterator
object and [almost] block usage of istreambuf_iterator
for entities other then immutable files.

All tests from 24_iterators and 25_algorithms passed,
so I expect it conform to Standard.

This is series of patches, not single patch because
I keep in mind technology aspect---easy transfer
to branches other then trunk.

> 
> I will repeat what Paolo said: changing the ABI is not acceptable.

I will repeat special for you:


Is we really worry about frozen sizeof of instantiated template?
(Removed private template member).

If yes, than

   int_type __dummy;

is our all.


I.e. problem can be easy resolved---i.e. ABI will not suffer, if we will
reach some consensus on the main issue. 

> 


Re: [PATCH 3/4] libstdc++: avoid character accumulation in istreambuf_iterator

2017-11-16 Thread Petr Ovtchenkov
On Thu, 16 Nov 2017 10:39:02 +0100
Paolo Carlini  wrote:

> Hi,
> 
> On 16/11/2017 06:31, Petr Ovtchenkov wrote:
> > Is we really worry about frozen sizeof of instantiated template? 
> Yes we do. See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html 
> under "Prohibited Changes", point 8.
> 
> Of course removing the buffering has performance implications too - 
> that's why it's there in the first place!

"buffering" here is a secondary buffering (after streambuf).
No relation to performance, but place for incoherence with
state of attached streambuf.

Of cause, I can spend time to measure the difference.

The main point of this patch series is avoidance of lost link between
streambuf and istream_iterator when istream_iterator see eof.
Implementations that forget about attached streambuf after
istream_iterator see eof (or lost synchronization with attached
streambuf) violate principles of C++ objects life cycle.
From practical point of view, such implementation block usage of
istream_iterator for sockets, ttys, etc. --- only non-modified
files remains in scope of application.


> - which I remember we 
> investigated a bit again in the past when somebody reported that a few 
> implementations had it other did not. But I can't say to have followed 
> all the (recently uncovered) conformance implications, it could well be 
> that we cannot be 100% conforming to the letter of the current standard 
> while taking advantage of a buffering mechanism. Jonathan will provide 
> feedback.
> 
> Paolo.

--

  - ptr


Re: Make istreambuf_iterator::_M_sbuf immutable and add debug checks

2017-11-15 Thread Petr Ovtchenkov
On Mon, 6 Nov 2017 22:19:22 +0100
François Dumont  wrote:

> Hi
> 
>      Any final decision regarding this patch ?
> 
> François

https://gcc.gnu.org/ml/libstdc++/2017-11/msg00036.html
https://gcc.gnu.org/ml/libstdc++/2017-11/msg00035.html
https://gcc.gnu.org/ml/libstdc++/2017-11/msg00037.html
https://gcc.gnu.org/ml/libstdc++/2017-11/msg00034.html

--

   - ptr


Re: [PATCH 3/4] libstdc++: avoid character accumulation in istreambuf_iterator

2017-11-15 Thread Petr Ovtchenkov
On Wed, 15 Nov 2017 22:31:11 +0100
Paolo Carlini  wrote:

> Hi,
> 
> On 15/11/2017 11:48, Petr Ovtchenkov wrote:
> > Ask associated streambuf for character when needed instead of
> > accumulate it in istreambuf_iterator object.
> >
> > Benefits from this:
> >- minus one class member in istreambuf_iterator
> >- trivial synchronization of states of istreambuf_iterator
> >  and associated streambuf
> > ---
> >   libstdc++-v3/include/bits/streambuf_iterator.h | 34 
> > --
> >   1 file changed, 15 insertions(+), 19 deletions(-)
> >
> > diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h
> > b/libstdc++-v3/include/bits/streambuf_iterator.h index 08fb13b..203da9d 
> > 100644
> > --- a/libstdc++-v3/include/bits/streambuf_iterator.h
> > +++ b/libstdc++-v3/include/bits/streambuf_iterator.h
> > @@ -95,19 +95,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > // NB: This implementation assumes the "end of stream" value
> > // is EOF, or -1.
> > mutable streambuf_type* _M_sbuf;
> > -  mutable int_type _M_c;
> Obviously this would be an ABI-breaking change, which certainly we don't 
> want. Unless I missed a detailed discussion of the non-trivial way to 
> avoid it in one of the recent threads about these topics...

Is we really worry about frozen sizeof of instantiated template?
(Removed private template member).

If yes, than

   int_type __dummy;

is our all.

> 
> Paolo.

--

   - ptr


[PATCH 2/4] libstdc++: istreambuf_iterator keep attached streambuf

2017-11-15 Thread Petr Ovtchenkov
istreambuf_iterator should not forget about attached
streambuf when it reach EOF.

Checks in debug mode has no infuence more on character
extraction in istreambuf_iterator increment operators.
In this aspect behaviour in debug and non-debug mode
is similar now.

Test for detached srteambuf in istreambuf_iterator:
When istreambuf_iterator reach EOF of istream, it should not
forget about attached streambuf.
>From fact "EOF in stream reached" not follow that
stream reach end of life and input operation impossible
more.

postfix increment (r++) return proxy object, due to

  copies of the previous value of r are no longer
  required either to be dereferenceable or to be in
  the domain of ==.

i.e. type that usable only for dereference and extraction
"previous" character.

istreambuf_iterator should has ctor from proxy object,
so proxy should store pointer to streambuf object.
---
 libstdc++-v3/include/bits/streambuf_iterator.h | 67 ++
 .../24_iterators/istreambuf_iterator/3.cc  | 66 +
 2 files changed, 109 insertions(+), 24 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/3.cc

diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h 
b/libstdc++-v3/include/bits/streambuf_iterator.h
index 69ee013..08fb13b 100644
--- a/libstdc++-v3/include/bits/streambuf_iterator.h
+++ b/libstdc++-v3/include/bits/streambuf_iterator.h
@@ -98,6 +98,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   mutable int_type _M_c;
 
 public:
+  class proxy
+  {
+  friend class istreambuf_iterator;
+  private:
+  proxy(int_type c, streambuf_type*sbuf_) :
+  _M_c(c),
+  _M_sbuf(sbuf_)
+  { }
+  int_type _M_c;
+  streambuf_type*  _M_sbuf;
+
+  public:
+  char_type
+  operator*() const
+  { return traits_type::to_char_type(_M_c); }
+  };
+
+public:
   ///  Construct end of input stream iterator.
   _GLIBCXX_CONSTEXPR istreambuf_iterator() _GLIBCXX_USE_NOEXCEPT
   : _M_sbuf(0), _M_c(traits_type::eof()) { }
@@ -116,6 +134,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   istreambuf_iterator(streambuf_type* __s) _GLIBCXX_USE_NOEXCEPT
   : _M_sbuf(__s), _M_c(traits_type::eof()) { }
 
+  ///  Construct start of istreambuf iterator.
+  istreambuf_iterator(const proxy& __p) _GLIBCXX_USE_NOEXCEPT
+  : _M_sbuf(__p._M_sbuf), _M_c(traits_type::eof()) { }
+
   ///  Return the current character pointed to by iterator.  This returns
   ///  streambuf.sgetc().  It cannot be assigned.  NB: The result of
   ///  operator*() on an end of stream is undefined.
@@ -136,29 +158,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   istreambuf_iterator&
   operator++()
   {
-   __glibcxx_requires_cond(!_M_at_eof(),
+   __glibcxx_requires_cond(_M_sbuf,
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
if (_M_sbuf)
  {
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+   int_type __tmp =
+#endif
_M_sbuf->sbumpc();
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+   
__glibcxx_requires_cond(!traits_type::eq_int_type(__tmp,traits_type::eof()),
+   
_M_message(__gnu_debug::__msg_inc_istreambuf)
+   ._M_iterator(*this));
+#endif
_M_c = traits_type::eof();
  }
return *this;
   }
 
   /// Advance the iterator.  Calls streambuf.sbumpc().
-  istreambuf_iterator
+  proxy
   operator++(int)
   {
-   __glibcxx_requires_cond(!_M_at_eof(),
+_M_get();
+   __glibcxx_requires_cond(_M_sbuf
+   && 
!traits_type::eq_int_type(_M_c,traits_type::eof()),
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
 
-   istreambuf_iterator __old = *this;
+   proxy __old(_M_c, _M_sbuf);
if (_M_sbuf)
  {
-   __old._M_c = _M_sbuf->sbumpc();
+   _M_sbuf->sbumpc();
_M_c = traits_type::eof();
  }
return __old;
@@ -177,18 +209,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _M_get() const
   {
const int_type __eof = traits_type::eof();
-   int_type __ret = __eof;
-   if (_M_sbuf)
- {
-   if (!traits_type::eq_int_type(_M_c, __eof))
- __ret = _M_c;
-   else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()),
-  __eof))
- _M_c = __ret;
-   else
- _M_sbuf = 0;
- }
-   return __ret;
+   if (_M_sbuf && traits_type::eq_int_type(_M_c, __eof))
+  _M_c = _M_sbuf->sgetc();
+   return _M_c;
   }
 
   bool
@@ -339,7 +362,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   typedef typename __is_it

[PATCH 1/4] Revert "2017-10-04 Petr Ovtchenkov "

2017-11-15 Thread Petr Ovtchenkov
This reverts commit 0dfbafdf338cc6899d146add5161e52efb02c067
(svn r253417).
---
 libstdc++-v3/include/bits/streambuf_iterator.h | 59 ++
 1 file changed, 33 insertions(+), 26 deletions(-)

diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h 
b/libstdc++-v3/include/bits/streambuf_iterator.h
index 081afe5..69ee013 100644
--- a/libstdc++-v3/include/bits/streambuf_iterator.h
+++ b/libstdc++-v3/include/bits/streambuf_iterator.h
@@ -95,7 +95,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // NB: This implementation assumes the "end of stream" value
   // is EOF, or -1.
   mutable streambuf_type*  _M_sbuf;
-  int_type _M_c;
+  mutable int_type _M_c;
 
 public:
   ///  Construct end of input stream iterator.
@@ -122,29 +122,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   char_type
   operator*() const
   {
-   int_type __c = _M_get();
-
 #ifdef _GLIBCXX_DEBUG_PEDANTIC
// Dereferencing a past-the-end istreambuf_iterator is a
// libstdc++ extension
-   __glibcxx_requires_cond(!_S_is_eof(__c),
+   __glibcxx_requires_cond(!_M_at_eof(),
_M_message(__gnu_debug::__msg_deref_istreambuf)
._M_iterator(*this));
 #endif
-   return traits_type::to_char_type(__c);
+   return traits_type::to_char_type(_M_get());
   }
 
   /// Advance the iterator.  Calls streambuf.sbumpc().
   istreambuf_iterator&
   operator++()
   {
-   __glibcxx_requires_cond(_M_sbuf &&
-   (!_S_is_eof(_M_c) || 
!_S_is_eof(_M_sbuf->sgetc())),
+   __glibcxx_requires_cond(!_M_at_eof(),
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
-
-   _M_sbuf->sbumpc();
-   _M_c = traits_type::eof();
+   if (_M_sbuf)
+ {
+   _M_sbuf->sbumpc();
+   _M_c = traits_type::eof();
+ }
return *this;
   }
 
@@ -152,14 +151,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   istreambuf_iterator
   operator++(int)
   {
-   __glibcxx_requires_cond(_M_sbuf &&
-   (!_S_is_eof(_M_c) || 
!_S_is_eof(_M_sbuf->sgetc())),
+   __glibcxx_requires_cond(!_M_at_eof(),
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
 
istreambuf_iterator __old = *this;
-   __old._M_c = _M_sbuf->sbumpc();
-   _M_c = traits_type::eof();
+   if (_M_sbuf)
+ {
+   __old._M_c = _M_sbuf->sbumpc();
+   _M_c = traits_type::eof();
+ }
return __old;
   }
 
@@ -175,21 +176,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   int_type
   _M_get() const
   {
-   int_type __ret = _M_c;
-   if (_M_sbuf && _S_is_eof(__ret) && _S_is_eof(__ret = _M_sbuf->sgetc()))
- _M_sbuf = 0;
+   const int_type __eof = traits_type::eof();
+   int_type __ret = __eof;
+   if (_M_sbuf)
+ {
+   if (!traits_type::eq_int_type(_M_c, __eof))
+ __ret = _M_c;
+   else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()),
+  __eof))
+ _M_c = __ret;
+   else
+ _M_sbuf = 0;
+ }
return __ret;
   }
 
   bool
   _M_at_eof() const
-  { return _S_is_eof(_M_get()); }
-
-  static bool
-  _S_is_eof(int_type __c)
   {
const int_type __eof = traits_type::eof();
-   return traits_type::eq_int_type(__c, __eof);
+   return traits_type::eq_int_type(_M_get(), __eof);
   }
 };
 
@@ -367,14 +373,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   typedef typename __is_iterator_type::traits_type traits_type;
   typedef typename __is_iterator_type::streambuf_type  streambuf_type;
   typedef typename traits_type::int_type   int_type;
-  const int_type __eof = traits_type::eof();
 
   if (__first._M_sbuf && !__last._M_sbuf)
{
  const int_type __ival = traits_type::to_int_type(__val);
  streambuf_type* __sb = __first._M_sbuf;
  int_type __c = __sb->sgetc();
- while (!traits_type::eq_int_type(__c, __eof)
+ while (!traits_type::eq_int_type(__c, traits_type::eof())
 && !traits_type::eq_int_type(__c, __ival))
{
  streamsize __n = __sb->egptr() - __sb->gptr();
@@ -391,9 +396,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__c = __sb->snextc();
}
 
- __first._M_c = __eof;
+ if (!traits_type::eq_int_type(__c, traits_type::eof()))
+   __first._M_c = __c;
+ else
+   __first._M_sbuf = 0;
}
-
   return __first;
 }
 
-- 
2.10.1



[PATCH 3/4] libstdc++: avoid character accumulation in istreambuf_iterator

2017-11-15 Thread Petr Ovtchenkov
Ask associated streambuf for character when needed instead of
accumulate it in istreambuf_iterator object.

Benefits from this:
  - minus one class member in istreambuf_iterator
  - trivial synchronization of states of istreambuf_iterator
and associated streambuf
---
 libstdc++-v3/include/bits/streambuf_iterator.h | 34 --
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h 
b/libstdc++-v3/include/bits/streambuf_iterator.h
index 08fb13b..203da9d 100644
--- a/libstdc++-v3/include/bits/streambuf_iterator.h
+++ b/libstdc++-v3/include/bits/streambuf_iterator.h
@@ -95,19 +95,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // NB: This implementation assumes the "end of stream" value
   // is EOF, or -1.
   mutable streambuf_type*  _M_sbuf;
-  mutable int_type _M_c;
 
 public:
   class proxy
   {
   friend class istreambuf_iterator;
   private:
-  proxy(int_type c, streambuf_type*sbuf_) :
+  proxy(int_type c, streambuf_type* sbuf_) :
   _M_c(c),
   _M_sbuf(sbuf_)
   { }
   int_type _M_c;
-  streambuf_type*  _M_sbuf;
+  streambuf_type* _M_sbuf;
 
   public:
   char_type
@@ -118,7 +117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 public:
   ///  Construct end of input stream iterator.
   _GLIBCXX_CONSTEXPR istreambuf_iterator() _GLIBCXX_USE_NOEXCEPT
-  : _M_sbuf(0), _M_c(traits_type::eof()) { }
+  : _M_sbuf(0) { }
 
 #if __cplusplus >= 201103L
   istreambuf_iterator(const istreambuf_iterator&) noexcept = default;
@@ -128,15 +127,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   ///  Construct start of input stream iterator.
   istreambuf_iterator(istream_type& __s) _GLIBCXX_USE_NOEXCEPT
-  : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { }
+  : _M_sbuf(__s.rdbuf()) { }
 
   ///  Construct start of streambuf iterator.
   istreambuf_iterator(streambuf_type* __s) _GLIBCXX_USE_NOEXCEPT
-  : _M_sbuf(__s), _M_c(traits_type::eof()) { }
+  : _M_sbuf(__s) { }
 
   ///  Construct start of istreambuf iterator.
   istreambuf_iterator(const proxy& __p) _GLIBCXX_USE_NOEXCEPT
-  : _M_sbuf(__p._M_sbuf), _M_c(traits_type::eof()) { }
+  : _M_sbuf(__p._M_sbuf) { }
 
   ///  Return the current character pointed to by iterator.  This returns
   ///  streambuf.sgetc().  It cannot be assigned.  NB: The result of
@@ -147,11 +146,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #ifdef _GLIBCXX_DEBUG_PEDANTIC
// Dereferencing a past-the-end istreambuf_iterator is a
// libstdc++ extension
-   __glibcxx_requires_cond(!_M_at_eof(),
+   int_type __tmp = _M_get();
+   
__glibcxx_requires_cond(!traits_type::eq_int_type(__tmp,traits_type::eof()),
_M_message(__gnu_debug::__msg_deref_istreambuf)
._M_iterator(*this));
-#endif
+   return traits_type::to_char_type(__tmp);
+#else
return traits_type::to_char_type(_M_get());
+#endif
   }
 
   /// Advance the iterator.  Calls streambuf.sbumpc().
@@ -172,7 +174,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION

_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
 #endif
-   _M_c = traits_type::eof();
  }
return *this;
   }
@@ -181,17 +182,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   proxy
   operator++(int)
   {
-_M_get();
-   __glibcxx_requires_cond(_M_sbuf
-   && 
!traits_type::eq_int_type(_M_c,traits_type::eof()),
+int_type c = _M_get();
+   __glibcxx_requires_cond(!traits_type::eq_int_type(c,traits_type::eof()),
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
 
-   proxy __old(_M_c, _M_sbuf);
+   proxy __old(c, _M_sbuf);
if (_M_sbuf)
  {
_M_sbuf->sbumpc();
-   _M_c = traits_type::eof();
  }
return __old;
   }
@@ -209,9 +208,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _M_get() const
   {
const int_type __eof = traits_type::eof();
-   if (_M_sbuf && traits_type::eq_int_type(_M_c, __eof))
-  _M_c = _M_sbuf->sgetc();
-   return _M_c;
+   return _M_sbuf ? _M_sbuf->sgetc() : __eof;
   }
 
   bool
@@ -418,7 +415,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  else
__c = __sb->snextc();
}
- __first._M_c = __c;
}
   return __first;
 }
-- 
2.10.1



[PATCH 4/4] libstdc++: immutable _M_sbuf in istreambuf_iterator

2017-11-15 Thread Petr Ovtchenkov
No needs to have mutable _M_sbuf in istreambuf_iterator
more.
---
 libstdc++-v3/include/bits/streambuf_iterator.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h 
b/libstdc++-v3/include/bits/streambuf_iterator.h
index 203da9d..e2b6707 100644
--- a/libstdc++-v3/include/bits/streambuf_iterator.h
+++ b/libstdc++-v3/include/bits/streambuf_iterator.h
@@ -94,7 +94,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // the "end of stream" iterator value.
   // NB: This implementation assumes the "end of stream" value
   // is EOF, or -1.
-  mutable streambuf_type*  _M_sbuf;
+  streambuf_type* _M_sbuf;
 
 public:
   class proxy
-- 
2.10.1



Re: [libstdc++, patch] Fix build on APFS file system

2017-10-19 Thread Petr Ovtchenkov
On Thu, 19 Oct 2017 10:37:14 +0200
Richard Biener  wrote:

> On Wed, Oct 18, 2017 at 11:58 PM, FX  wrote:
> >> Could you test using .PHONY: install-headers instead?
> >> That target *is* phony, so telling make that seems sensible.
> >
> > I’ve tried adding it to the existing .PHONY list:
> >
> > Index: libstdc++-v3/include/Makefile.in
> > ===
> > --- libstdc++-v3/include/Makefile.in(revision 253855)
> > +++ libstdc++-v3/include/Makefile.in(working copy)
> > @@ -1449,6 +1449,7 @@ uninstall-am:
> > distclean-libtool dvi dvi-am html html-am info info-am install \
> > install-am install-data install-data-am install-data-local \
> > install-dvi install-dvi-am install-exec install-exec-am \
> > +   install-freestanding-headers install-headers \
> > install-html install-html-am install-info install-info-am \
> > install-man install-pdf install-pdf-am install-ps \
> > install-ps-am install-strip installcheck installcheck-am \
> >
> >
> > But that doesn’t work:
> >
> > In file included
> > from 
> > /Users/fx/devel/gcc/ibin/x86_64-apple-darwin17.0.0/i386/libstdc++-v3/include/bits/exception_ptr.h:39:0,
> > from /Users/fx/devel/gcc/trunk/libstdc++-v3/libsupc++/exception:143,
> > from 
> > /Users/fx/devel/gcc/ibin/x86_64-apple-darwin17.0.0/i386/libstdc++-v3/include/ios:39,
> > from 
> > /Users/fx/devel/gcc/ibin/x86_64-apple-darwin17.0.0/i386/libstdc++-v3/include/istream:38,
> > from 
> > /Users/fx/devel/gcc/ibin/x86_64-apple-darwin17.0.0/i386/libstdc++-v3/include/sstream:38,
> > from 
> > /Users/fx/devel/gcc/ibin/x86_64-apple-darwin17.0.0/i386/libstdc++-v3/include/complex:45,
> > from 
> > /Users/fx/devel/gcc/ibin/x86_64-apple-darwin17.0.0/i386/libstdc++-v3/include/ccomplex:39,
> > from 
> > /Users/fx/devel/gcc/trunk/libstdc++-v3/include/precompiled/stdc++.h:52: 
> > /Users/fx/devel/gcc/trunk/libstdc++-v3/libsupc++/typeinfo:36:10:
> > fatal error: bits/hash_bytes.h: No such file or directory #include 
> > 
> >   ^~~
> 
> So the issue is PCH generation (why's that re-generated at install time?).

May be indeed: I have a lot parallel builds and never see problem like this,
but I skip PCH generation.

--

   - ptr


Re: [libstdc++, patch] Fix build on APFS file system

2017-10-18 Thread Petr Ovtchenkov
On Wed, 18 Oct 2017 16:51:37 +0200
FX  wrote:

> Parallel builds of libstdc++ on APFS filesystem (with 1 ns granularity) on 
> macOS 10.13 often fail
> (failure rate for “make -j2” to “make -j8” is about 60% from my own builds 
> and results reported
> by others): https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81797 This is 
> reproducible with several
> versions of GNU make.
> 
> Changing libstdc++’s makefile to mark install-headers with .NOTPARALLEL fixes 
> the issue. We've
> carried that patch in Homebrew (https://brew.sh) for a few months now, and 
> have had no report of
> build issues since then.
> 
> Bootstrapped and regtested on x86_64-apple-darwin17 (as well as other 
> platforms). OK to commit?
> 
> FX
> 
> 

From supplied info not follow that problem is on gcc build side.
I can suspect that APFS has problem with direntry intensive
modification, for example.

--

  - ptr


Re: [PATCH] libstdc++: istreambuf_iterator proxy

2017-10-09 Thread Petr Ovtchenkov
On Sun, 8 Oct 2017 16:59:39 +0200
François Dumont  wrote:

> ...
> >>> We have three issues with istreambuf_iterator:
> >>> - debug-dependent behaviour
> >> Fixed.
> > +   __glibcxx_requires_cond(_M_sbuf,
> > _M_message(__gnu_debug::__msg_inc_istreambuf)
> > ._M_iterator(*this));
> > vs
> >
> > +   __glibcxx_requires_cond(_M_sbuf && !_S_is_eof(_M_sbuf->sgetc()),
> > _M_message(__gnu_debug::__msg_inc_istreambuf)
> > ._M_iterator(*this));
> >
> > and
> >
> > +   __glibcxx_requires_cond(_M_sbuf
> > +   && 
> > !traits_type::eq_int_type(_M_c,traits_type::eof()),
> > _M_message(__gnu_debug::__msg_inc_istreambuf)
> > ._M_iterator(*this));
> > vs
> >
> > +   __glibcxx_requires_cond(_M_sbuf && !_S_is_eof(_M_sbuf->sgetc()),
> > _M_message(__gnu_debug::__msg_inc_istreambuf)
> > ._M_iterator(*this));
> >
> > I'm insist on the first variant. It free from code that may lead to 
> > different
> > behaviour between debug/non-debug (like _M_sbuf->sgetc()).
> 
> The first patch fixed the impact of the Debug mode on the 
> istreambuf_iterator state. This kind of difference is classical with 
> Debug mode, this mode usually introduces additional calls to some 
> operators or in this case to sgetc.
> 

The key is "_M_sbuf->sgetc()" and "_S_is_eof" that may call ->sgetc() too.
This may lead to difference in debug/non-debug behaviour.
Solution without such difference exist and was presented here.


Re: [PATCH] libstdc++: istreambuf_iterator proxy

2017-10-09 Thread Petr Ovtchenkov
On Sun, 8 Oct 2017 16:59:39 +0200
François Dumont  wrote:

> ...
> >>
> >> Consider this code:
> >>
> >>     std::istringstream inf("abc");
> >>     std::istreambuf_iterator j(inf), eof;
> >>     std::istreambuf_iterator i = j++;
> >>
> >>     assert( *i == 'a' );
> >>
> >> At this point it looks like i is pointing to 'a' but then when you do:
> >>
> >> std::string str(i, eof);
> >>
> >> you have:
> >> assert( str == "ac" );
> > No. I mean that in last (my) suggestion ([PATCH])
> >
> > std::istreambuf_iterator i = j++;
> >
> > is impossible ("impossible" is in aggree with standard).
> > So test test01() in 2.cc isn't correct.
> 
> It is correct as this constructor:
> +  /// Construct start of streambuf iterator.
> +  istreambuf_iterator(const proxy& __prx) _GLIBCXX_USE_NOEXCEPT
> +  : _M_sbuf(__prx._M_sbuf)
> +  { }
> 
> is defined by the Standard. This is why the llvm test is fine too.

Yes, you right here.

But in

+  std::istringstream inf("abc");
+  std::istreambuf_iterator j(inf);
+  std::istreambuf_iterator i = j++;
+
+  VERIFY( i != std::istreambuf_iterator() );
+  VERIFY( *i == 'b' );
+  VERIFY( *j++ == 'b' );

the last two lines

+  VERIFY( *i == 'b' );
+  VERIFY( *j++ == 'b' );

is a check of the implementation-specific behaviour, because of

  ++r ... any copies of the previous
  value of r are no longer
  required either to be
  dereferenceable or to be in
  the domain of ==.
  ...
  (void)r++equivalent to (void)++r

(i is a copy of "previous" value of j)


From other side, for ctor from proxy

   istreambuf_iterator(const proxy& p) noexcept;
5  Effects: Initializes sbuf_ with p.sbuf_.

that mean that reference of istreambuf_iterator to basic_streambuf
(sbuf_) has some meaning. proxy may be dereferenced or used
to produce istreambuf_iterator that may be used for == (but not
for dereference itself ;)).



Re: [PATCH] libstdc++: istreambuf_iterator proxy (was: keep attached streambuf)

2017-10-06 Thread Petr Ovtchenkov
On Fri, 6 Oct 2017 18:01:36 +0200
François Dumont  wrote:

> ...
> >>> The test itself simulate "stop and go" istream usage.
> >>> stringstream is convenient for behaviuor illustration, but in "real life"
> >>> I can assume socket or tty on this place.
> >> At the very minimum we should have a comment in the test explaining
> >> how it relies on non-standard, non-portable behaviour.
> >>
> >> But I'd prefer to avoid introducing more divergence from other
> >> implementations.
> > Standard itself say nothting about "stop and go" scenario.
> > At least I don't see any words pro or contra.
> > But current implementation block usage of istreambuf_iterator
> > with underlying streams like socket or tty, so istreambuf_iterator become
> > almost useless structure for practice.
> Why not creating a new istreambuf_iterator each time you need to check 
> that streambuf is not in eof anymore ?

It's strange question. Because EOL (end-of-life) for istreambuf_iterator
object after EOF of associated streambuf 

  - not directly follow from standard, just follow from (IMO wrong)
implementations; and this is a balk for useful usage of istreambuf_iterator;
  - violate expectations from point of view of C++ objects life cycle;
  - require destruction and construction of istreambuf_iterator
object after check for equality with istreambuf_iterator()
(strange trick).

> 
> > We have three issues with istreambuf_iterator:
> >- debug-dependent behaviour
> Fixed.

+   __glibcxx_requires_cond(_M_sbuf,
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
vs

+   __glibcxx_requires_cond(_M_sbuf && !_S_is_eof(_M_sbuf->sgetc()),
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));

and

+   __glibcxx_requires_cond(_M_sbuf
+   && 
!traits_type::eq_int_type(_M_c,traits_type::eof()),
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
vs

+   __glibcxx_requires_cond(_M_sbuf && !_S_is_eof(_M_sbuf->sgetc()),
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));

I'm insist on the first variant. It free from code that may lead to different
behaviour between debug/non-debug (like _M_sbuf->sgetc()).



> >- EOL of istreambuf_iterator when it reach EOF (but this not mean
> >  EOL of associated streambuf)
> Controversial.
> >- postfix increment operator return istreambuf_iterator, but here
> >  expected restricted type, that accept only dereference, if it possible.
> I agree that we need to fix this last point too.
> 
> Consider this code:
> 
>    std::istringstream inf("abc");
>    std::istreambuf_iterator j(inf), eof;
>    std::istreambuf_iterator i = j++;
> 
>    assert( *i == 'a' );
> 
> At this point it looks like i is pointing to 'a' but then when you do:
> 
> std::string str(i, eof);
> 
> you have:
> assert( str == "ac" );

No. I mean that in last (my) suggestion ([PATCH])

   std::istreambuf_iterator i = j++;

is impossible ("impossible" is in aggree with standard).
So test test01() in 2.cc isn't correct.

> 
> We jump other the 'b'.
> 
> We could improve the situation by adding a debug assertion that _M_c is 
> eof when pre-increment is being used or by changing semantic of 
> pre-increment to only call sbumpc if _M_c is eof. But then we would need 
> to consider _M_c in find overload and in some other places in the lib I 
> think.
> 
> Rather than going through this complicated path I agree with Petr that 
> we need to simply implement the solution advised by the Standard with 
> the nested proxy type.
> 
> This is what I have done in the attached patch in a naive way. Do we 
> need to have abi compatibility here ? If so I'll rework it.
> 
> This patch will make libstdc++ pass the llvm test. I even duplicate it 
> on our side with a small refinement to check for the return value of the 
> proxy::operator*().
> 
> François
> 

--

  - ptr


Re: [Libgomp, Fortran] Fix canadian cross build

2017-10-05 Thread Petr Ovtchenkov
On Thu, 5 Oct 2017 12:56:36 +0200
Yvan Roux  wrote:

> On 5 September 2017 at 12:04, Jakub Jelinek  wrote:
> > On Tue, Sep 05, 2017 at 10:58:22AM +0200, Yvan Roux wrote:
> >> ping
> >>
> >> https://gcc.gnu.org/ml/gcc-patches/2017-06/msg01784.html
> >
> > This really needs to be reviewed by a build machinery maintainer.
> 
> Thanks for the CC list update Jakub, ping again then...
> 
> https://gcc.gnu.org/ml/gcc-patches/2017-06/msg01784.html

BTW,

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71212
https://gcc.gnu.org/ml/gcc-patches/2017-09/msg01332.html
https://gcc.gnu.org/ml/gcc-patches/2017-09/msg01334.html

> 
> >> > config/ChangeLog
> >> > 2017-06-23  Yvan Roux  
> >> >
> >> > * acx.m4 (NCN_STRICT_CHECK_TARGET_TOOLS): Renamed to ...
> >> > (NCN_STRICT_PATH_TARGET_TOOLS): ... this.  It reflects the 
> >> > replacement
> >> > of AC_CHECK_PROG by AC_PATH_PROG to get the absolute name of 
> >> > the
> >> > program.
> >> > (ACX_CHECK_INSTALLED_TARGET_TOOL): Use renamed function.
> >> >
> >> > ChangeLog
> >> > 2017-06-23  Yvan Roux  
> >> >
> >> > * configure.ac: Use NCN_STRICT_PATH_TARGET_TOOLS instead of
> >> > NCN_STRICT_CHECK_TARGET_TOOLS.
> >> > * configure: Regenerate.
> >
> > Jakub

--

   - ptr


[PATCH v2] libstdc++: istreambuf_iterator keep attached streambuf

2017-10-03 Thread Petr Ovtchenkov
istreambuf_iterator should not forget about attached
streambuf when it reach EOF.

Checks in debug mode has no infuence more on character
extraction in istreambuf_iterator increment operators.
In this aspect behaviour in debug and non-debug mode
is similar now.

Test for detached srteambuf in istreambuf_iterator:
When istreambuf_iterator reach EOF of istream, it should not
forget about attached streambuf.
>From fact "EOF in stream reached" not follow that
stream reach end of life and input operation impossible
more.

postfix increment (r++) return isb_iterator_proxy, due to

  copies of the previous value of r are no longer
  required either to be dereferenceable or to be in
  the domain of ==.

i.e. type that usable only for dereference and extraction
"previous" character.
---
 libstdc++-v3/include/bits/streambuf_iterator.h | 60 
 .../24_iterators/istreambuf_iterator/3.cc  | 64 ++
 2 files changed, 100 insertions(+), 24 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/3.cc

diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h 
b/libstdc++-v3/include/bits/streambuf_iterator.h
index f0451b1..b71bdd2 100644
--- a/libstdc++-v3/include/bits/streambuf_iterator.h
+++ b/libstdc++-v3/include/bits/streambuf_iterator.h
@@ -97,6 +97,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   mutable streambuf_type*  _M_sbuf;
   mutable int_type _M_c;
 
+  class isb_iterator_proxy
+  {
+  friend class istreambuf_iterator;
+  private:
+  isb_iterator_proxy(int_type c) :
+  _M_c(c)
+  { }
+  int_type _M_c;
+
+  public:
+  char_type
+  operator*() const
+  { return traits_type::to_char_type(_M_c); }
+  };
+
 public:
   ///  Construct end of input stream iterator.
   _GLIBCXX_CONSTEXPR istreambuf_iterator() _GLIBCXX_USE_NOEXCEPT
@@ -136,29 +151,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   istreambuf_iterator&
   operator++()
   {
-   __glibcxx_requires_cond(!_M_at_eof(),
+   __glibcxx_requires_cond(_M_sbuf,
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
if (_M_sbuf)
  {
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+   int_type __tmp =
+#endif
_M_sbuf->sbumpc();
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+   
__glibcxx_requires_cond(!traits_type::eq_int_type(__tmp,traits_type::eof()),
+   
_M_message(__gnu_debug::__msg_inc_istreambuf)
+   ._M_iterator(*this));
+#endif
_M_c = traits_type::eof();
  }
return *this;
   }
 
   /// Advance the iterator.  Calls streambuf.sbumpc().
-  istreambuf_iterator
+  isb_iterator_proxy
   operator++(int)
   {
-   __glibcxx_requires_cond(!_M_at_eof(),
+_M_get();
+   __glibcxx_requires_cond(_M_sbuf
+   && 
!traits_type::eq_int_type(_M_c,traits_type::eof()),
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
 
-   istreambuf_iterator __old = *this;
+   isb_iterator_proxy __old(_M_c);
if (_M_sbuf)
  {
-   __old._M_c = _M_sbuf->sbumpc();
+   _M_sbuf->sbumpc();
_M_c = traits_type::eof();
  }
return __old;
@@ -177,18 +202,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _M_get() const
   {
const int_type __eof = traits_type::eof();
-   int_type __ret = __eof;
-   if (_M_sbuf)
- {
-   if (!traits_type::eq_int_type(_M_c, __eof))
- __ret = _M_c;
-   else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()),
-  __eof))
- _M_c = __ret;
-   else
- _M_sbuf = 0;
- }
-   return __ret;
+   if (_M_sbuf && traits_type::eq_int_type(_M_c, __eof))
+  _M_c = _M_sbuf->sgetc();
+   return _M_c;
   }
 
   bool
@@ -339,7 +355,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   typedef typename __is_iterator_type::streambuf_type  streambuf_type;
   typedef typename traits_type::int_type   int_type;
 
-  if (__first._M_sbuf && !__last._M_sbuf)
+  if (__first._M_sbuf && (__last == istreambuf_iterator<_CharT>()))
{
  streambuf_type* __sb = __first._M_sbuf;
  int_type __c = __sb->sgetc();
@@ -374,7 +390,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   typedef typename __is_iterator_type::streambuf_type  streambuf_type;
   typedef typename traits_type::int_type   int_type;
 
-  if (__first._M_sbuf && !__last._M_sbuf)
+  if (__first._M_sbuf && (__last == istreambuf_iterator<_CharT>()))
{
  const int_type __ival = traits_type::to_int_type(__val);
  stre

Re: [PATCH] libstdc++: istreambuf_iterator keep attached streambuf

2017-10-03 Thread Petr Ovtchenkov
On Thu, 28 Sep 2017 13:38:06 +0100
Jonathan Wakely  wrote:

> On 28/09/17 15:06 +0300, Petr Ovtchenkov wrote:
> >On Thu, 28 Sep 2017 11:34:25 +0100
> >Jonathan Wakely  wrote:
> >
> >> On 23/09/17 09:54 +0300, Petr Ovtchenkov wrote:
> >> >istreambuf_iterator should not forget about attached
> >> >streambuf when it reach EOF.
> >> >
> >> >Checks in debug mode has no infuence more on character
> >> >extraction in istreambuf_iterator increment operators.
> >> >In this aspect behaviour in debug and non-debug mode
> >> >is similar now.
> >> >
> >> >Test for detached srteambuf in istreambuf_iterator:
> >> >When istreambuf_iterator reach EOF of istream, it should not
> >> >forget about attached streambuf.
> >> From fact "EOF in stream reached" not follow that
> >> >stream reach end of life and input operation impossible
> >> >more.
> >> >---
> >> > libstdc++-v3/include/bits/streambuf_iterator.h | 41 +++
> >> > .../24_iterators/istreambuf_iterator/3.cc  | 61 
> >> > ++
> >> > 2 files changed, 80 insertions(+), 22 deletions(-)
> >> > create mode 100644 
> >> > libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/3.cc
> >> >
> >> >diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h
> >> >b/libstdc++-v3/include/bits/streambuf_iterator.h index f0451b1..45c3d89 
> >> >100644
> >> >--- a/libstdc++-v3/include/bits/streambuf_iterator.h
> >> >+++ b/libstdc++-v3/include/bits/streambuf_iterator.h
> >> >@@ -136,12 +136,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >> >   istreambuf_iterator&
> >> >   operator++()
> >> >   {
> >> >- __glibcxx_requires_cond(!_M_at_eof(),
> >> >+ __glibcxx_requires_cond(_M_sbuf,
> >> >  _M_message(__gnu_debug::__msg_inc_istreambuf)
> >> >  ._M_iterator(*this));
> >> >  if (_M_sbuf)
> >> >{
> >> >+#ifdef _GLIBCXX_DEBUG_PEDANTIC
> >> >+ int_type _tmp =
> >> >+#endif
> >> >  _M_sbuf->sbumpc();
> >> >+#ifdef _GLIBCXX_DEBUG_PEDANTIC
> >> >+ 
> >> >__glibcxx_requires_cond(!traits_type::eq_int_type(_tmp,traits_type::eof()),
> >> >+ 
> >> >_M_message(__gnu_debug::__msg_inc_istreambuf)
> >> >+ ._M_iterator(*this));
> >> >+#endif
> >> >  _M_c = traits_type::eof();
> >> >}
> >> >  return *this;
> >> >@@ -151,14 +159,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >> >   istreambuf_iterator
> >> >   operator++(int)
> >> >   {
> >> >- __glibcxx_requires_cond(!_M_at_eof(),
> >> >+_M_get();
> >> >+ __glibcxx_requires_cond(_M_sbuf
> >> >+ && 
> >> >!traits_type::eq_int_type(_M_c,traits_type::eof()),
> >> >  _M_message(__gnu_debug::__msg_inc_istreambuf)
> >> >  ._M_iterator(*this));
> >> >
> >> >  istreambuf_iterator __old = *this;
> >> >  if (_M_sbuf)
> >> >{
> >> >- __old._M_c = _M_sbuf->sbumpc();
> >> >+ _M_sbuf->sbumpc();
> >> >  _M_c = traits_type::eof();
> >> >}
> >> >  return __old;
> >> >@@ -177,18 +187,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >> >   _M_get() const
> >> >   {
> >> >  const int_type __eof = traits_type::eof();
> >> >- int_type __ret = __eof;
> >> >- if (_M_sbuf)
> >> >-   {
> >> >- if (!traits_type::eq_int_type(_M_c, __eof))
> >> >-   __ret = _M_c;
> >> >- else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()),
> >> >-__eof))
> >> >-   _M_c = __ret;
> >> >- else
> >> >-   _M_sbuf = 0;
> >> >-   }
> >> >- return __ret;
> >> >+ if (_M_sbuf && traits_type::eq_int_type(_M_c, __eof))
> >> >+  _M_c = _M_sbuf->sgetc();
> >> >+ return _M_c;
> >> >   }
> >> >
> >> >   bool
> >> >@@ -339,7 +340,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>

Re: [PATCH] libstdc++: istreambuf_iterator keep attached streambuf

2017-09-28 Thread Petr Ovtchenkov
On Thu, 28 Sep 2017 11:34:25 +0100
Jonathan Wakely  wrote:

> On 23/09/17 09:54 +0300, Petr Ovtchenkov wrote:
> >istreambuf_iterator should not forget about attached
> >streambuf when it reach EOF.
> >
> >Checks in debug mode has no infuence more on character
> >extraction in istreambuf_iterator increment operators.
> >In this aspect behaviour in debug and non-debug mode
> >is similar now.
> >
> >Test for detached srteambuf in istreambuf_iterator:
> >When istreambuf_iterator reach EOF of istream, it should not
> >forget about attached streambuf.
> From fact "EOF in stream reached" not follow that
> >stream reach end of life and input operation impossible
> >more.
> >---
> > libstdc++-v3/include/bits/streambuf_iterator.h | 41 +++
> > .../24_iterators/istreambuf_iterator/3.cc  | 61 
> > ++
> > 2 files changed, 80 insertions(+), 22 deletions(-)
> > create mode 100644 
> > libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/3.cc
> >
> >diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h
> >b/libstdc++-v3/include/bits/streambuf_iterator.h index f0451b1..45c3d89 
> >100644
> >--- a/libstdc++-v3/include/bits/streambuf_iterator.h
> >+++ b/libstdc++-v3/include/bits/streambuf_iterator.h
> >@@ -136,12 +136,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >   istreambuf_iterator&
> >   operator++()
> >   {
> >-__glibcxx_requires_cond(!_M_at_eof(),
> >+__glibcxx_requires_cond(_M_sbuf,
> > _M_message(__gnu_debug::__msg_inc_istreambuf)
> > ._M_iterator(*this));
> > if (_M_sbuf)
> >   {
> >+#ifdef _GLIBCXX_DEBUG_PEDANTIC
> >+int_type _tmp =
> >+#endif
> > _M_sbuf->sbumpc();
> >+#ifdef _GLIBCXX_DEBUG_PEDANTIC
> >+
> >__glibcxx_requires_cond(!traits_type::eq_int_type(_tmp,traits_type::eof()),
> >+
> >_M_message(__gnu_debug::__msg_inc_istreambuf)
> >+._M_iterator(*this));
> >+#endif
> > _M_c = traits_type::eof();
> >   }
> > return *this;
> >@@ -151,14 +159,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >   istreambuf_iterator
> >   operator++(int)
> >   {
> >-__glibcxx_requires_cond(!_M_at_eof(),
> >+_M_get();
> >+__glibcxx_requires_cond(_M_sbuf
> >+&& 
> >!traits_type::eq_int_type(_M_c,traits_type::eof()),
> > _M_message(__gnu_debug::__msg_inc_istreambuf)
> > ._M_iterator(*this));
> >
> > istreambuf_iterator __old = *this;
> > if (_M_sbuf)
> >   {
> >-__old._M_c = _M_sbuf->sbumpc();
> >+_M_sbuf->sbumpc();
> > _M_c = traits_type::eof();
> >   }
> > return __old;
> >@@ -177,18 +187,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >   _M_get() const
> >   {
> > const int_type __eof = traits_type::eof();
> >-int_type __ret = __eof;
> >-if (_M_sbuf)
> >-  {
> >-if (!traits_type::eq_int_type(_M_c, __eof))
> >-  __ret = _M_c;
> >-else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()),
> >-   __eof))
> >-  _M_c = __ret;
> >-else
> >-  _M_sbuf = 0;
> >-  }
> >-return __ret;
> >+if (_M_sbuf && traits_type::eq_int_type(_M_c, __eof))
> >+  _M_c = _M_sbuf->sgetc();
> >+return _M_c;
> >   }
> >
> >   bool
> >@@ -339,7 +340,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >   typedef typename __is_iterator_type::streambuf_type  streambuf_type;
> >   typedef typename traits_type::int_type   int_type;
> >
> >-  if (__first._M_sbuf && !__last._M_sbuf)
> >+  if (__first._M_sbuf && (__last == istreambuf_iterator<_CharT>()))
> > {
> >   streambuf_type* __sb = __first._M_sbuf;
> >   int_type __c = __sb->sgetc();
> >@@ -374,7 +375,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >   typedef typename __is_iterator_type::streambuf_type  streambuf_type;
> >   typedef typename traits_type::int_type   int_type;
> >
> >-  if (__first._M_sbuf && !__last._M_sbuf)
> >+  if (__first._M_sbuf && (__last == istreambuf_iterator<_CharT>()))
> > {
> &

[PATCH] libstdc++: istreambuf_iterator keep attached streambuf

2017-09-23 Thread Petr Ovtchenkov
istreambuf_iterator should not forget about attached
streambuf when it reach EOF.

Checks in debug mode has no infuence more on character
extraction in istreambuf_iterator increment operators.
In this aspect behaviour in debug and non-debug mode
is similar now.

Test for detached srteambuf in istreambuf_iterator:
When istreambuf_iterator reach EOF of istream, it should not
forget about attached streambuf.
>From fact "EOF in stream reached" not follow that
stream reach end of life and input operation impossible
more.
---
 libstdc++-v3/include/bits/streambuf_iterator.h | 41 +++
 .../24_iterators/istreambuf_iterator/3.cc  | 61 ++
 2 files changed, 80 insertions(+), 22 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/3.cc

diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h 
b/libstdc++-v3/include/bits/streambuf_iterator.h
index f0451b1..45c3d89 100644
--- a/libstdc++-v3/include/bits/streambuf_iterator.h
+++ b/libstdc++-v3/include/bits/streambuf_iterator.h
@@ -136,12 +136,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   istreambuf_iterator&
   operator++()
   {
-   __glibcxx_requires_cond(!_M_at_eof(),
+   __glibcxx_requires_cond(_M_sbuf,
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
if (_M_sbuf)
  {
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+   int_type _tmp =
+#endif
_M_sbuf->sbumpc();
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+   
__glibcxx_requires_cond(!traits_type::eq_int_type(_tmp,traits_type::eof()),
+   
_M_message(__gnu_debug::__msg_inc_istreambuf)
+   ._M_iterator(*this));
+#endif
_M_c = traits_type::eof();
  }
return *this;
@@ -151,14 +159,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   istreambuf_iterator
   operator++(int)
   {
-   __glibcxx_requires_cond(!_M_at_eof(),
+_M_get();
+   __glibcxx_requires_cond(_M_sbuf
+   && 
!traits_type::eq_int_type(_M_c,traits_type::eof()),
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
 
istreambuf_iterator __old = *this;
if (_M_sbuf)
  {
-   __old._M_c = _M_sbuf->sbumpc();
+   _M_sbuf->sbumpc();
_M_c = traits_type::eof();
  }
return __old;
@@ -177,18 +187,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _M_get() const
   {
const int_type __eof = traits_type::eof();
-   int_type __ret = __eof;
-   if (_M_sbuf)
- {
-   if (!traits_type::eq_int_type(_M_c, __eof))
- __ret = _M_c;
-   else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()),
-  __eof))
- _M_c = __ret;
-   else
- _M_sbuf = 0;
- }
-   return __ret;
+   if (_M_sbuf && traits_type::eq_int_type(_M_c, __eof))
+  _M_c = _M_sbuf->sgetc();
+   return _M_c;
   }
 
   bool
@@ -339,7 +340,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   typedef typename __is_iterator_type::streambuf_type  streambuf_type;
   typedef typename traits_type::int_type   int_type;
 
-  if (__first._M_sbuf && !__last._M_sbuf)
+  if (__first._M_sbuf && (__last == istreambuf_iterator<_CharT>()))
{
  streambuf_type* __sb = __first._M_sbuf;
  int_type __c = __sb->sgetc();
@@ -374,7 +375,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   typedef typename __is_iterator_type::streambuf_type  streambuf_type;
   typedef typename traits_type::int_type   int_type;
 
-  if (__first._M_sbuf && !__last._M_sbuf)
+  if (__first._M_sbuf && (__last == istreambuf_iterator<_CharT>()))
{
  const int_type __ival = traits_type::to_int_type(__val);
  streambuf_type* __sb = __first._M_sbuf;
@@ -395,11 +396,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  else
__c = __sb->snextc();
}
-
- if (!traits_type::eq_int_type(__c, traits_type::eof()))
-   __first._M_c = __c;
- else
-   __first._M_sbuf = 0;
+ __first._M_c = __c;
}
   return __first;
 }
diff --git a/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/3.cc 
b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/3.cc
new file mode 100644
index 000..803ede4
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/3.cc
@@ -0,0 +1,61 @@
+// { dg-options "-std=gnu++17" }
+
+// Copyright (C) 2017 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 F

Re: [PATCH] Remove CANADIAN, that break compilation for foreign target

2017-09-20 Thread Petr Ovtchenkov
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71212

On Fri, 20 May 2016 16:10:50 +0300
Petr Ovtchenkov  wrote:

> Some old ad-hoc (adding -I/usr/include to compiler
> flags) break compilation of libstdc++ for foreign
> target architecture (due to compiler see includes
> of native).


[PATCH] Remove CANADIAN, that break compilation for foreign target

2017-09-20 Thread Petr Ovtchenkov
Some old ad-hoc (adding -I/usr/include to compiler
flags) break compilation of libstdc++ for foreign
target architecture (due to compiler see includes
of native).
---
 libstdc++-v3/acinclude.m4 |  5 -
 libstdc++-v3/configure| 22 --
 libstdc++-v3/configure.ac | 14 --
 3 files changed, 41 deletions(-)

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index e48cf96..60c93bf 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -734,11 +734,6 @@ AC_DEFUN([GLIBCXX_EXPORT_INCLUDES], [
 -I$glibcxx_builddir/include \
 -I$glibcxx_srcdir/libsupc++"
 
-  # For Canadian crosses, pick this up too.
-  if test $CANADIAN = yes; then
-GLIBCXX_INCLUDES="$GLIBCXX_INCLUDES -I\${includedir}"
-  fi
-
   # Stuff in the actual top level.  Currently only used by libsupc++ to
   # get unwind* headers from the libgcc dir.
   #TOPLEVEL_INCLUDES='-I$(toplevel_srcdir)/libgcc -I$(toplevel_srcdir)/include'
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 9bf152a..7839518 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -21762,11 +21762,6 @@ done
 # Only do link tests if native. Else, hardcode.
 if $GLIBCXX_IS_NATIVE; then
 
-  # We can do more elaborate tests that assume a working linker.
-  CANADIAN=no
-
-
-
 # Check whether --with-gnu-ld was given.
 if test "${with_gnu_ld+set}" = set; then :
   withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
@@ -28807,17 +28802,6 @@ else
   # When all of that is done, all of this hokey, excessive AC_DEFINE junk for
   # crosses can be removed.
 
-  # If Canadian cross, then don't pick up tools from the build directory.
-  # Used only in GLIBCXX_EXPORT_INCLUDES.
-  if test -n "$with_cross_host" &&
- test x"$build_alias" != x"$with_cross_host" &&
- test x"$build" != x"$target";
-  then
-CANADIAN=yes
-  else
-CANADIAN=no
-  fi
-
   # Construct crosses by hand, eliminating bits that need ld...
   # GLIBCXX_CHECK_MATH_SUPPORT
 
@@ -81041,7 +81025,6 @@ CPU_OPT_BITS_RANDOM=config/${cpu_opt_bits_random}
 
 # Determine cross-compile flags and AM_CONDITIONALs.
 #AC_SUBST(GLIBCXX_IS_NATIVE)
-#AM_CONDITIONAL(CANADIAN, test $CANADIAN = yes)
 if test $is_hosted = yes; then
   GLIBCXX_HOSTED_TRUE=
   GLIBCXX_HOSTED_FALSE='#'
@@ -81423,11 +81406,6 @@ $as_echo "$gxx_include_dir" >&6; }
 -I$glibcxx_builddir/include \
 -I$glibcxx_srcdir/libsupc++"
 
-  # For Canadian crosses, pick this up too.
-  if test $CANADIAN = yes; then
-GLIBCXX_INCLUDES="$GLIBCXX_INCLUDES -I\${includedir}"
-  fi
-
   # Stuff in the actual top level.  Currently only used by libsupc++ to
   # get unwind* headers from the libgcc dir.
   #TOPLEVEL_INCLUDES='-I$(toplevel_srcdir)/libgcc -I$(toplevel_srcdir)/include'
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 9e19e99..3a8e26d 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -243,8 +243,6 @@ wchar.h wctype.h])
 if $GLIBCXX_IS_NATIVE; then
 
   # We can do more elaborate tests that assume a working linker.
-  CANADIAN=no
-
   GLIBCXX_CHECK_LINKER_FEATURES
   GLIBCXX_CHECK_MATH_SUPPORT
   GLIBCXX_CHECK_STDLIB_SUPPORT
@@ -276,17 +274,6 @@ else
   # When all of that is done, all of this hokey, excessive AC_DEFINE junk for
   # crosses can be removed.
 
-  # If Canadian cross, then don't pick up tools from the build directory.
-  # Used only in GLIBCXX_EXPORT_INCLUDES.
-  if test -n "$with_cross_host" &&
- test x"$build_alias" != x"$with_cross_host" &&
- test x"$build" != x"$target";
-  then
-CANADIAN=yes
-  else
-CANADIAN=no
-  fi
-
   # Construct crosses by hand, eliminating bits that need ld...
   # GLIBCXX_CHECK_MATH_SUPPORT
 
@@ -480,7 +467,6 @@ AC_SUBST(CPU_OPT_BITS_RANDOM)
 
 # Determine cross-compile flags and AM_CONDITIONALs.
 #AC_SUBST(GLIBCXX_IS_NATIVE)
-#AM_CONDITIONAL(CANADIAN, test $CANADIAN = yes)
 GLIBCXX_EVALUATE_CONDITIONALS
 
 AC_CACHE_SAVE
-- 
2.10.1



Re: [PATCH] streambuf_iterator: avoid debug-dependent behaviour

2017-09-07 Thread Petr Ovtchenkov
-gcc-patches 

On Thu, 7 Sep 2017 23:02:15 +0200
François Dumont  wrote:

> + _M_c = _M_sbuf->sgetc();
> + if (_S_at_eof(_M_c))
> +   _M_sbuf = 0;

_M_sbuf = 0; <--- Is not what I axpect here.

Suggestions will be later, after we finish copyright assignment for
changes procedure (in progress).

WBR,

--

   - ptr


[PATCH] libstdc++: test for copy_n/istreambuf_iterator

2017-08-25 Thread Petr Ovtchenkov
copy_n return result + n (i.e. increment OutputIterator n times) and
increment InputIterator max(0, n - 1).

This is issue 81857.

See also https://cplusplus.github.io/LWG/issue2471
---
 .../testsuite/25_algorithms/copy_n/81857.cc| 83 ++
 1 file changed, 83 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/25_algorithms/copy_n/81857.cc

diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_n/81857.cc 
b/libstdc++-v3/testsuite/25_algorithms/copy_n/81857.cc
new file mode 100644
index 000..adb6c35
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/copy_n/81857.cc
@@ -0,0 +1,83 @@
+// { dg-options "-std=gnu++11" }
+
+// Copyright (C) 2017 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 
+#include 
+
+// libstdc++/81857
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+
+  std::stringstream s;
+  char b[] = "c2ee3d09-43b3-466d-b490-db35999a22cf";
+  char r[] = "";
+  //  012345678901234567890123456789012345
+  //  0 1 2 3
+  s << b;
+  VERIFY( !s.fail() );
+
+  VERIFY( s.tellg() == 0 );
+  /*
+https://cplusplus.github.io/LWG/issue2471
+
+It's unspecified how many times copy_n increments the InputIterator.
+uninitialized_copy_n is specified to increment it exactly n times,
+which means if an istream_iterator is used then the next character
+after those copied is read from the stream and then discarded, losing data.
+
+I believe all three of Dinkumware, libc++ and libstdc++ implement copy_n
+with n - 1 increments of the InputIterator, which avoids reading and
+discarding a character when used with istream_iterator, but is inconsistent
+with uninitialized_copy_n and causes surprising behaviour with
+istreambuf_iterator instead, because copy_n(in, 2, copy_n(in, 2, out))
+is not equivalent to copy_n(in, 4, out)
+   */
+
+  /*
+copy_n return result + n (i.e. increment OutputIterator n times) and
+increment InputIterator max(0, n - 1).
+   */
+  std::copy_n( std::istreambuf_iterator(s), 36, r );
+  VERIFY( !s.fail() );
+  VERIFY( memcmp(b, r, 36) == 0 );
+
+  char c = 'q';
+  std::copy_n( std::istreambuf_iterator(s), 1, &c );
+  VERIFY( std::istreambuf_iterator(s) != 
std::istreambuf_iterator() ); // see comment above
+  VERIFY( !s.fail() ); // surprise, see comment above
+  VERIFY( c != 'q' );
+  VERIFY( c == 'f' ); // surprise, see comment above
+
+  // Suggested workaround technique:
+  std::istreambuf_iterator iis(s);
+  ++iis; // <---
+  std::copy_n( iis, 1, &c );
+  // VERIFY( s.fail() ); // ?!
+  VERIFY( iis == std::istreambuf_iterator() );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
-- 
2.10.1



Re: [PATCH] istream_iterator: unexpected read in ctor

2017-08-24 Thread Petr Ovtchenkov
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81964

On Thu, 24 Aug 2017 11:55:58 +0300
Petr Ovtchenkov  wrote:

> istream_iterator do unexpected read from stream
> when initialized by istream&.
> 
> It is not required from increment operators of istream_iterator
> that _M_ok will be true as precondition.
> ---
>  libstdc++-v3/include/bits/stream_iterator.h| 19 +-
>  .../24_iterators/istream_iterator/81964.cc | 42 
> ++
>  2 files changed, 50 insertions(+), 11 deletions(-)
>  create mode 100644 
> libstdc++-v3/testsuite/24_iterators/istream_iterator/81964.cc
> 
> diff --git a/libstdc++-v3/include/bits/stream_iterator.h
> b/libstdc++-v3/include/bits/stream_iterator.h index f9c6ba6..26959ce 100644
> --- a/libstdc++-v3/include/bits/stream_iterator.h
> +++ b/libstdc++-v3/include/bits/stream_iterator.h
> @@ -56,8 +56,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  
>  private:
>istream_type*  _M_stream;
> -  _Tp_M_value;
> -  bool   _M_ok;
> +  mutable _Tp_M_value;
> +  mutable bool   _M_ok;
>  
>  public:
>///  Construct end of input stream iterator.
> @@ -66,8 +66,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  
>///  Construct start of input stream iterator.
>istream_iterator(istream_type& __s)
> -  : _M_stream(&__s)
> -  { _M_read(); }
> +  : _M_stream(&__s), _M_value(), _M_ok(false)
> +  { }
>  
>istream_iterator(const istream_iterator& __obj)
>: _M_stream(__obj._M_stream), _M_value(__obj._M_value),
> @@ -77,6 +77,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>const _Tp&
>operator*() const
>{
> + if (!_M_ok) {
> +   _M_read();
> + }
>   __glibcxx_requires_cond(_M_ok,
>   _M_message(__gnu_debug::__msg_deref_istream)
>   ._M_iterator(*this));
> @@ -89,9 +92,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>istream_iterator&
>operator++()
>{
> - __glibcxx_requires_cond(_M_ok,
> - _M_message(__gnu_debug::__msg_inc_istream)
> - ._M_iterator(*this));
>   _M_read();
>   return *this;
>}
> @@ -99,9 +99,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>istream_iterator
>operator++(int)
>{
> - __glibcxx_requires_cond(_M_ok,
> - _M_message(__gnu_debug::__msg_inc_istream)
> - ._M_iterator(*this));
>   istream_iterator __tmp = *this;
>   _M_read();
>   return __tmp;
> @@ -113,7 +110,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  
>  private:
>void
> -  _M_read()
> +  _M_read() const
>{
>   _M_ok = (_M_stream && *_M_stream) ? true : false;
>   if (_M_ok)
> diff --git a/libstdc++-v3/testsuite/24_iterators/istream_iterator/81964.cc
> b/libstdc++-v3/testsuite/24_iterators/istream_iterator/81964.cc new file mode 
> 100644
> index 000..f58fc87
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/24_iterators/istream_iterator/81964.cc
> @@ -0,0 +1,42 @@
> +// { dg-options "-std=gnu++11" }
> +
> +// Copyright (C) 2017 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 
> +#include 
> +#include 
> +
> +// libstdc++/81964
> +void test0x()
> +{
> +  using namespace std;
> +  bool test __attribute__((unused)) = true;
> +
> +  std::istringstream s("1 2");
> +  std::istream_iterator ii1(s);
> +  std::istream_iterator ii2(s);
> +
> +  VERIFY( *ii2 == 1 );
> +  VERIFY( *ii1 == 2 );
> +}
> +
> +int main()
> +{
> +  test0x();
> +  return 0;
> +}
> -- 
> 2.10.1
> 


[PATCH] streambuf_iterator: avoid debug-dependent behaviour

2017-08-24 Thread Petr Ovtchenkov
Explicit do sgetc from associated streambuf. Avoid debug-dependent
sgetc (within _M_at_eof()):

   __glibcxx_requires_cond(!_M_at_eof(),
   _M_message(__gnu_debug::__msg_inc_istreambuf)
   ._M_iterator(*this));

Increment operators not require not-eof precoditions.

Don't unlink associated streambuf if eof detected (in _M_get).

Clean logic in postfix increment operator.
---
 libstdc++-v3/include/bits/streambuf_iterator.h | 24 +---
 1 file changed, 5 insertions(+), 19 deletions(-)

diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h 
b/libstdc++-v3/include/bits/streambuf_iterator.h
index 2230e94..cff3b69 100644
--- a/libstdc++-v3/include/bits/streambuf_iterator.h
+++ b/libstdc++-v3/include/bits/streambuf_iterator.h
@@ -136,9 +136,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   istreambuf_iterator&
   operator++()
   {
-   __glibcxx_requires_cond(!_M_at_eof(),
-   _M_message(__gnu_debug::__msg_inc_istreambuf)
-   ._M_iterator(*this));
if (_M_sbuf)
  {
_M_sbuf->sbumpc();
@@ -151,14 +148,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   istreambuf_iterator
   operator++(int)
   {
-   __glibcxx_requires_cond(!_M_at_eof(),
-   _M_message(__gnu_debug::__msg_inc_istreambuf)
-   ._M_iterator(*this));
+_M_get();
 
istreambuf_iterator __old = *this;
if (_M_sbuf)
  {
-   __old._M_c = _M_sbuf->sbumpc();
+   _M_sbuf->sbumpc();
_M_c = traits_type::eof();
  }
return __old;
@@ -177,18 +172,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _M_get() const
   {
const int_type __eof = traits_type::eof();
-   int_type __ret = __eof;
-   if (_M_sbuf)
- {
-   if (!traits_type::eq_int_type(_M_c, __eof))
- __ret = _M_c;
-   else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()),
-  __eof))
- _M_c = __ret;
-   else
- _M_sbuf = 0;
- }
-   return __ret;
+   if (_M_sbuf && traits_type::eq_int_type(_M_c, __eof))
+  _M_c = _M_sbuf->sgetc();
+   return _M_c;
   }
 
   bool
-- 
2.10.1



[PATCH] istream_iterator: unexpected read in ctor

2017-08-24 Thread Petr Ovtchenkov
istream_iterator do unexpected read from stream
when initialized by istream&.

It is not required from increment operators of istream_iterator
that _M_ok will be true as precondition.
---
 libstdc++-v3/include/bits/stream_iterator.h| 19 +-
 .../24_iterators/istream_iterator/81964.cc | 42 ++
 2 files changed, 50 insertions(+), 11 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/24_iterators/istream_iterator/81964.cc

diff --git a/libstdc++-v3/include/bits/stream_iterator.h 
b/libstdc++-v3/include/bits/stream_iterator.h
index f9c6ba6..26959ce 100644
--- a/libstdc++-v3/include/bits/stream_iterator.h
+++ b/libstdc++-v3/include/bits/stream_iterator.h
@@ -56,8 +56,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 private:
   istream_type*_M_stream;
-  _Tp  _M_value;
-  bool _M_ok;
+  mutable _Tp  _M_value;
+  mutable bool _M_ok;
 
 public:
   ///  Construct end of input stream iterator.
@@ -66,8 +66,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   ///  Construct start of input stream iterator.
   istream_iterator(istream_type& __s)
-  : _M_stream(&__s)
-  { _M_read(); }
+  : _M_stream(&__s), _M_value(), _M_ok(false)
+  { }
 
   istream_iterator(const istream_iterator& __obj)
   : _M_stream(__obj._M_stream), _M_value(__obj._M_value),
@@ -77,6 +77,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const _Tp&
   operator*() const
   {
+   if (!_M_ok) {
+ _M_read();
+   }
__glibcxx_requires_cond(_M_ok,
_M_message(__gnu_debug::__msg_deref_istream)
._M_iterator(*this));
@@ -89,9 +92,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   istream_iterator&
   operator++()
   {
-   __glibcxx_requires_cond(_M_ok,
-   _M_message(__gnu_debug::__msg_inc_istream)
-   ._M_iterator(*this));
_M_read();
return *this;
   }
@@ -99,9 +99,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   istream_iterator
   operator++(int)
   {
-   __glibcxx_requires_cond(_M_ok,
-   _M_message(__gnu_debug::__msg_inc_istream)
-   ._M_iterator(*this));
istream_iterator __tmp = *this;
_M_read();
return __tmp;
@@ -113,7 +110,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 private:
   void
-  _M_read()
+  _M_read() const
   {
_M_ok = (_M_stream && *_M_stream) ? true : false;
if (_M_ok)
diff --git a/libstdc++-v3/testsuite/24_iterators/istream_iterator/81964.cc 
b/libstdc++-v3/testsuite/24_iterators/istream_iterator/81964.cc
new file mode 100644
index 000..f58fc87
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/istream_iterator/81964.cc
@@ -0,0 +1,42 @@
+// { dg-options "-std=gnu++11" }
+
+// Copyright (C) 2017 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 
+
+// libstdc++/81964
+void test0x()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+
+  std::istringstream s("1 2");
+  std::istream_iterator ii1(s);
+  std::istream_iterator ii2(s);
+
+  VERIFY( *ii2 == 1 );
+  VERIFY( *ii1 == 2 );
+}
+
+int main()
+{
+  test0x();
+  return 0;
+}
-- 
2.10.1



[PATCH] copy_n for input iterator, avoid in-loop jumps

2017-08-24 Thread Petr Ovtchenkov
Reword loop in copy_n specialization for input iterator.
Avoid condition check and jumps within loop.
Pay attention that input iterator incremented n - 1 times,
while output iterator incremented n times.

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50119 and
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81857
---
 libstdc++-v3/include/bits/stl_algo.h | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_algo.h 
b/libstdc++-v3/include/bits/stl_algo.h
index c2ac031..bf043cd 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -757,17 +757,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _OutputIterator __result, input_iterator_tag)
 {
   if (__n > 0)
-   {
- while (true)
-   {
- *__result = *__first;
- ++__result;
- if (--__n > 0)
-   ++__first;
- else
-   break;
-   }
-   }
+{
+  *__result = *__first;
+  ++__result;
+  --__n;
+}
+  for (; __n > 0; --__n)
+{
+  ++__first;
+  *__result = *__first;
+  ++__result;
+}
   return __result;
 }
 
-- 
2.10.1