Bug 10093 - [3.3/3.4 Regression] [L DR 61] Setting failbit in exceptions doesn't work
Summary: [3.3/3.4 Regression] [L DR 61] Setting failbit in exceptions doesn't work
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 3.3
: P3 critical
Target Milestone: 3.3.3
Assignee: Benjamin Kosnik
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-03-15 10:36 UTC by Pétur Runólfsson
Modified: 2004-01-17 04:22 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
exceptionsbug2.cc (188 bytes, text/plain)
2003-05-21 15:17 UTC, Pétur Runólfsson
Details
2003 10 25 work in progress (7.80 KB, patch)
2003-10-26 03:11 UTC, Benjamin Kosnik
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Pétur Runólfsson 2003-03-15 10:36:01 UTC
Setting ios_base::failbit in basic_ios::exceptions does not cause basic_istream::operator>>(int&) to throw an exception.

This appears to have been caused by the recent patch for PR libstdc++/9561.

Release:
gcc version 3.3 20030310 (prerelease)

Environment:
Red Hat Linux 8.0

How-To-Repeat:
See attachment.
Comment 1 Paolo Carlini 2003-03-22 15:22:25 UTC
Responsible-Changed-From-To: unassigned->jlquinn
Responsible-Changed-Why: Jerry, can you please have a look? According to Pétur, the
    problem may have to do with your fix for 9561.
    Thanks, Paolo.
Comment 2 Paolo Carlini 2003-03-22 15:22:25 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Confirmed.
Comment 3 Jerry Quinn 2003-03-23 01:50:11 UTC
From: Jerry Quinn <jlquinn@optonline.net>
To: gcc-gnats@gcc.gnu.org, peturr02@ru.is, gcc-bugs@gcc.gnu.org,
 gcc-prs@gcc.gnu.org, libstdc++@gcc.gnu.org
Cc:  
Subject: Re: libstdc++/10093: Regression: Setting failbit in exceptions doesn't
 work
Date: Sun, 23 Mar 2003 01:50:11 -0500

 I'm a bit confused by this bug.  What should the behavior be here?  To my
 simple reading of the standard, it seems that the code is operating correctly.
 
 The test case is designed to throw if failbit is set.  Failbit does get set,
 which causes the exception to be thrown.  However, it is caught in the
 exception handler and not rethrown.
 
 27.6.1.2.1 says that the exception is rethrown if badbit is set in the
 exception mask (and badbit is set), otherwise not.  This makes it sound like
 the _only_ way to get an exception from the formatted input functions is to
 set badbit in the exception mask.
 
 Petur, can you explain what I'm missing?
 
 Thanks
 Jerry Quinn

Comment 4 Martin Sebor 2003-03-23 13:18:57 UTC
From: Martin Sebor <sebor@roguewave.com>
To: gcc-gnats@gcc.gnu.org
Cc:  
Subject: Re: libstdc++/10093: Regression: Setting failbit in exceptions doesn't
 work
Date: Sun, 23 Mar 2003 13:18:57 -0700

 Pétur Runólfsson wrote:
 ...
 > 
 > Note the "during input". I read that as meaning that this refers only
 > to exceptions thrown by the call to num_get::get(), not to exceptions
 > thrown from other functions the extractors may call.
 
 The general requirements on what causes exceptions to be caught
 and rethrown are buried in 27.6.1.1, p1-4. According to the text
 only calls to members of streambuf are supposed to be checked
 for exceptions. But because it's not possible to distinguish
 between an exception thrown by, say, a (virtual) member function
 of ctype called from num_get::get() and one thrown by a (virtual)
 streambuf member called (indirectly, via an istreambuf_iterator
 member) from num_get::get(), the requirement cannot realistically
 be taken to mean just exceptions thrown during a call to num_get
 ::get() and not, for instance, ctype::is() called by the istream
 ::sentry ctor. IMO, stream members should consistently catch all
 exceptions from any functions they may call.
 
 > 
 ...
 > The whole text about the meaning of exceptions() and the handling of
 > exceptions thrown during calls to I/O functions seems rather messy.
 > Perhaps someone more familiar with the standard cares to comment?
 
 I agree that error handling in iostreams (and locale) in general
 and exception handling in particular is less than perfect. I have
 filed a number of issues(*) in an attempt to clean up this area
 but I have a feeling there is more work to be done.
 
 (*) A number of them aren't listed yet (they should be in Revision
 25 of the issues list), but this one is
 
 http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#309
 
 Regards
 Martin
 

Comment 5 Pétur Runólfsson 2003-03-23 19:13:24 UTC
From: =?iso-8859-1?Q?P=E9tur_Run=F3lfsson?= <peturr02@ru.is>
To: "Jerry Quinn" <jlquinn@optonline.net>,
	<gcc-gnats@gcc.gnu.org>,
	<gcc-bugs@gcc.gnu.org>,
	<gcc-prs@gcc.gnu.org>,
	<libstdc++@gcc.gnu.org>
Cc:  
Subject: RE: libstdc++/10093: Regression: Setting failbit in exceptions doesn't work
Date: Sun, 23 Mar 2003 19:13:24 -0000

 Jerry Quinn wrote:
 > I'm a bit confused by this bug.  What should the behavior be=20
 > here?  To my
 > simple reading of the standard, it seems that the code is=20
 > operating correctly.
 >=20
 > The test case is designed to throw if failbit is set. =20
 > Failbit does get set,
 > which causes the exception to be thrown.  However, it is caught in the
 > exception handler and not rethrown.
 >=20
 > 27.6.1.2.1 says that the exception is rethrown if badbit is set in the
 > exception mask (and badbit is set), otherwise not.  This=20
 > makes it sound like
 > the _only_ way to get an exception from the formatted input=20
 > functions is to
 > set badbit in the exception mask.
 
 This is the relevant quote:
 
   27.6.1.2.1 - Common requirements [lib.istream.formatted.reqmts]
   -1- [...] If an exception is thrown *during input* then ios::badbit is
   turned on in *this's error state.=20
 
   If (exception() & badbit) !=3D 0 then the exception is rethrown. In =
 any
   case, the formatted input function destroys the sentry object. If no
   exception has been thrown, it returns *this.
 
 Note the "during input". I read that as meaning that this refers only
 to exceptions thrown by the call to num_get::get(), not to exceptions
 thrown from other functions the extractors may call.
 
 IMHO the resolution to DR 64 is in support of this reading, as well as
 the description of badbit in 27.4.2.1.3.
 
 Also, the function exceptions(iostate) is rather silly if only badbit
 is supposed to cause exceptions to be thrown.
 
 The whole text about the meaning of exceptions() and the handling of
 exceptions thrown during calls to I/O functions seems rather messy.
 Perhaps someone more familiar with the standard cares to comment?
 
 Petur

