public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
To: bkoz at gcc dot gnu dot org <gcc-bugzilla@gcc.gnu.org>
Cc: gcc-bugs@gcc.gnu.org
Subject: Re: [Bug libstdc++/11584] ios::iword() fails to zero-initialize storage on failure
Date: Thu, 18 Sep 2003 12:35:00 -0000	[thread overview]
Message-ID: <20030918115600.15210.qmail@thales.mathematik.uni-ulm.de> (raw)
In-Reply-To: <20030917234529.16905.qmail@sources.redhat.com>

On Wed, Sep 17, 2003 at 11:45:29PM -0000, bkoz at gcc dot gnu dot org wrote:
> On closer examination, I don't think this is a bug. 

I don't agree. See below.

> For one thing:
> 
>     int i = std::ios::xalloc();
>     std::cout.iword (i) = 0xdeadbeef;
>     long l = std::cout.iword (i);
>     l == 0xdeadbeef;
> is valid, based on the fact that the index is the same (regardless of the
> replacement operator new). 

First note that iword must try to realloc the array if it is called
with an out of bounds index. This is what happens here and the case
where iword succeeds seems to be standard conforming.

But the bug report is about the case where iword _fails_ to extend the
array. 27.4.2.5[3] clearly states for this case:

| Returns: [...] On failure, a valid long& initialized to 0.

The comparions in the above testcase MUST be false in the case where
iword can't allocate enough memory. The reason is that both iword calls
fail and consequently both calls should return 0.

> If, instead:
> 
> void test01()
> {
>   bool test = true;
>   new_fails = 1;
> 
>   const int i = std::ios::xalloc();
>   std::cout.iword(i) = 0xdeadbeef;
>   long l1 = std::cout.iword(i);
>   VERIFY( l1 == 0xdeadbeef);

This is correct for the success case but false for the failure case.

> [ ... ]
>   // The reference returned may become invalid after another call to
>   // the object's iword member with a different index.  NB: Note the
>   // 'may': it's not required, and in this case should not be
>   // required, as the i size array is still allocated.
>   long l3 = std::cout.iword(i);
>   VERIFY( l3 == 0 || l3 == 0xdeadbeef);

Here we must have l3 == 0xdeadbeef iff iword succeeds. l3 == 0 is correct
iff iword fails!

Note that the term ``reference may become invalid'' above does NOT
mean that the value for a certain index may change. It only means that the
_location_ where that value is stored may change (do to realloc).

The bug is in the following code

   const int i = <very large value, e.g. 0x7FFFFF0>
   std::cout.iword (i) = 0xdeadbeef;
   std::cerr << "expected 0 got " << std::iword (i+1) << std::endl;
   assert (std::cout.iword (i) == 0 || !std::cout.badbit);

which outputs:

   expected 0 got -559038737
   Assertion failed: !std::cout.badbit || std::cout.iword (i) == 0 ...

instead of just

   expected 0 got 0 

The remaining problematic case is: What do we expect from this code:

   const int i = <very large value, e.g. 0x7FFFFF0>
   long & ref =  std::cout.iword (i);
   assert (std::cout.badbit);
   ref = 0xdeadbeef;
   std::cout.iword (i+1) = 0x12345678;
   std::cerr << "ref is " << ref << std::endl;

IMHO it is unreasonable to expect ref to have the value 0xdeadbeef. We
can justify this with the ``reference becomes invalid'' clause cited
above. However, invoking this clause is misleading and doesn't help in
this case, which is even worse:

   const int i = <very large value, e.g. 0x7FFFFF0>
   long & ref =  std::cout.iword (i);
   assert (std::cout.badbit);
   ref = 0xdeadbeef;
   long val = std::cout.iword (i); /* Reference does NOT become invalid */
   assert ((ref == 0xdeadbeef) && (val == 0));

IMHO given the words of the standard the assertion should hold.

  regards  Christian


  reply	other threads:[~2003-09-18 11:56 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-07-18 23:10 [Bug libstdc++/11584] New: " sebor at roguewave dot com
2003-07-29 16:56 ` [Bug libstdc++/11584] " ehrhardt at mathematik dot uni-ulm dot de
2003-08-23  0:52 ` dhazeghi at yahoo dot com
2003-09-10 14:46 ` bkoz at gcc dot gnu dot org
2003-09-17 23:50 ` bkoz at gcc dot gnu dot org
2003-09-18 12:35   ` Christian Ehrhardt [this message]
2003-09-18 12:49 ` ehrhardt at mathematik dot uni-ulm dot de
2003-12-30 20:42 ` jlquinn at optonline dot net
2004-01-08 17:21 ` bkoz at gcc dot gnu dot org
2004-01-26  1:45 ` jlquinn at gcc dot gnu dot org
2004-01-26 20:36 ` bkoz at redhat dot com
2004-01-27  2:32 ` jlquinn at gcc dot gnu dot org
2004-01-27  2:33 ` jlquinn at gcc dot gnu dot org
2004-01-27  4:50 ` bkoz at redhat dot com
2004-01-27 15:46 ` cvs-commit at gcc dot gnu dot org
2004-01-27 15:54 ` cvs-commit at gcc dot gnu dot org
2004-01-27 15:55 ` jlquinn at gcc dot gnu dot org
2004-01-27 16:00 ` pinskia at gcc dot gnu dot org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030918115600.15210.qmail@thales.mathematik.uni-ulm.de \
    --to=ehrhardt@mathematik.uni-ulm.de \
    --cc=gcc-bugs@gcc.gnu.org \
    --cc=gcc-bugzilla@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).