This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

streambuf::underflow() bug in 2.10.0


Hi..

 Following is source code that reproduces what is, as far as I can tell, a
bug in stdlibc++ 2.10.0, appearing under gcc version 2.95.2-6 19991024
(cygwin experimental), as well as various other gcc's on other operating
systems.
 In short, the 'this' pointer being implicitly passed to a function derived
from streambuf::underflow() is *wrong* because C++ typecasting is being
circumvented by code in _IO_default_uflow (called by streambuf::uflow()) that
appears to directly access the virtual function table and call the
underflow() function directly with the this pointer, a this pointer that, in
this particular situation, will be wrong because it points to the streambuf,
NOT to the actual class, and will not be converted by C++.
 If this was not clear enough, the test program below will make the problem
obvious.  I came across this bug when working on a C++ sockets library.  
Other compilers I tested (Borland C++ 5.5.1 on Windows 98, Compaq's C++ on
Digital UNIX) passed the test program successfully, while all versions of gcc
2.95.x I tried on Cygwin, DJGPP, Ming32, OpenBSD, and Linux failed.

(compiled with g++ -Wall -ansi -pedantic -O0 -g -o underflow underflow.cpp)

here is example bad gcc output:
$ ./underflow
dummy pointer= 0x255fccc
streambuf pointer= 0x255fcd0
mystreambuf pointer= 0x255fccc
mystreambuf::five= 5

underflow() this= 0x255fcd0
underflow() five= 2
-snip-
mystreambuf::underflow is clearly being called with the wrong pointer.  
notice underflow reports 'this' (0x255fcd0 should be 0x255fccc) incorrectly,
resulting in incorrect 'five' giving an incorrect value.  gcc generates no
warning.

correct behavior generated by Compaq's C++:
 dummy pointer= 0x11ffffb10
 streambuf pointer= 0x11ffffb18
 mystreambuf pointer= 0x11ffffb10
 mystreambuf::five= 5

 underflow() this= 0x11ffffb10
 underflow() five= 5


Here is the code for the test program:

// begin
#include <iostream>

using namespace std;

class dummy {
 int llama;
};

class mystreambuf : public dummy, public streambuf {
 public:
   mystreambuf()
     : five(5) {
     cout << "dummy pointer= " << (void *)(dummy *)this << endl;
     cout << "streambuf pointer= " << (void *)(streambuf *)this << endl;

     cout << "mystreambuf pointer= " << (void *)this << endl;
     cout << "mystreambuf::five= " << five << endl << endl;
   }
 protected:
   int underflow() {
     cout << "underflow() this= " << (void *)this << endl;
     cout << "underflow() five= " << five << endl;

     return EOF;
   }

   int five;
};

int main() {
 class mystreambuf strbuf;
 istream is(&strbuf);
 char ch;

 is >> ch;

 return 0;
}
// end

Thats it.  Sorry for the length and lack of technical detail.. im still a C++
newbie.  Are there are workarounds for this problem?  All gcc's appear to
have it, which is exactly the target compiler for the program i am working
on...

Aaron W. LaFramboise aaronwl@aol.com
Contact Info and PGP Key: http://members.aol.com/aaronwl/contact.txt

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]