Comment 6 Pétur Runólfsson 2003-03-24 10:46:51 UTC
From: =?iso-8859-1?Q?P=E9tur_Run=F3lfsson?= <peturr02@ru.is>
To: <jlquinn@optonline.net>,
	"Martin Sebor" <sebor@roguewave.com>
Cc: <gcc-gnats@gcc.gnu.org>,
	<libstdc++@gcc.gnu.org>
Subject: RE: libstdc++/10093: Regression: Setting failbit in exceptions doesn't work
Date: Mon, 24 Mar 2003 10:46:51 -0000

 Jerry Quinn wrote:
 > Martin Sebor writes:
 >  >  P=E9tur Run=F3lfsson wrote:
 >  >  ...
 >  >  >=20
 >  >  > Note the "during input". I read that as meaning that=20
 > this refers only
 >  >  > to exceptions thrown by the call to num_get::get(), not=20
 > to exceptions
 >  >  > thrown from other functions the extractors may call.
 >  > =20
 >  >  The general requirements on what causes exceptions to be caught
 >  >  and rethrown are buried in 27.6.1.1, p1-4. According to the text
 >  >  only calls to members of streambuf are supposed to be checked
 >  >  for exceptions.
 
 Do you mean that "these called functions" in p4 only refers to
 rdbuf()->sbumpc() and rdbuf()->sgetc() and not setstate()?
 
 The part "as if the called function had returned a failure
 indication" implies that setstate is not included (after all, it
 doesn't return failure indications), but the part "If badbit is
 on in exceptions(), [...], otherwise it does not throw anything"
 implies that s >> x will only throw if
 (s.exceptions() & ios::badbit) !=3D 0, so setstate should be
 included (but this contradicts the resolution to DR 64).
 
 >  >  But because it's not possible to distinguish
 >  >  between an exception thrown by, say, a (virtual) member function
 >  >  of ctype called from num_get::get() and one thrown by a (virtual)
 >  >  streambuf member called (indirectly, via an istreambuf_iterator
 >  >  member) from num_get::get(), the requirement cannot realistically
 >  >  be taken to mean just exceptions thrown during a call to num_get
 >  >  ::get() and not, for instance, ctype::is() called by the istream
 >  >  ::sentry ctor.
 
 I agree. It seems reasonable to set badbit if say,
 use_facet<ctype<CharT> >(getloc()) fails (since this makes the stream
 unreadable, i.e. bad), but neither 27.6.1.1 nor 27.6.1.2.1 says
 anything about this one way or the other if we take "these called
 functions" and "during input" to mean only rdbuf->sbumpc() and
 rdbuf()->sgetc().
 
 >  >  IMO, stream members should consistently catch all
 >  >  exceptions from any functions they may call.
 > I buy this :-)
 
 I agree, however I also think that exceptions() should be consistent
 with itself, that is, setting exceptions(foobit) should simply mean
 that whenever foobit is set in rdstate(), an exception is thrown.
 In the current implementation (and to some extent, the standard)
 the effect of exceptions(foobit) differs between the various I/O
 functions and depends on the value of foobit.
 
 > Given that we catch all the exceptions,
 
 IMHO this is never stated unambiguously in the standard.
 
 > when do we
 > rethrow?  The original text says rethrow if badbit is set in the
 > exception mask.  DR64 says to rethrow if failbit is set and the
 > exception mask has failbit set.  So, does it make sense to change
 
 No. DR 64 only refers to
 basic_istream<C, T>::operator>>(basic_streambuf<C, T>* sb). It only
 states that if operations on sb [1] throw then failbit should be set
 in rdstate(), and if (exceptions() & failbit) !=3D 0, the exception is
 rethrown. It does not override the requirements on formatted input
 functions, so exceptions thrown by operations on rdbuf() should
 cause badbit to be set, and only be rethrown if
 (exceptions() & badbit) !=3D 0. The reason I brought up this DR is
 that the resolution states that exceptions thrown by
 setstate(failbit) should not be caught.
 
 Petur
 
 [1] Actually, the resolution talks about exceptions thrown "while
 extracting characters from sb" which seems rather silly as the
 function extracts characters from rdbuf() and inserts them into
 sb.

Comment 7 Pétur Runólfsson 2003-03-24 18:21:12 UTC
From: =?iso-8859-1?Q?P=E9tur_Run=F3lfsson?= <peturr02@ru.is>
To: <jlquinn@optonline.net>,
	"Martin Sebor" <sebor@roguewave.com>
Cc: <gcc-gnats@gcc.gnu.org>,
	<libstdc++@gcc.gnu.org>
