diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 4b9b29c1eb009090a0688f533b18007b5d915f9d..2dd488bb987d536f00f2ee8434b9563357f23d41 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,10 @@
+2003-10-04  Paolo Carlini  <pcarlini@unitus.it>
+
+	PR libstdc++/12206
+	* include/bits/fstream.tcc (imbue): In case a codecvt facet
+	is not available, set _M_codecvt = 0.
+	* testsuite/27_io/basic_filebuf/imbue/12206.cc: New.
+
 2003-10-02  Harald Boehme  <boehme@informatik.hu-berlin.de>
 
 	PR libstdc++/12451
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index 4a7ad850f38a44fa6060a376abb4b78996c04c03..35cb3c7f4466d457d05866ad22645eb0e6b6a6df 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -671,6 +671,8 @@ namespace std
 	  this->_M_buf_locale = __loc;
 	  if (__builtin_expect(has_facet<__codecvt_type>(__loc), true))
 	    _M_codecvt = &use_facet<__codecvt_type>(__loc);
+	  else
+	    _M_codecvt = 0;
 
 	  // NB This may require the reconversion of previously
 	  // converted chars. This in turn may cause the
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/12206.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/12206.cc
new file mode 100644
index 0000000000000000000000000000000000000000..23f14faaeac5d10dd9399bb51d0b02e3ff69afac
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/12206.cc
@@ -0,0 +1,126 @@
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 27.8.1.4 Overridden virtual functions
+
+#include <fstream>
+
+typedef unsigned char Char;
+
+namespace std
+{
+  template <>
+  class codecvt<Char, char, mbstate_t> :
+    public locale::facet, public codecvt_base
+  {
+  public:
+    typedef Char intern_type;
+    typedef char extern_type;
+    typedef mbstate_t state_type;
+    
+    explicit codecvt(size_t refs = 0)
+      : locale::facet(refs) { }
+    result out(mbstate_t& state, const Char* from,
+	       const Char* from_end, const Char*& from_next,
+	       char* to, char* to_limit, char*& to_next) const
+    {
+      return do_out(state, from, from_end, from_next,
+		    to, to_limit, to_next);
+    }
+    result in(mbstate_t& state, const char* from,
+	      const char* from_end, const char*& from_next,
+	      Char* to, Char* to_limit, Char*& to_next) const
+    {
+      return do_in(state, from, from_end, from_next,
+		   to, to_limit, to_next);
+    }
+    result unshift(mbstate_t& state, char* to, char* to_end,
+		   char*& to_next) const
+    { return do_unshift(state, to, to_end, to_next); }
+    int length(mbstate_t& state, const char* from,
+	       const char* from_end, size_t max) const
+    { return do_length(state, from, from_end, max); }
+    int encoding() const throw()
+    { return do_encoding(); }
+    bool always_noconv() const throw()
+    { return do_always_noconv(); }
+    int max_length() const throw()
+    { return do_max_length(); }
+    
+    static locale::id id;
+    
+  protected:
+    virtual result do_out(mbstate_t&, const Char* from,
+			  const Char* from_end,
+			  const Char*& from_next, char* to,
+			  char* to_limit, char*& to_next) const
+    { return ok; }
+    virtual result do_in(mbstate_t&, const char* from,
+			 const char* from_end,
+			 const char*& from_next, Char* to,
+			 Char* to_limit, Char*& to_next) const
+    { return ok; }
+    virtual result do_unshift(mbstate_t&, char* to, char*,
+			      char*& to_next) const
+    { return noconv; }
+    virtual int do_length(mbstate_t&, const char* from,
+			  const char* from_end, size_t max) const
+    { return 1; }
+    virtual int do_encoding() const throw()
+    { return 1; }
+    virtual bool do_always_noconv() const throw()
+    { return false; }
+    virtual int do_max_length() const throw()
+    { return 1; }
+  };
+  
+  locale::id codecvt<Char, char, mbstate_t>::id;
+}
+
+// libstdc++/12206
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+  
+  locale loc(locale::classic(),
+	     new codecvt<Char, char, std::mbstate_t>);
+  locale::global(loc);
+  
+  basic_filebuf<Char, char_traits<Char> > fb;
+
+  loc = locale::classic();
+  locale::global(loc);
+  fb.pubimbue(loc);
+
+  fb.open("tmp_12206", ios_base::out);
+  try
+    {
+      fb.pubseekoff(0, ios_base::cur);
+    }
+  catch (std::exception&)
+    {
+    }
+  fb.close();
+}
+
+int main()
+{
+  test01();
+  return 0;
+}