From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32268 invoked by alias); 20 Jan 2003 09:56:01 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 32223 invoked by uid 71); 20 Jan 2003 09:56:01 -0000 Resent-Date: 20 Jan 2003 09:56:01 -0000 Resent-Message-ID: <20030120095601.32222.qmail@sources.redhat.com> Resent-From: gcc-gnats@gcc.gnu.org (GNATS Filer) Resent-Cc: gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org Resent-Reply-To: gcc-gnats@gcc.gnu.org, peturr02@ru.is Received: (qmail 23184 invoked by uid 48); 20 Jan 2003 09:52:53 -0000 Message-Id: <20030120095253.23183.qmail@sources.redhat.com> Date: Mon, 20 Jan 2003 09:56:00 -0000 From: peturr02@ru.is Reply-To: peturr02@ru.is To: gcc-gnats@gcc.gnu.org X-Send-Pr-Version: gnatsweb-2.9.3 (1.1.1.1.2.31) Subject: libstdc++/9370: Bad exception handling in formatted I/O functions X-SW-Source: 2003-01/txt/msg01111.txt.bz2 List-Id: >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 #include #include #include 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 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; }