Subject: RE: libstdc++/10093: Regression: Setting failbit in exceptions doesn't work
Date: Mon, 24 Mar 2003 18:21:12 -0000

 I wrote:
 > I agree, however I also think that exceptions() should be consistent
 > with itself, that is, setting exceptions(foobit) should simply mean
 > that whenever foobit is set in rdstate(), an exception is thrown.
 > In the current implementation (and to some extent, the standard)
 > the effect of exceptions(foobit) differs between the various I/O
 > functions and depends on the value of foobit.
 
 Just to clarify:
 
 What I think that ios::exceptions() means (and what appears to have
 been the intent, judging by some old USENET posts) is that this
 should always work:
 
 istream is(...);
 is.exceptions(...);
 ...
 
 try
 {
   is >> x;
   assert((is.exceptions() & is.rdstate()) =3D=3D 0);
 }
 catch (...)
 {
   assert((is.exceptions() & is.rdstate()) !=3D 0);
 }
 
 Likewise for ostream and for unformatted I/O functions. Also, the
 value of is.rdstate() at the end of this code should not depend on
 the value of is.exceptions().
 
 Regards,
 Petur

Comment 8 Martin Sebor 2003-03-25 19:29:23 UTC
From: Martin Sebor <sebor@roguewave.com>
To: gcc-gnats@gcc.gnu.org
Cc:  
Subject: Re: libstdc++/10093: Regression: Setting failbit in exceptions doesn't
 work
Date: Tue, 25 Mar 2003 19:29:23 -0700

 Pétur Runólfsson wrote:
  >
 ...
 > Do you mean that "these called functions" in p4 only refers to
 > rdbuf()->sbumpc() and rdbuf()->sgetc() and not setstate()?
 
 Yes, that's how I read it.
 
 > 
 > The part "as if the called function had returned a failure
 > indication" implies that setstate is not included (after all, it
 > doesn't return failure indications), but the part "If badbit is
 > on in exceptions(), [...], otherwise it does not throw anything"
 > implies that s >> x will only throw if
 > (s.exceptions() & ios::badbit) != 0, so setstate should be
 > included (but this contradicts the resolution to DR 64).
 
 I'm not sure I follow you here. Are you concerned that the text
 contradicts itself in that if badbit is not set in exceptions
 but failbit is, calling setstate (failbit) is not allowed to
 throw failure? I don't think that is the intent of the text.
 
 > 
 ...
 >> >  IMO, stream members should consistently catch all
 >> >  exceptions from any functions they may call.
 >>I buy this :-)
 > 
 > 
 > I agree, however I also think that exceptions() should be consistent
 > with itself, that is, setting exceptions(foobit) should simply mean
 > that whenever foobit is set in rdstate(), an exception is thrown.
 
 I agree.
 
 > In the current implementation (and to some extent, the standard)
 > the effect of exceptions(foobit) differs between the various I/O
 > functions and depends on the value of foobit.
 
 I'm not too familiar with the libstdc++ implementation so I can't
 speak for it but I can't think of any place in the standard that
 mandates or allows this behavior. Do you have an example?
 
 > 
 ...
 > [1] Actually, the resolution talks about exceptions thrown "while
 > extracting characters from sb" which seems rather silly as the
 > function extracts characters from rdbuf() and inserts them into
 > sb.
 
 That looks like a typo in the resolution. I would expect the
 function to behave as if the text read:
 
      If the function inserts no characters, it calls setstate
      (failbit), which may throw ios_base::failure (27.4.4.3).
      If the function caught an exception thrown while inserting
      characters into *sb then if failbit is on in exceptions()
      (27.4.4.3), failbit is set in *this without throwing
      ios_base::failure and the caught exception is rethrown;
      otherwise the function calls setstate(failbit), which may
      throw ios_base::failure (27.4.4.3).
 
 Martin
Comment 9 Pétur Runólfsson 2003-07-01 10:08:27 UTC
Martin Sebor wrote:
> I'm not sure I follow you here. Are you concerned that the text
> contradicts itself in that if badbit is not set in exceptions
> but failbit is, calling setstate (failbit) is not allowed to
> throw failure? I don't think that is the intent of the text.

I don't think there is any doubt that setstate(failbit) should throw if
failbit is set in exceptions(), the question is whether the (un)formatted
input/output functions should catch those exceptions. Some parts of the
standard imply that the exceptions should be caught, some imply that they
should not be caught.
 
>> In the current implementation (and to some extent, the standard)
>> the effect of exceptions(foobit) differs between the various I/O
>> functions and depends on the value of foobit.
> 
> I'm not too familiar with the libstdc++ implementation so I can't
> speak for it but I can't think of any place in the standard that
> mandates or allows this behavior. Do you have an example?

basic_istream<charT,traits>& get(basic_streambuf<char_type,traits>& sb,
                  char_type delim );

Notice bullet 4:
  an exception occurs (in which case, the exception is caught but not rethrown).
I read this to mean that exceptions thrown by either operations on sb or on
rdbuf() should not propagate from this function, even if badbit is set in
exceptions(). This is inconsistent with the rest of the (un)formatted
input/output functions. This function also differs from
operator>>(basic_streambuf* sb) which rethrows exceptions from sb if failbit is
on in exceptions().
 
> That looks like a typo in the resolution. I would expect the
> function to behave as if the text read
[...]

Yes, that makes sense. 

Petur
Comment 10 Martin Sebor 2003-07-02 01:02:44 UTC
Subject: Re:  Regression: Setting failbit in exceptions
 doesn't work

peturr02 at ru dot is wrote:

...
> I don't think there is any doubt that setstate(failbit) should throw if
> failbit is set in exceptions(), the question is whether the (un)formatted
> input/output functions should catch those exceptions. Some parts of the
> standard imply that the exceptions should be caught, some imply that they
> should not be caught.

My feeling is that if setstate() should end up throwing an exception
some exception should always propagate out of the calling function.

>  
...
> basic_istream<charT,traits>& get(basic_streambuf<char_type,traits>& sb,
>                   char_type delim );
> 
> Notice bullet 4:
>   an exception occurs (in which case, the exception is caught but not rethrown).
> I read this to mean that exceptions thrown by either operations on sb or on
> rdbuf() should not propagate from this function, even if badbit is set in
> exceptions().

