Currently, basic_streambuf::pubimbue does not modify _M_buf_locale, but basic_streambuf::imbue does so. This appears wrong. * The effects clause of imbue says "Does nothing" * The postcondition clause of pubimbue(loc) is "loc == getloc()". There is no mention that derived classes need to call basic_streambuf::imbue() from overridden versions for this to hold. * The returns clause of getloc() says that if getloc() is called from an overridden version of imbue, then getloc() will return the previously imbued locale. There is no mention that this does not hold if basic_streambuf::imbue is called from the derived class version.
Created attachment 5113 [details] Test case
Created attachment 5114 [details] Draft patch (without new testsuite entry)
Hi, thanks for the PR and the detailed testcase (will be properly acknowledged!) Could you please have a look to the attached draft patch? (Passes testsuite + imbuebug4.cc of course) Thanks, Paolo.
This bit is wrong: { locale __tmp(this->getloc()); this->imbue(__loc); + if (__tmp != __loc) + _M_buf_locale = __loc; return __tmp; } Consider an implementation of imbue that caches a facet: class Foo : public streambuf { ctype<char>* ct; void imbue(const locale& loc) { ct = &use_facet<ctype<char> >(loc); } }; This is then called like this: Foo foo; foo.pubimbue(locale("is_IS")); foo.pubimbue(locale("is_IS")); In the first call to pubimbue the locale is set correctly and all is well. In the second call the temporary object is passed to imbue and a reference to the facet stored, but streambuf does not store a copy of the temporary and so the cached facet becomes a dangling pointer.
I see... Will change those two lines with a plain "_M_buf_locale = __loc;" Thanks! Paolo.
Subject: Bug 13007 CVSROOT: /cvs/gcc Module name: gcc Changes by: paolo@gcc.gnu.org 2003-11-13 23:13:22 Modified files: libstdc++-v3 : ChangeLog libstdc++-v3/include/bits: fstream.tcc libstdc++-v3/include/std: std_streambuf.h libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char: 2.cc libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t: 2.cc Added files: libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char: 13007.cc libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t: 13007.cc libstdc++-v3/testsuite/27_io/basic_streambuf/imbue/char: 13007-1.cc 13007-2.cc libstdc++-v3/testsuite/27_io/basic_streambuf/imbue/wchar_t: 13007-1.cc 13007-2.cc Log message: 2003-11-13 Paolo Carlini <pcarlini@suse.de> Petur Runolfsson <peturr02@ru.is> PR libstdc++/13007 * include/bits/fstream.tcc (imbue): Don't touch the stored locale. * include/std/std_streambuf.h (imbue): According to the standard, base class version does nothing. (pubimbue): Store the locale. * testsuite/27_io/basic_filebuf/imbue/char/13007.cc: New. * testsuite/27_io/basic_filebuf/imbue/wchar_t/13007.cc: New. * testsuite/27_io/basic_filebuf/imbue/char/2.cc: Tweak. * testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc: Likewise. * testsuite/27_io/basic_streambuf/imbue/char/13007-1.cc: New. * testsuite/27_io/basic_streambuf/imbue/char/13007-2.cc: New. * testsuite/27_io/basic_streambuf/imbue/wchar_t/13007-1.cc: New. * testsuite/27_io/basic_streambuf/imbue/wchar_t/13007-2.cc: New. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&r1=1.2082&r2=1.2083 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/fstream.tcc.diff?cvsroot=gcc&r1=1.106&r2=1.107 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/std/std_streambuf.h.diff?cvsroot=gcc&r1=1.44&r2=1.45 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13007.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/2.cc.diff?cvsroot=gcc&r1=1.3&r2=1.4 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/13007.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc.diff?cvsroot=gcc&r1=1.3&r2=1.4 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_streambuf/imbue/char/13007-1.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_streambuf/imbue/char/13007-2.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_streambuf/imbue/wchar_t/13007-1.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_streambuf/imbue/wchar_t/13007-2.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
Fixed for 3.4.
Yo folks, we should move this patch to the gcc-3_3-branch. Thoughts? -benjamin
Subject: Bug 13007 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_3-branch Changes by: paolo@gcc.gnu.org 2004-01-07 11:57:36 Modified files: libstdc++-v3 : ChangeLog libstdc++-v3/include/bits: fstream.tcc libstdc++-v3/include/std: std_streambuf.h Log message: 2004-01-07 Paolo Carlini <pcarlini@suse.de> Petur Runolfsson <peturr02@ru.is> PR libstdc++/13007 * include/bits/fstream.tcc (imbue): Don't touch the stored locale. * include/std/std_streambuf.h (imbue): According to the standard, base class version does nothing. (pubimbue): Store the locale. 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.161&r2=1.1464.2.162 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.13&r2=1.42.2.14 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/std/std_streambuf.h.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.11.2.2&r2=1.11.2.3
Fixed for 3.3.3 too!
Subject: Re: basic_streambuf::pubimbue, imbue wrong >Fixed for 3.3.3 too! Thanks Paolo! -benjamin