public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* libstdc++/9370: Bad exception handling in formatted I/O functions
@ 2003-01-20  9:56 peturr02
  0 siblings, 0 replies; only message in thread
From: peturr02 @ 2003-01-20  9:56 UTC (permalink / raw)
  To: gcc-gnats


>Number:         9370
>Category:       libstdc++
>Synopsis:       Bad exception handling in formatted I/O functions
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jan 20 09:56:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     peturr02@ru.is
>Release:        gcc-3.2.1
>Organization:
>Environment:
Red Hat Linux 8.0
>Description:
Exception handling in the formatted I/O functions (istream::operator>> and ostream::operator<<) appears to be broken.

1. Exceptions derived from std::exception are handled correctly, except that the original exception isn't rethrown if badbit is set in exceptions(), an ios_base::failure is thrown instead.

2. Exceptions not derived from std::exception are not handled at all, badbit is not set in rdstate() and the exception is passed on to the caller even if badbit is not set in exceptions().
>How-To-Repeat:
See attachment.
>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="exceptionsbug.cc"
Content-Disposition: inline; filename="exceptionsbug.cc"

#include <streambuf>
#include <istream>
#include <ostream>
#include <stdexcept>

class MyEx
{
};

class Badbuf1 : public std::streambuf
{
public:
  void reset()
  {
    static char p[] = "0";
    setg(p, p, p + 1);
  }

  virtual int_type underflow()
  {
    throw MyEx();
  }

  virtual int_type overflow(int_type)
  {
    throw MyEx();
  }
};

class Badbuf2 : public std::streambuf
{
public:
  void reset()
  {
    static char p[] = "0";
    setg(p, p, p + 1);
  }

  virtual int_type underflow()
  {
    throw std::out_of_range("");
  }

  virtual int_type overflow(int_type)
  {
    throw std::out_of_range("");
  }
};

#undef NDEBUG
#include <cassert>

using namespace std;

void test1()
{
  Badbuf1 bb1;
  istream stream1 (&bb1);
  int n;
  
  stream1.clear();
  stream1.exceptions(ios_base::goodbit);
  bb1.reset();

  try
    {
      stream1 >> n;
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }
  catch (MyEx&)
    {
      assert(false);
    }
  catch (...)
    {
      assert(false);
    }

  assert(stream1.rdstate() & ios_base::badbit);

  stream1.clear();
  stream1.exceptions(ios_base::badbit);
  bb1.reset();

  try
    {
      stream1 >> n;

      assert(false);
    }
  catch (std::ios_base::failure&)
    {
      assert(false);
    }
  catch (MyEx&)
    {
    }
  catch (...)
    {
      assert(false);
    }

  assert(stream1.rdstate() & ios_base::badbit);
}

void test2()
{
  Badbuf2 bb2;
  istream stream2 (&bb2);
  short s;

  stream2.clear();
  stream2.exceptions(ios_base::goodbit);
  bb2.reset();

  try
    {
      stream2 >> s;
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }
  catch (out_of_range&)
    {
      assert(false);
    }
  catch (...)
    {
      assert(false);
    }

  assert(stream2.rdstate() & ios_base::badbit);

  stream2.clear();
  stream2.exceptions(ios_base::badbit);
  bb2.reset();

  try
    {
      stream2 >> s;

      assert(false);
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }
  catch (out_of_range&)
    {
    }
  catch (...)
    {
      assert(false);
    }  

  assert(stream2.rdstate() & ios_base::badbit);
}

void test3()
{
  Badbuf1 bb1;
  ostream stream1 (&bb1);
  int n = 0;
  
  stream1.clear();
  stream1.exceptions(ios_base::goodbit);

  try
    {
      stream1 << n;
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }
  catch (MyEx&)
    {
      assert(false);
    }
  catch (...)
    {
      assert(false);
    }

  assert(stream1.rdstate() & ios_base::badbit);

  stream1.clear();
  stream1.exceptions(ios_base::badbit);

  try
    {
      stream1 << n;

      assert(false);
    }
  catch (std::ios_base::failure&)
    {
      assert(false);
    }
  catch (MyEx&)
    {
    }
  catch (...)
    {
      assert(false);
    }

  assert(stream1.rdstate() & ios_base::badbit);
}

void test4()
{
  Badbuf2 bb2;
  ostream stream2 (&bb2);
  short s = 0;

  stream2.clear();
  stream2.exceptions(ios_base::goodbit);

  try
    {
      stream2 << s;
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }
  catch (out_of_range&)
    {
      assert(false);
    }
  catch (...)
    {
      assert(false);
    }

  assert(stream2.rdstate() & ios_base::badbit);

  stream2.clear();
  stream2.exceptions(ios_base::badbit);

  try
    {
      stream2 << s;

      assert(false);
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }
  catch (out_of_range&)
    {
    }
  catch (...)
    {
      assert(false);
    }  

  assert(stream2.rdstate() & ios_base::badbit);
}

int main()
{
  test1();
  test2();
  test3();
  test4();

  return 0;
}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-01-20  9:56 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-01-20  9:56 libstdc++/9370: Bad exception handling in formatted I/O functions peturr02

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).