I don't think that's the intended interpretation but I agree that
it's a possible one. I would like to believe that the intent here
was only to swallow exceptions thrown from calls on sb (although
I don't like that either).

> This is inconsistent with the rest of the (un)formatted
> input/output functions. This function also differs from
> operator>>(basic_streambuf* sb) which rethrows exceptions from sb if failbit is
> on in exceptions().

Right. I don't think swallowing the exception is correct. IMO,
if exceptions are on, the function should rethrow the exception
no matter where it comes from. The reason for exceptions in
iostreams being optional is to provide backward compatibility
with classic iostreams. Once they're on there's no reason to
swallow them.

The more interesting question, IMO, is what bit to set if one
of the virtual calls on sb throws an exception. Should badbit
be set? I would be inclined to say no since the purpose of the
bit is to indicate some unrecoverable error in the stream
object's streambuf, but not necessarily such an error in the
argument. The stream itself might be perfectly fine after the
exception. My approach would be to set failbit in this case
(which is what our implementation does). If failbit is also
set in exceptions, the original exception is rethrown. This
is done without causing badbit to be set.

Martin


Comment 11 Pétur Runólfsson 2003-07-24 15:47:19 UTC
Martin Sebor wrote:
> My feeling is that if setstate() should end up throwing an exception
> some exception should always propagate out of the calling function.

I would like to agree, but the current proposed resolution and rationale
for DR 309 says otherwise:

  The LWG feels that no clarification of EH policy is necessary: the
  standard is precise about which operations sentry's constructor
  performs, and about which of those operations can throw.

In other words, the description of the sentry constructor has been
declared to be *clear* and *precise*. Since the description is
precise, and it does not say that the sentry::sentry() catches
exceptions, I assume this means that it should not catch any
exceptions.

The problem is that sentry::sentry() performs input (calls
rdbuf()->sgetc() and/or rdbuf()->sbumpc()) and operator>> is
supposed to catch those exceptions - which means it must catch all
exceptions thrown by sentry::sentry(), including those thrown by
setstate(). I don't think it would make sense to treat exceptions
thrown by setstate() differently based on whether setstate() was
called directly by operator>> or indirectly through sentry::sentry(),
so operator>> should catch exceptions thrown from setstate().

However, if this is the intended meaning, then we have a potential
DR: The description of badbit in 27.4.2.1.3 is incomplete and the
words "or (exceptions() & failbit) != 0" need to be added.

Petur
Comment 12 Martin Sebor 2003-07-24 17:08:05 UTC
Subject: Re:  Regression: Setting failbit in exceptions
 doesn't work

peturr02 at ru dot is wrote:

> ------- Additional Comments From peturr02 at ru dot is  2003-07-24 15:47 -------
> Martin Sebor wrote:
> 
>>My feeling is that if setstate() should end up throwing an exception
>>some exception should always propagate out of the calling function.
> 
> 
> I would like to agree, but the current proposed resolution and rationale
> for DR 309 says otherwise:
> 
>   The LWG feels that no clarification of EH policy is necessary: the
>   standard is precise about which operations sentry's constructor
>   performs, and about which of those operations can throw.

What DR is this again? I don't see this in the still open
issue 309:

http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#309

> 
> In other words, the description of the sentry constructor has been
> declared to be *clear* and *precise*. Since the description is
> precise, and it does not say that the sentry::sentry() catches
> exceptions, I assume this means that it should not catch any
> exceptions.

309 proposes that the sentry ctor set badbit if it catches
an exception during input, and that the caught exception be
rethrown when (badbit & exceptions()) is non-zero.

> 
> The problem is that sentry::sentry() performs input (calls
> rdbuf()->sgetc() and/or rdbuf()->sbumpc()) and operator>> is
> supposed to catch those exceptions

That's not my understanding. Here's how I would implement
operator>>() (which is also what our library does, even
though the code might look different):

     operator>>(int &x)
     {
         sentry guard (*this);
         if (guard) {
             iostate err;
             try {
                 use_facet<num_get<charT> >(getloc ())
                     .get (..., *this, err, x);
             }
             catch (...) {
                 bool rethrow;
                 try {
                     setstate (badbit);
                     rethrow = false;
                 }
                 catch (...) {
                     rethrow = true;
                 }
                 if (rethrow)
                     throw;
             }
             if (err)
                 setstate (err);
         }
     }

> - which means it must catch all
> exceptions thrown by sentry::sentry(), including those thrown by
> setstate(). I don't think it would make sense to treat exceptions
> thrown by setstate() differently based on whether setstate() was
> called directly by operator>> or indirectly through sentry::sentry(),
> so operator>> should catch exceptions thrown from setstate().

That's why sentry must catch exceptions, and that's also
why you can't implement the function above as

     operator>>(int &x)
     {
         try {
             sentry guard (*this);
             ...
         }
         catch (...) {
             bool rethrow;
             try {
                 setstate (badbit);
              ...

Because such an implementation would end up setting badbit
if sentry threw failbit. I'm sure you agree that's not what
should happen.

> 
> However, if this is the intended meaning, then we have a potential
> DR: The description of badbit in 27.4.2.1.3 is incomplete and the
> words "or (exceptions() & failbit) != 0" need to be added.

I don't think this could ever pass. The intent of badbit is
to indicate some unrecoverable error in the stream buffer.
Setting it as a result of failbit being set in both state
and exceptions would defeat the purpose of the bit.

If there is a defect in there somewhere (I don't doubt there
is), it's in the imprecise wording possibly even muddied by
a number of fixes that went into the TC, not in the intent.

Martin


Comment 13 Pétur Runólfsson 2003-07-24 20:43:39 UTC
Martin Sebor wrote:
> http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#309

That's not the latest version; revision 26 (post-oxford) is here:

http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1480.html

(Why haven't the links been updated?)

The only semantics for exceptions() that make any real amount of
sense are that after a call to an (un)formatted input/output
operation R on a [io]stream s and object x:

s R x;

1) If (s.rdstate() == 0) before the call, an exception is thrown
if and only if after the call (s.rdstate() & s.exceptions()) != 0;

2) The value of s.rdstate() after the call does not depend on
the value of s.exceptions().

The implementation of operator>> you described seems to
achieve exactly this.

Unfortunately the description of basic_ios::exceptions() gives
no such guarantees, nor any other hint whatsoever about what
the intent of exceptions() was. Even worse, the rationale for
closing DR 399 as NAD indicates that property 1) isn't supposed
to hold.

> I don't think this could ever pass. The intent of badbit is
> to indicate some unrecoverable error in the stream buffer.
> Setting it as a result of failbit being set in both state
> and exceptions would defeat the purpose of the bit.

I agree. If property 2) doesn't hold, badbit is meaningless
if either failbit or eofbit is set in exceptions().

Perhaps I am reading to much into the words "if an exception is
thrown during input" in 27.6.1.2.1 and the intent is not to
catch exceptions thrown during the sentry constructor, whether
by use_facet, ctype::is or rdbuf()->underflow().

(Or perhaps the "no clarification needed" part of the rationale
for DR 309 simply means that 27.6.1.2.1 already requires
sentry::sentry() to catch exceptions; but if this is accepted
one might equally argue that 27.6.1.2.1 requires num_get::get
to catch exceptions. I don't think this can be intended.)

Petur
Comment 14 Martin Sebor 2003-07-24 22:34:54 UTC
Subject: Re:  Regression: Setting failbit in exceptions
 doesn't work

peturr02 at ru dot is wrote:

...
> 
> That's not the latest version; revision 26 (post-oxford) is here:
> 
> http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1480.html
> 
> (Why haven't the links been updated?)

Hmm, dunno. I sent an email to have them updated.

> 
> The only semantics for exceptions() that make any real amount of
> sense are that after a call to an (un)formatted input/output
> operation R on a [io]stream s and object x:
> 
> s R x;
> 
> 1) If (s.rdstate() == 0) before the call, an exception is thrown
> if and only if after the call (s.rdstate() & s.exceptions()) != 0;
> 2) The value of s.rdstate() after the call does not depend on
> the value of s.exceptions().

Agreed.

> 
> The implementation of operator>> you described seems to
> achieve exactly this.

Yes. Our implementation tries to follow 1) and 2) above.

