re PR libstdc++/30127 (std::has_facet returns true for not installed derived facets)

2007-12-14  Benjamin Kosnik  <bkoz@redhat.com>

	PR libstdc++/30127
	PR libstdc++/34449
	* include/bits/locale_classes.h (use_facet): Check facet hierarchy.
	(has_facet): Same.
	* testsuite/22_locale/global_templates/user_facet_hierarchies.cc: New.
	* testsuite/22_locale/global_templates/
	standard_facet_hierarchies.cc: New.

From-SVN: r130941
This commit is contained in:
Benjamin Kosnik 2007-12-14 19:32:03 +00:00 committed by Benjamin Kosnik
parent 18117c0574
commit c5f416abf7
4 changed files with 216 additions and 3 deletions

View File

@ -1,3 +1,13 @@
2007-12-14 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/30127
PR libstdc++/34449
* include/bits/locale_classes.h (use_facet): Check facet hierarchy.
(has_facet): Same.
* testsuite/22_locale/global_templates/user_facet_hierarchies.cc: New.
* testsuite/22_locale/global_templates/
standard_facet_hierarchies.cc: New.
2007-12-11 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/34015

View File

@ -579,7 +579,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
const size_t __i = _Facet::id._M_id();
const locale::facet** __facets = __loc._M_impl->_M_facets;
return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);
bool __b(false);
try
{
if (__i < __loc._M_impl->_M_facets_size
&& dynamic_cast<const _Facet*>(__facets[__i]) != NULL)
__b = true;
}
catch (...)
{ }
return __b;
}
/**
@ -601,9 +611,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
const size_t __i = _Facet::id._M_id();
const locale::facet** __facets = __loc._M_impl->_M_facets;
if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i]))
if (__i >= __loc._M_impl->_M_facets_size
|| dynamic_cast<const _Facet*>(__facets[__i]) == NULL)
__throw_bad_cast();
return static_cast<const _Facet&>(*__facets[__i]);
return dynamic_cast<const _Facet&>(*__facets[__i]);
}

View File

@ -0,0 +1,84 @@
// Copyright (C) 2007 Free Software Foundation
//
// 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
#include <string>
#include <locale>
#include <cassert>
#include <testsuite_hooks.h>
// Based on Langer Kreft "Standard C++ IOStreams and Locales" p 316-318
// PR libstdc++/30127
// PR libstdc++/34449
int main()
{
bool test __attribute__((unused)) = true;
using std::locale;
using std::has_facet;
using std::use_facet;
typedef std::ctype<char> base_facet;
typedef std::ctype_byname<char> derived_facet;
locale loc_c = locale::classic();
locale loc_base = loc_c;
locale loc_derived(loc_c, new derived_facet(""));
bool b;
// Standard base facet.
VERIFY( has_facet<base_facet>(loc_c) );
VERIFY( has_facet<base_facet>(loc_base) );
VERIFY( has_facet<base_facet>(loc_derived) );
// Standard derived facet.
VERIFY( !has_facet<derived_facet>(loc_c) );
VERIFY( !has_facet<derived_facet>(loc_base) );
VERIFY( has_facet<derived_facet>(loc_derived) );
// 1
try
{
if (has_facet<derived_facet>(loc_base))
{
use_facet<derived_facet>(loc_base).widen('k');
VERIFY( true );
}
}
catch (...)
{
// Expect no exception.
VERIFY( true );
}
// 2
try
{
if (has_facet<base_facet>(loc_derived))
use_facet<base_facet>(loc_derived).widen('k');
else
VERIFY( true );
}
catch (...)
{
// Expect no exception.
VERIFY( true );
}
return 0;
}

View File

@ -0,0 +1,108 @@
// Copyright (C) 2007 Free Software Foundation
//
// 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
#include <string>
#include <locale>
#include <cassert>
#include <testsuite_hooks.h>
// Based on Langer Kreft "Standard C++ IOStreams and Locales" p 316-318
struct base_facet: public std::locale::facet
{
virtual std::string msg() const
{ return "base class"; }
static std::locale::id id;
};
std::locale::id base_facet::id;
struct derived_facet: public base_facet
{
virtual std::string msg() const
{ return "derived class"; }
virtual std::string msg_repeater() const
{ return "derived class derived class"; }
};
// PR libstdc++/30127
// PR libstdc++/34449
int main()
{
bool test __attribute__((unused)) = true;
using std::locale;
using std::has_facet;
using std::use_facet;
locale loc_c = locale::classic();
locale loc_base(loc_c, new base_facet);
locale loc_derived(loc_c, new derived_facet);
bool b;
// Standard facets.
VERIFY( has_facet<std::ctype<char> >(loc_c) );
VERIFY( has_facet<std::ctype<char> >(loc_base) );
VERIFY( has_facet<std::ctype<char> >(loc_derived) );
// User defined base facet.
VERIFY( !has_facet<base_facet>(loc_c) );
VERIFY( has_facet<base_facet>(loc_base) );
VERIFY( has_facet<base_facet>(loc_derived) );
// User defined derived facet.
VERIFY( !has_facet<derived_facet>(loc_c) );
VERIFY( !has_facet<derived_facet>(loc_base) );
VERIFY( has_facet<derived_facet>(loc_derived) );
// 1
try
{
if (has_facet<derived_facet>(loc_base))
{
use_facet<derived_facet>(loc_base).msg_repeater();
VERIFY( false );
}
}
catch (...)
{
// Expect no exception.
VERIFY( true );
}
// 2
try
{
if (has_facet<base_facet>(loc_derived))
use_facet<base_facet>(loc_derived).msg();
else
VERIFY( true );
}
catch (...)
{
// Expect no exception.
VERIFY( true );
}
return 0;
}