> 
> Unfortunately the description of basic_ios::exceptions() gives
> no such guarantees, nor any other hint whatsoever about what
> the intent of exceptions() was. Even worse, the rationale for
> closing DR 399 as NAD indicates that property 1) isn't supposed
> to hold.

Again, I don't think the intent of the original design was
anything other than your 1) and 2) above, despite the status
of 399 or 309.

> 
> 
>>I don't think this could ever pass. The intent of badbit is
>>to indicate some unrecoverable error in the stream buffer.
>>Setting it as a result of failbit being set in both state
>>and exceptions would defeat the purpose of the bit.
> 
> 
> I agree. If property 2) doesn't hold, badbit is meaningless
> if either failbit or eofbit is set in exceptions().
> 
> Perhaps I am reading to much into the words "if an exception is
> thrown during input" in 27.6.1.2.1 and the intent is not to
> catch exceptions thrown during the sentry constructor, whether
> by use_facet, ctype::is or rdbuf()->underflow().

The intent as I understand it from the email discussions that
took place years ago on the reflector, was to accommodate, at
least to some extent, classic iostreams, that didn't throw
exceptions and didn't expect any functions called from the
iostream members to do so, either.

The text in iostreams is probably slightly out of sync with
locale, which came later. My guess is that whoever wrote it
did not anticipate any virtual functions other than members
of streambuf to be called from iostream members. The only
sane and consistent thing to do, IMHO, is to have iostreams
behave according to your 1) and 2) above.

> 
> (Or perhaps the "no clarification needed" part of the rationale
> for DR 309 simply means that 27.6.1.2.1 already requires
> sentry::sentry() to catch exceptions; but if this is accepted
> one might equally argue that 27.6.1.2.1 requires num_get::get
> to catch exceptions. I don't think this can be intended.)

I think one just needs to take the standard with a big
grain of salt when it comes to error handling in iostreams.

Martin

Comment 15 Pétur Runólfsson 2003-09-03 08:17:16 UTC
I don't know how I managed to miss this:

http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#61

This means that exceptions thrown by setstate() should not be caught.
So this bug is real, and is a regression.

This still leaves open what to do in sentry::sentry(), but that's not
really relevant to this bug, and is the subject of another DR:

http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#309
Comment 16 Mark Mitchell 2003-10-16 02:53:40 UTC
Postponed until GCC 3.3.3.
Comment 17 Benjamin Kosnik 2003-10-24 07:41:53 UTC
I think something like this will work, but will have to be propagated throughout
the istream/ostream functions.

Index: include/bits/istream.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/istream.tcc,v
retrieving revision 1.52
diff -c -p -r1.52 istream.tcc
*** include/bits/istream.tcc	12 Oct 2003 10:12:08 -0000	1.52
--- include/bits/istream.tcc	24 Oct 2003 07:39:25 -0000
*************** namespace std 
*** 60,69 ****
  	      while (!traits_type::eq_int_type(__c, __eof)
  		     && __ct.is(ctype_base::space, 
  				traits_type::to_char_type(__c)))
! 		  __c = __sb->snextc();
  
  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
! 	      // 195. Should basic_istream::sentry's constructor ever set eofbit? 
  	      if (traits_type::eq_int_type(__c, __eof))
  		__in.setstate(ios_base::eofbit);
  	    }
--- 60,70 ----
  	      while (!traits_type::eq_int_type(__c, __eof)
  		     && __ct.is(ctype_base::space, 
  				traits_type::to_char_type(__c)))
! 		__c = __sb->snextc();
  
  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
! 	      // 195. Should basic_istream::sentry's constructor ever
! 	      // set eofbit?
  	      if (traits_type::eq_int_type(__c, __eof))
  		__in.setstate(ios_base::eofbit);
  	    }
*************** namespace std 
*** 113,124 ****
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
  	  try 
  	    {
- 	      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
- 	      this->setstate(__err);
  	    }
  	  catch(...)
  	    {
--- 114,124 ----
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
+ 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
  	  catch(...)
  	    {
*************** namespace std 
*** 128,133 ****
--- 128,134 ----
  	      if ((this->exceptions() & ios_base::badbit) != 0)
  		__throw_exception_again;
  	    }
+ 	  this->setstate(__err);
  	}
        return *this;
      }
*************** namespace std 
*** 140,149 ****
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
  	  try 
  	    {
  	      long __l;
- 	      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __l);
  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
--- 141,150 ----
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
+ 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
  	      long __l;
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __l);
  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
*************** namespace std 
*** 154,160 ****
  		__n = __l;
  	      else
                  __err |= ios_base::failbit;
- 	      this->setstate(__err);
  	    }
  	  catch(...)
  	    {
--- 155,160 ----
*************** namespace std 
*** 164,169 ****
--- 164,170 ----
  	      if ((this->exceptions() & ios_base::badbit) != 0)
  		__throw_exception_again;
  	    }
+ 	  this->setstate(__err);
  	}
        return *this;
      }
*************** namespace std 
*** 176,187 ****
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
  	  try 
  	    {
- 	      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
- 	      this->setstate(__err);
  	    }
  	  catch(...)
  	    {
--- 177,187 ----
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
+ 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
  	  catch(...)
  	    {
*************** namespace std 
*** 191,196 ****
--- 191,197 ----
  	      if ((this->exceptions() & ios_base::badbit) != 0)
  		__throw_exception_again;
  	    }
+ 	  this->setstate(__err);
  	}
        return *this;
      }
*************** namespace std 
*** 203,212 ****
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
  	  try 
  	    {
  	      long __l;
- 	      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __l);
  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
--- 204,213 ----
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
+ 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
  	      long __l;
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __l);
  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
*************** namespace std 
*** 217,223 ****
  		__n = __l;
  	      else
                  __err |= ios_base::failbit;
- 	      this->setstate(__err);
  	    }
  	  catch(...)
  	    {
--- 218,223 ----
*************** namespace std 
*** 227,232 ****
--- 227,233 ----
  	      if ((this->exceptions() & ios_base::badbit) != 0)
  		__throw_exception_again;
  	    }
+ 	  this->setstate(__err);
  	}
        return *this;
      }
*************** namespace std 
*** 239,250 ****
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
  	  try 
  	    {
- 	      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
- 	      this->setstate(__err);
  	    }
  	  catch(...)
  	    {
--- 240,250 ----
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
+ 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
  	  catch(...)
  	    {
*************** namespace std 
*** 254,259 ****
--- 254,260 ----
  	      if ((this->exceptions() & ios_base::badbit) != 0)
  		__throw_exception_again;
  	    }
+ 	  this->setstate(__err);
  	}
        return *this;
      }
*************** namespace std 
*** 266,277 ****
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
  	  try 
  	    {
- 	      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
- 	      this->setstate(__err);
  	    }
  	  catch(...)
  	    {
--- 267,277 ----
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
+ 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
  	  catch(...)
  	    {
*************** namespace std 
*** 281,286 ****
--- 281,287 ----
  	      if ((this->exceptions() & ios_base::badbit) != 0)
  		__throw_exception_again;
  	    }
+ 	  this->setstate(__err);
  	}
        return *this;
      }
*************** namespace std 
*** 293,304 ****
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
  	  try 
  	    {
- 	      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
- 	      this->setstate(__err);
  	    }
  	  catch(...)
  	    {
--- 294,304 ----
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
+ 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
  	  catch(...)
  	    {
*************** namespace std 
*** 308,313 ****
--- 308,314 ----
  	      if ((this->exceptions() & ios_base::badbit) != 0)
  		__throw_exception_again;
  	    }
+ 	  this->setstate(__err);
  	}
        return *this;
      }
*************** namespace std 
*** 321,332 ****
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
  	  try 
  	    {
- 	      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
- 	      this->setstate(__err);
  	    }
  	  catch(...)
  	    {
--- 322,332 ----
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
+ 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
  	  catch(...)
  	    {
*************** namespace std 
*** 336,341 ****
--- 336,342 ----
  	      if ((this->exceptions() & ios_base::badbit) != 0)
  	      __throw_exception_again;
  	    }
+ 	  this->setstate(__err);
  	}
        return *this;
      }
*************** namespace std 
*** 348,359 ****
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
  	  try 
  	    {
- 	      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
- 	      this->setstate(__err);
  	    }
  	  catch(...)
  	    {
--- 349,359 ----
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
+ 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
  	  catch(...)
  	    {
*************** namespace std 
*** 363,368 ****
--- 363,369 ----
  	      if ((this->exceptions() & ios_base::badbit) != 0)
  		__throw_exception_again;
  	    }
+ 	  this->setstate(__err);
  	}
        return *this;
      }
*************** namespace std 
*** 376,387 ****
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
  	  try 
  	    {
- 	      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
- 	      this->setstate(__err);
  	    }
  	  catch(...)
  	    {
--- 377,387 ----
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
+ 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
  	  catch(...)
  	    {
*************** namespace std 
*** 391,396 ****
--- 391,397 ----
  	      if ((this->exceptions() & ios_base::badbit) != 0)
  		__throw_exception_again;
  	    }
+ 	  this->setstate(__err);
  	}
        return *this;
      }
*************** namespace std 
*** 403,414 ****
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
  	  try 
  	    {
- 	      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
- 	      this->setstate(__err);
  	    }
  	  catch(...)
  	    {
--- 404,414 ----
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
+ 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
  	  catch(...)
  	    {
*************** namespace std 
*** 418,423 ****
--- 418,424 ----
  	      if ((this->exceptions() & ios_base::badbit) != 0)
  		__throw_exception_again;
  	    }
+ 	  this->setstate(__err);
  	}
        return *this;
      }
*************** namespace std 
*** 430,441 ****
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
  	  try 
  	    {
- 	      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
- 	      this->setstate(__err);
  	    }
  	  catch(...)
  	    {
--- 431,441 ----
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
+ 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
  	  catch(...)
  	    {
*************** namespace std 
*** 445,450 ****
--- 445,451 ----
  	      if ((this->exceptions() & ios_base::badbit) != 0)
  		__throw_exception_again;
  	    }
+ 	  this->setstate(__err);
  	}
        return *this;
      }
*************** namespace std 
*** 457,468 ****
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
  	  try 
  	    {
- 	      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
- 	      this->setstate(__err);
  	    }
  	  catch(...)
  	    {
--- 458,468 ----
        sentry __cerb(*this, false);
        if (__cerb) 
  	{
+ 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
  	  catch(...)
  	    {
*************** namespace std 
*** 472,477 ****
--- 472,478 ----
  	      if ((this->exceptions() & ios_base::badbit) != 0)
  		__throw_exception_again;
  	    }
+ 	  this->setstate(__err);
  	}
        return *this;
      }
Comment 18 Benjamin Kosnik 2003-10-26 03:11:47 UTC
Created attachment 4999 [details]
2003 10 25 work in progress

Unfinished, need to fix

1) istream formatted char tests for badbit (possible?)
2) add tests for ostream
3) consolidate some of the test code in testsuite_io.h or some other file?

then, think about the rest of the member functions, like the positioning ones
and the formatted member funtions.
Comment 19 CVS Commits 2003-11-27 08:14:35 UTC
Subject: Bug 10093

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	bkoz@gcc.gnu.org	2003-11-27 08:14:25

Modified files:
	libstdc++-v3   : ChangeLog 
	libstdc++-v3/include/bits: basic_ios.h basic_ios.tcc fstream.tcc 
	                           istream.tcc locale_facets.tcc 
	                           ostream.tcc streambuf.tcc 
	libstdc++-v3/testsuite: testsuite_io.h 
	libstdc++-v3/testsuite/27_io/basic_istream/exceptions/char: 
	                                                            9561.cc 
Added files:
	libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char: 
	                                                                       exceptions_badbit_throw.cc 
	                                                                       exceptions_failbit.cc 
	                                                                       exceptions_failbit_throw.cc 
	libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char: 
	                                                                  error_failbit.cc 
	                                                                  exceptions_badbit_throw.cc 
	                                                                  exceptions_failbit_throw.cc 
	                                                                  exceptions_null.cc 
	libstdc++-v3/testsuite/27_io/basic_istream/seekg/char: 
	                                                       exceptions_badbit_throw.cc 
	libstdc++-v3/testsuite/27_io/basic_istream/tellg/char: 
	                                                       exceptions_badbit_throw.cc 
	libstdc++-v3/testsuite/27_io/basic_ostream/flush/char: 
	                                                       exceptions_badbit_throw.cc 
	libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char: 
	                                                                      exceptions_badbit_throw.cc 
	                                                                      exceptions_failbit_throw.cc 
	libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char: 
	                                                                 error_failbit.cc 
	                                                                 exceptions_badbit_throw.cc 
	                                                                 exceptions_failbit_throw.cc 
	                                                                 exceptions_null.cc 
	libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char: 
	                                                       exceptions_badbit_throw.cc 
	libstdc++-v3/testsuite/27_io/basic_ostream/tellp/char: 
	                                                       exceptions_badbit_throw.cc 

Log message:
	2003-11-26  Benjamin Kosnik  <bkoz@redhat.com>
	
	PR libstdc++/9371
	PR libstdc++/9546
	PR libstdc++/10093
	PR libstdc++/10095
	* include/bits/basic_ios.h (basic_ios::setstate): Elide if goodbit.
	(basic_ios::_M_setstate): Consolidate common error handling code.
	* include/bits/basic_ios.tcc: Tweak.
	* include/bits/fstream.tcc: Tweak.
	* include/bits/istream.tcc: Use _M_setstate for common exception
	handling. Move setstate calls after catch.
	(basic_istream::tellg): Check for exceptions thrown by streambuf
	virtual functions.
	(basic_istream::seekg): Same.
	* include/bits/ostream.tcc: Same, but for ostream.
	(basic_ostream::flush): Check for exceptions thrown by streambuf
	virtual functions.
	(basic_istream::tellp): Same.
	(basic_istream::seekp): Same.
	* include/bits/locale_facets.tcc: Tweak.
	* include/bits/streambuf.tcc: Tweak.
	(__copy_streambufs): Propagate exceptions.
	* testsuite/testsuite_io.h (fail_streambuf): New.
	(fail_num_get): New.
	(fail_num_put): New.
	(facet_error): New.
	(underflow_error): New.
	(overflow_error): New.
	(positioning_error): New.
	* testsuite/27_io/basic_istream/exceptions/char/9561.cc: Tweak.
	* testsuite/27_io/basic_istream/extractors_arithmetic/char/
	exceptions_badbit_throw.cc, exceptions_failbit.cc,
	exceptions_failbit_throw.cc: New.
	* testsuite/27_io/basic_istream/extractors_other/char/
	error_failbit.cc, exceptions_badbit_throw.cc,
	exceptions_failbit_throw.cc, exceptions_null.cc: New.
	* testsuite/27_io/basic_istream/seekg/char/exceptions_badbit_throw.cc:
	New.
	* testsuite/27_io/basic_istream/tellg/char/exceptions_badbit_throw.cc:
	New.
	* testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc:
	New.
	* testsuite/27_io/basic_ostream/inserters_arithmetic/char/
	exceptions_badbit_throw.cc, exceptions_failbit_throw.cc: New.
	* testsuite/27_io/basic_ostream/inserters_other/char/
	error_failbit.cc, exceptions_badbit_throw.cc,
	exceptions_failbit_throw.cc, exceptions_null.cc: New.
	* testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc:
	New.
	* testsuite/27_io/basic_ostream/tellp/char/exceptions_badbit_throw.cc:
	New.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&r1=1.2111&r2=1.2112
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/basic_ios.h.diff?cvsroot=gcc&r1=1.25&r2=1.26
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/basic_ios.tcc.diff?cvsroot=gcc&r1=1.27&r2=1.28
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/fstream.tcc.diff?cvsroot=gcc&r1=1.109&r2=1.110
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/istream.tcc.diff?cvsroot=gcc&r1=1.57&r2=1.58
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/locale_facets.tcc.diff?cvsroot=gcc&r1=1.147&r2=1.148
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/ostream.tcc.diff?cvsroot=gcc&r1=1.47&r2=1.48
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/streambuf.tcc.diff?cvsroot=gcc&r1=1.45&r2=1.46
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/testsuite_io.h.diff?cvsroot=gcc&r1=1.4&r2=1.5
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/exceptions/char/9561.cc.diff?cvsroot=gcc&r1=1.2&r2=1.3
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_badbit_throw.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit_throw.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/error_failbit.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_badbit_throw.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_failbit_throw.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/seekg/char/exceptions_badbit_throw.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/tellg/char/exceptions_badbit_throw.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_badbit_throw.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_failbit_throw.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/error_failbit.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_badbit_throw.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_failbit_throw.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/char/exceptions_badbit_throw.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 20 Andrew Pinski 2003-11-27 09:05:09 UTC
Fixed for 3.4 but will be fix also for 3.3.3.
Comment 21 CVS Commits 2003-12-04 03:09:51 UTC
Subject: Bug 10093

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-3_3-branch
Changes by:	bkoz@gcc.gnu.org	2003-12-04 03:09:44

Modified files:
	libstdc++-v3/include/bits: basic_ios.h fstream.tcc istream.tcc 
	                           ostream.tcc streambuf.tcc 

Log message:
	2003-12-03  Benjamin Kosnik  <bkoz@redhat.com>
	
	* include/bits/basic_ios.h (basic_ios::setstate): Revert.
	* include/bits/istream.tcc: Only call setstate if __err != goodbit.
	* include/bits/ostream.tcc: Same.
	* testsuite/27_io/basic_ios/exceptions/char/2.cc: New.
	
	2003-12-03  Benjamin Kosnik  <bkoz@redhat.com>
	
	PR libstdc++/9371
	PR libstdc++/9546
	PR libstdc++/10093
	PR libstdc++/10095
	* include/bits/basic_ios.h (basic_ios::setstate): Elide if goodbit.
	(basic_ios::_M_setstate): Consolidate common error handling code.
	* include/bits/basic_ios.tcc: Tweak.
	* include/bits/fstream.tcc: Tweak.
	* include/bits/istream.tcc: Use _M_setstate for common exception
	handling. Move setstate calls after catch.
	(basic_istream::tellg): Check for exceptions thrown by streambuf
	virtual functions.
	(basic_istream::seekg): Same.
	* include/bits/ostream.tcc: Same, but for ostream.
	(basic_ostream::flush): Check for exceptions thrown by streambuf
	virtual functions.
	(basic_istream::tellp): Same.
	(basic_istream::seekp): Same.
	* include/bits/locale_facets.tcc: Tweak.
	* include/bits/streambuf.tcc: Tweak.
	(__copy_streambufs): Propagate exceptions.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/basic_ios.h.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.14.2.6&r2=1.14.2.7
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/fstream.tcc.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.42.2.12&r2=1.42.2.13
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/istream.tcc.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.36.4.8&r2=1.36.4.9
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/ostream.tcc.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.31.14.7&r2=1.31.14.8
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/streambuf.tcc.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.21.2.5&r2=1.21.2.6

Comment 22 CVS Commits 2003-12-04 03:11:02 UTC
Subject: Bug 10093

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-3_3-branch
Changes by:	bkoz@gcc.gnu.org	2003-12-04 03:10:55

Modified files:
	libstdc++-v3   : ChangeLog 

Log message:
	2003-12-03  Benjamin Kosnik  <bkoz@redhat.com>
	
	* include/bits/basic_ios.h (basic_ios::setstate): Revert.
	* include/bits/istream.tcc: Only call setstate if __err != goodbit.
	* include/bits/ostream.tcc: Same.
	* testsuite/27_io/basic_ios/exceptions/char/2.cc: New.
	
	2003-12-03  Benjamin Kosnik  <bkoz@redhat.com>
	
	PR libstdc++/9371
	PR libstdc++/9546
	PR libstdc++/10093
	PR libstdc++/10095
	* include/bits/basic_ios.h (basic_ios::setstate): Elide if goodbit.
	(basic_ios::_M_setstate): Consolidate common error handling code.
	* include/bits/basic_ios.tcc: Tweak.
	* include/bits/fstream.tcc: Tweak.
	* include/bits/istream.tcc: Use _M_setstate for common exception
	handling. Move setstate calls after catch.
	(basic_istream::tellg): Check for exceptions thrown by streambuf
	virtual functions.
	(basic_istream::seekg): Same.
	* include/bits/ostream.tcc: Same, but for ostream.
	(basic_ostream::flush): Check for exceptions thrown by streambuf
	virtual functions.
	(basic_istream::tellp): Same.
	(basic_istream::seekp): Same.
	* include/bits/locale_facets.tcc: Tweak.
	* include/bits/streambuf.tcc: Tweak.
	(__copy_streambufs): Propagate exceptions.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.1464.2.156&r2=1.1464.2.157

Comment 23 Andrew Pinski 2003-12-04 08:21:18 UTC
Fixed for 3.3.3.