re PR rtl-optimization/7291 (off-by-one in generated inline bzero code for i386 (64bit))

gcc/ChangeLog

2002-07-24  Frank van der Linden  <fvdl@wasabisystems.com>

	PR optimization/7291
	* config/i386/i386.c (ix86_expand_clrstr): Fix bzero alignment
	problem on x86_64.

2002-05-16  Jason Merrill  <jason@redhat.com>

	* config/mips/mips.c (mips_output_external): Don't do sdata
	optimization for a variable with DECL_COMDAT set.

2002-01-03  Jakub Jelinek  <jakub@redhat.com>

	* c-decl.c (build_compound_literal): Set decl TREE_READONLY from TYPE.

	* c-decl.c (build_compound_literal): Defer compound literal decls
	until until file end to emit them only if they are actually used.

gcc/cp/ChangeLog

2002-07-17  Scott Snyder <snyder@fnal.gov>

	PR c++/7320
	* rtti.c (get_tinfo_decl): Set DECL_COMDAT.

2002-07-05  Nathan Sidwell  <nathan@codesourcery.com>

	Repair damage on weak-impared targets caused by my previous patch.
	* cp-tree.h (import_export_tinfo): Add parameter.
	* decl2.c (import_export_tinfo): Add parameter, post adjust
	DECL_COMDAT.
	* rtti.c (emit_tinfo_decl): DECL_COMDAT is (nearly) always setup by
	import_export_tinfo.

2002-06-30  Nathan Sidwell  <nathan@codesourcery.com>

	* cp-tree.h (CPTI_TINFO_DECL_TYPE): Replace with ...
	(CPTI_TYPE_INFO_PTR_TYPE): ... this.
	(tinfo_decl_type): Replace with ...
	(type_info_ptr_type): ... this.
	(import_export_tinfo): Declare.
	(tinfo_decl_p): Rename to ...
	(unemitted_tinfo_decl_p): ... this.
	* decl2.c (import_export_decl): Break out tinfo handling into ...
	(import_export_tinfo): ... here. New function.
	(finish_file): Adjust.
	* rtti.c (TINFO_REAL_NAME): New macro.
	(init_rtti_processing): Create the tinfo types.
	(get_tinfo_decl_dynamic): Use type_info_ptr_type, get_tinfo_ptr.
	(get_tinfo_decl): Adjust.
	(get_tinfo_ptr): New function.
	(get_type_id): Use it.
	(tinfo_base_init): Create vtable decl here, if it doesn't exist.
	(ptr_initializer): Use get_tinfo_ptr.
	(ptm_initializer): Likewise.
	(synthesize_tinfo_var): Break into ...
	(get_pseudo_ti_init): ... this. Just create the initializer.
	(get_pseudo_ti_desc): .. and this.
	(create_real_tinfo_var): Remove.
	(create_pseudo_type_info): Don't create the vtable decl here.
	(get_vmi_pseudo_type_info): Remove.
	(create_tinfo_types): Adjust.
	(tinfo_decl_p): Rename to ...
	(unemitted_tinfo_decl_p): ... here. Adjust.
	(emit_tinfo_decl): Adjust. Create the initializer.

2002-06-14  Jason Merrill  <jason@redhat.com>

	C++ ABI changes.
	* class.c (build_base_field): Set DECL_PACKED.
	(layout_class_type): Don't use tail padding of PODs.
	* mangle.c (write_unqualified_name): Fix template conversion op
	mangling.

2002-05-18  Jason Merrill  <jason@redhat.com>

	PR c++/6611
	* decl2.c (import_export_decl): If we clear
	DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set.

2002-05-14  Jason Merrill  <jason@redhat.com>

	* rtti.c (get_tinfo_decl): Don't call comdat_linkage.
	Do set DECL_COMDAT.
	(synthesize_tinfo_var): Take the public decl.
	(create_real_tinfo_var): Likewise.  Check DECL_COMDAT.
	(emit_tinfo_decl): Adjust.  Call import_export_decl.
	* decl2.c (import_export_decl): Simplify tinfo decl handling.

gcc/testsuite/ChangeLog

2002-07-24  Roger Sayle  <roger@eyesopen.com>

	* gcc.c-torture/execute/memset-3.c: New testcase.

2002-06-14  Jason Merrill  <jason@redhat.com>

	* g++.dg/abi/layout1.C: New test.
	* g++.dg/abi/layout2.C: New test.
	* g++.dg/abi/mangle8.C: New test.

2002-05-14  Jason Merrill  <jason@redhat.com>

	* g++.dg/abi/rtti1.C: New test.

2002-01-03  Jakub Jelinek  <jakub@redhat.com>

	* gcc.dg/gnu89-init-2.c: New test.

libstdc++-v3/ChangeLog

2002-07-26  Phil Edwards  <pme@gcc.gnu.org>

	* libsupc++/new (placement delete):  Remove unused paramater names.

2002-07-25  Benjamin Kosnik  <bkoz@redhat.com>

	PR libstdc++/7216
	* include/std/std_istream.h (basic_iostream): Add typedefs for
	char_type, int_type, pos_type, off_type, and traits_type.
	* testsuite/27_io/iostream.cc (test01): Add typedef tests.
	* testsuite/27_io/istream.cc: Same.
	* testsuite/27_io/ostream.cc: Same.
	* testsuite/27_io/filebuf.cc: Same.
	* testsuite/27_io/stringbuf.cc: Replace content, move to...
	* testsuite/27_io/stringbuf_members.cc: ...here.
	* testsuite/27_io/streambuf.cc: Replace content, move to...
	* testsuite/27_io/streambuf_members.cc: ...here.
	* testsuite/27_io/stringstream.cc: Replace content, move to...
	* testsuite/27_io/stringstream_members.cc: ...here.
	* testsuite/27_io/ios.cc: New file.
	* testsuite/27_io/fstream.cc: New file.
	* testsuite/27_io/ifstream.cc: New file.
	* testsuite/27_io/ofstream.cc: New file.
	* testsuite/27_io/istringstream.cc: New file.
	* testsuite/27_io/ostringstream.cc: New file.

2002-07-25  Benjamin Kosnik  <bkoz@redhat.com>

	PR libstdc++/7220
	* include/bits/istream.tcc (istream::ignore): Don't extract on
	zero.
	* testsuite/27_io/istream_unformatted.cc (test10): Add.

2002-07-24  Benjamin Kosnik  <bkoz@redhat.com>

	PR libstdc++/7222
	* src/locale.cc (locale::locale(const char*)): Use setlocale NULL.
	* testsuite/22_locale/ctor_copy_dtor.cc (test02): New.

2002-07-24  Benjamin Kosnik  <bkoz@redhat.com>

	PR libstdc++/7286
	* libsupc++/new: Add placement delete.
	* testsuite/18_support/new_delete_placement.cc: New.

2002-07-07  Paolo Carlini  <pcarlini@unitus.it>

	PR libstdc++/7186
	* include/bits/stl_deque.h (_Deque_iterator::operator-):
	Make non-member, as already happens for the comparison
	operators in accord with DR179 (Ready).
	* testsuite/23_containers/deque_operators.cc: Add test02.

2002-07-04  Benjamin Kosnik  <bkoz@redhat.com>
	    Jack Reeves  <jackw_reeves@hotmail.com>

	* include/std/std_streambuf.h (basic_streambuf::_M_buf): Change to
	size_t, from int_type.
 	(basic_streambuf::_M_buf_size_opt): Same.
 	(basic_streambuf::_S_pback_sizex): Same.
	* include/bits/streambuf.tcc: Same.
	* include/std/std_streambuf.h (basic_streambuf::snextc): Use
	eq_int_type.
	(basic_streambuf::uflow): Same.
	* include/bits/sstream.tcc (basic_stringbuf::overflow): Use
	to_char_type.
	* include/bits/basic_ios.tcc (basic_ios::init): Use _CharT().
	* include/bits/streambuf.tcc (basic_streambuf::xsgetn): Use
	eq_int_type.
	(basic_streambuf::xsputn): Same.
	(__copy_streambufs): Same.

2002-07-02  Paolo Carlini  <pcarlini@unitus.it>

	PR libstdc++/6642
	* include/bits/stl_iterator.h
	(__normal_iterator::operator-(const __normal_iterator&)):
	Make non-member, as already happens for the comparison
	operators in accord with DR179 (Ready).
	* testsuite/24_iterators/iterator.cc: Add test from the PR.

2002-07-02  Benjamin Kosnik  <bkoz@redhat.com>

	PR libstdc++/6410
	* include/bits/locale_facets.h (moneypunct::moneypunct): Add const
	char* name parameter.
	* config/locale/gnu/monetary_members.cc: Use it.
	* config/locale/generic/monetary_members.cc: Same.
	* src/localename.cc (_Impl::_Impl(const char*, size_t)): Use it.

2002-07-01  Benjamin Kosnik  <bkoz@redhat.com>

	* configure.in (libtool_VERSION): Bump to 5:0:0.
	* configure: Regenerate.

2002-05-19  Paolo Carlini  <pcarlini@unitus.it>

	* testsuite/23_containers/deque_operators.cc (test01):
	Fix minor typo in last commit.

2002-05-18  Paolo Carlini  <pcarlini@unitus.it>

	PR libstdc++/6503
	* include/bits/stl_deque.h (_Deque_iterator::operator==,
	operator!=, operator<, operator>, operator>=, operator<=):
	Make non-member functions, to allow comparing const and
	non-const iterators in any order.
	* testsuite/23_containers/deque_operators.cc: New testfile.

From-SVN: r55786
This commit is contained in:
Jakub Jelinek 2002-07-27 01:23:45 +02:00
parent 09f8b2cd1b
commit a7580e63a7
40 changed files with 1114 additions and 1354 deletions

View File

@ -1,3 +1,21 @@
2002-07-24 Frank van der Linden <fvdl@wasabisystems.com>
PR optimization/7291
* config/i386/i386.c (ix86_expand_clrstr): Fix bzero alignment
problem on x86_64.
2002-05-16 Jason Merrill <jason@redhat.com>
* config/mips/mips.c (mips_output_external): Don't do sdata
optimization for a variable with DECL_COMDAT set.
2002-01-03 Jakub Jelinek <jakub@redhat.com>
* c-decl.c (build_compound_literal): Set decl TREE_READONLY from TYPE.
* c-decl.c (build_compound_literal): Defer compound literal decls
until until file end to emit them only if they are actually used.
2002-07-25 Release Manager
* GCC 3.1.1 Released.

View File

@ -3911,6 +3911,7 @@ build_compound_literal (type, init)
DECL_CONTEXT (decl) = current_function_decl;
TREE_USED (decl) = 1;
TREE_TYPE (decl) = type;
TREE_READONLY (decl) = TREE_READONLY (type);
store_init_value (decl, init);
if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
@ -3933,12 +3934,18 @@ build_compound_literal (type, init)
if (TREE_STATIC (decl))
{
/* This decl needs a name for the assembler output. We also need
a unique suffix to be added to the name, for which DECL_CONTEXT
must be set. */
DECL_NAME (decl) = get_identifier ("__compound_literal");
DECL_CONTEXT (decl) = complit;
a unique suffix to be added to the name. */
char *name;
extern int var_labelno;
ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal", var_labelno);
var_labelno++;
DECL_NAME (decl) = get_identifier (name);
DECL_DEFER_OUTPUT (decl) = 1;
DECL_COMDAT (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
pushdecl (decl);
rest_of_decl_compilation (decl, NULL, 1, 0);
DECL_CONTEXT (decl) = NULL_TREE;
}
return complit;

View File

@ -9505,7 +9505,7 @@ ix86_expand_clrstr (src, count_exp, align_exp)
gen_rtx_SUBREG (SImode, zeroreg, 0)));
if (TARGET_64BIT && (align <= 4 || count == 0))
{
rtx label = ix86_expand_aligntest (countreg, 2);
rtx label = ix86_expand_aligntest (countreg, 4);
emit_insn (gen_strsetsi (destreg,
gen_rtx_SUBREG (SImode, zeroreg, 0)));
emit_label (label);

View File

@ -5854,6 +5854,7 @@ mips_output_external (file, decl, name)
if (TARGET_GP_OPT
&& TREE_CODE (decl) != FUNCTION_DECL
&& !DECL_COMDAT (decl)
&& (len = int_size_in_bytes (TREE_TYPE (decl))) > 0
&& ((section_name = DECL_SECTION_NAME (decl)) == NULL
|| strcmp (TREE_STRING_POINTER (section_name), ".sbss") == 0

View File

@ -1,3 +1,72 @@
2002-07-17 Scott Snyder <snyder@fnal.gov>
PR c++/7320
* rtti.c (get_tinfo_decl): Set DECL_COMDAT.
2002-07-05 Nathan Sidwell <nathan@codesourcery.com>
Repair damage on weak-impared targets caused by my previous patch.
* cp-tree.h (import_export_tinfo): Add parameter.
* decl2.c (import_export_tinfo): Add parameter, post adjust
DECL_COMDAT.
* rtti.c (emit_tinfo_decl): DECL_COMDAT is (nearly) always setup by
import_export_tinfo.
2002-06-30 Nathan Sidwell <nathan@codesourcery.com>
* cp-tree.h (CPTI_TINFO_DECL_TYPE): Replace with ...
(CPTI_TYPE_INFO_PTR_TYPE): ... this.
(tinfo_decl_type): Replace with ...
(type_info_ptr_type): ... this.
(import_export_tinfo): Declare.
(tinfo_decl_p): Rename to ...
(unemitted_tinfo_decl_p): ... this.
* decl2.c (import_export_decl): Break out tinfo handling into ...
(import_export_tinfo): ... here. New function.
(finish_file): Adjust.
* rtti.c (TINFO_REAL_NAME): New macro.
(init_rtti_processing): Create the tinfo types.
(get_tinfo_decl_dynamic): Use type_info_ptr_type, get_tinfo_ptr.
(get_tinfo_decl): Adjust.
(get_tinfo_ptr): New function.
(get_type_id): Use it.
(tinfo_base_init): Create vtable decl here, if it doesn't exist.
(ptr_initializer): Use get_tinfo_ptr.
(ptm_initializer): Likewise.
(synthesize_tinfo_var): Break into ...
(get_pseudo_ti_init): ... this. Just create the initializer.
(get_pseudo_ti_desc): .. and this.
(create_real_tinfo_var): Remove.
(create_pseudo_type_info): Don't create the vtable decl here.
(get_vmi_pseudo_type_info): Remove.
(create_tinfo_types): Adjust.
(tinfo_decl_p): Rename to ...
(unemitted_tinfo_decl_p): ... here. Adjust.
(emit_tinfo_decl): Adjust. Create the initializer.
2002-06-14 Jason Merrill <jason@redhat.com>
C++ ABI changes.
* class.c (build_base_field): Set DECL_PACKED.
(layout_class_type): Don't use tail padding of PODs.
* mangle.c (write_unqualified_name): Fix template conversion op
mangling.
2002-05-18 Jason Merrill <jason@redhat.com>
PR c++/6611
* decl2.c (import_export_decl): If we clear
DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set.
2002-05-14 Jason Merrill <jason@redhat.com>
* rtti.c (get_tinfo_decl): Don't call comdat_linkage.
Do set DECL_COMDAT.
(synthesize_tinfo_var): Take the public decl.
(create_real_tinfo_var): Likewise. Check DECL_COMDAT.
(emit_tinfo_decl): Adjust. Call import_export_decl.
* decl2.c (import_export_decl): Simplify tinfo decl handling.
2002-07-25 Release Manager
* GCC 3.1.1 Released.

View File

@ -3830,6 +3830,8 @@ build_base_field (rli, binfo, empty_p, offsets, t)
DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
/* Tell the backend not to round up to TYPE_ALIGN. */
DECL_PACKED (decl) = 1;
if (!integer_zerop (DECL_SIZE (decl)))
{
@ -4971,6 +4973,12 @@ layout_class_type (t, empty_p, vfuns_p,
CLASSTYPE_SIZE (t) = bitsize_zero_node;
CLASSTYPE_SIZE_UNIT (t) = size_zero_node;
}
/* If this is a POD, we can't reuse its tail padding. */
else if (!CLASSTYPE_NON_POD_P (t))
{
CLASSTYPE_SIZE (t) = TYPE_SIZE (t);
CLASSTYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (t);
}
else
{
CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t);

View File

@ -539,7 +539,7 @@ enum cp_tree_index
CPTI_STD,
CPTI_ABI,
CPTI_TYPE_INFO_TYPE,
CPTI_TINFO_DECL_TYPE,
CPTI_TYPE_INFO_PTR_TYPE,
CPTI_ABORT_FNDECL,
CPTI_GLOBAL_DELETE_FNDECL,
CPTI_AGGR_TAG,
@ -626,7 +626,7 @@ extern tree cp_global_trees[CPTI_MAX];
#define std_node cp_global_trees[CPTI_STD]
#define abi_node cp_global_trees[CPTI_ABI]
#define type_info_type_node cp_global_trees[CPTI_TYPE_INFO_TYPE]
#define tinfo_decl_type cp_global_trees[CPTI_TINFO_DECL_TYPE]
#define type_info_ptr_type cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE]
#define abort_fndecl cp_global_trees[CPTI_ABORT_FNDECL]
#define global_delete_fndecl cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL]
#define current_aggr cp_global_trees[CPTI_AGGR_TAG]
@ -3819,6 +3819,7 @@ extern tree coerce_delete_type PARAMS ((tree));
extern void comdat_linkage PARAMS ((tree));
extern void import_export_vtable PARAMS ((tree, tree, int));
extern void import_export_decl PARAMS ((tree));
extern void import_export_tinfo PARAMS ((tree, tree, int));
extern tree build_cleanup PARAMS ((tree));
extern void finish_file PARAMS ((void));
extern tree reparse_absdcl_as_expr PARAMS ((tree, tree));
@ -4051,7 +4052,7 @@ extern tree get_tinfo_decl PARAMS((tree));
extern tree get_typeid PARAMS((tree));
extern tree build_dynamic_cast PARAMS((tree, tree));
extern void emit_support_tinfos PARAMS((void));
extern int tinfo_decl_p PARAMS((tree, void *));
extern int unemitted_tinfo_decl_p PARAMS((tree, void *));
extern int emit_tinfo_decl PARAMS((tree *, void *));
/* in search.c */

View File

@ -2529,48 +2529,53 @@ import_export_decl (decl)
else
comdat_linkage (decl);
}
else if (tinfo_decl_p (decl, 0))
{
tree ctype = TREE_TYPE (DECL_NAME (decl));
if (IS_AGGR_TYPE (ctype))
import_export_class (ctype);
if (IS_AGGR_TYPE (ctype) && CLASSTYPE_INTERFACE_KNOWN (ctype)
&& TYPE_POLYMORPHIC_P (ctype)
/* If -fno-rtti, we're not necessarily emitting this stuff with
the class, so go ahead and emit it now. This can happen
when a class is used in exception handling. */
&& flag_rtti
/* If the type is a cv-qualified variant of a type, then we
must emit the tinfo function in this translation unit
since it will not be emitted when the vtable for the type
is output (which is when the unqualified version is
generated). */
&& same_type_p (ctype, TYPE_MAIN_VARIANT (ctype)))
{
DECL_NOT_REALLY_EXTERN (decl)
= ! (CLASSTYPE_INTERFACE_ONLY (ctype)
|| (DECL_DECLARED_INLINE_P (decl)
&& ! flag_implement_inlines
&& !DECL_VINDEX (decl)));
/* Always make artificials weak. */
if (flag_weak)
comdat_linkage (decl);
}
else if (TYPE_BUILT_IN (ctype)
&& same_type_p (ctype, TYPE_MAIN_VARIANT (ctype)))
DECL_NOT_REALLY_EXTERN (decl) = 0;
else
comdat_linkage (decl);
}
else
comdat_linkage (decl);
DECL_INTERFACE_KNOWN (decl) = 1;
}
/* Here, we only decide whether or not the tinfo node should be
emitted with the vtable. IS_IN_LIBRARY is non-zero iff the
typeinfo for TYPE should be in the runtime library. */
void
import_export_tinfo (decl, type, is_in_library)
tree decl;
tree type;
int is_in_library;
{
if (DECL_INTERFACE_KNOWN (decl))
return;
if (IS_AGGR_TYPE (type))
import_export_class (type);
if (IS_AGGR_TYPE (type) && CLASSTYPE_INTERFACE_KNOWN (type)
&& TYPE_POLYMORPHIC_P (type)
/* If -fno-rtti, we're not necessarily emitting this stuff with
the class, so go ahead and emit it now. This can happen when
a class is used in exception handling. */
&& flag_rtti)
{
DECL_NOT_REALLY_EXTERN (decl) = !CLASSTYPE_INTERFACE_ONLY (type);
DECL_COMDAT (decl) = 0;
}
else
{
DECL_NOT_REALLY_EXTERN (decl) = 1;
DECL_COMDAT (decl) = 1;
}
/* Now override some cases. */
if (flag_weak)
DECL_COMDAT (decl) = 1;
else if (is_in_library)
DECL_COMDAT (decl) = 0;
DECL_INTERFACE_KNOWN (decl) = 1;
}
tree
build_cleanup (decl)
tree decl;
@ -3364,7 +3369,7 @@ finish_file ()
/* Write out needed type info variables. Writing out one variable
might cause others to be needed. */
if (walk_globals (tinfo_decl_p, emit_tinfo_decl, /*data=*/0))
if (walk_globals (unemitted_tinfo_decl_p, emit_tinfo_decl, /*data=*/0))
reconsider = 1;
/* The list of objects with static storage duration is built up

View File

@ -982,8 +982,17 @@ write_unqualified_name (decl)
{
/* Conversion operator. Handle it right here.
<operator> ::= cv <type> */
tree type;
if (decl_is_template_id (decl, NULL))
{
tree fn_type = get_mostly_instantiated_function_type (decl, NULL,
NULL);
type = TREE_TYPE (fn_type);
}
else
type = TREE_TYPE (DECL_NAME (decl));
write_string ("cv");
write_type (TREE_TYPE (DECL_NAME (decl)));
write_type (type);
}
else if (DECL_OVERLOADED_OPERATOR_P (decl))
{

View File

@ -1,5 +1,5 @@
/* RunTime Type Identification
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
Mostly written by Jason Merrill (jason@cygnus.com).
@ -30,16 +30,46 @@ Boston, MA 02111-1307, USA. */
#include "assert.h"
#include "toplev.h"
/* C++ returns type information to the user in struct type_info
objects. We also use type information to implement dynamic_cast and
exception handlers. Type information for a particular type is
indicated with an ABI defined structure derived from type_info.
This would all be very straight forward, but for the fact that the
runtime library provides the definitions of the type_info structure
and the ABI defined derived classes. We cannot build declarations
of them directly in the compiler, but we need to layout objects of
their type. Somewhere we have to lie.
We define layout compatible POD-structs with compiler-defined names
and generate the appropriate initializations for them (complete
with explicit mention of their vtable). When we have to provide a
type_info to the user we reinterpret_cast the internal compiler
type to type_info. A well formed program can only explicitly refer
to the type_infos of complete types (& cv void). However, we chain
pointer type_infos to the pointed-to-type, and that can be
incomplete. We only need the addresses of such incomplete
type_info objects for static initialization.
The type information VAR_DECL of a type is held on the
IDENTIFIER_GLOBAL_VALUE of the type's mangled name. That VAR_DECL
will be the internal type. It will usually have the correct
internal type reflecting the kind of type it represents (pointer,
array, function, class, inherited class, etc). When the type it
represents is incomplete, it will have the internal type
corresponding to type_info. That will only happen at the end of
translation, when we are emitting the type info objects. */
/* Accessors for the type_info objects. We need to remember several things
about each of the type_info types. The global tree nodes such as
bltn_desc_type_node are TREE_LISTs, and these macros are used to access
the required information. */
/* The RECORD_TYPE of a type_info derived class. */
#define TINFO_PSEUDO_TYPE(NODE) TREE_TYPE (NODE)
/* The VAR_DECL of the vtable for the type_info derived class. */
/* The VAR_DECL of the vtable for the type_info derived class.
This is only filled in at the end of the translation. */
#define TINFO_VTABLE_DECL(NODE) TREE_VALUE (NODE)
extern struct obstack permanent_obstack;
/* The IDENTIFIER_NODE naming the real class. */
#define TINFO_REAL_NAME(NODE) TREE_PURPOSE (NODE)
static tree build_headof PARAMS((tree));
static tree ifnonnull PARAMS((tree, tree));
@ -48,7 +78,8 @@ static tree build_dynamic_cast_1 PARAMS((tree, tree));
static tree throw_bad_cast PARAMS((void));
static tree throw_bad_typeid PARAMS((void));
static tree get_tinfo_decl_dynamic PARAMS((tree));
static bool typeid_ok_p PARAMS ((void));
static tree get_tinfo_ptr PARAMS((tree));
static bool typeid_ok_p PARAMS((void));
static int qualifier_flags PARAMS((tree));
static int target_incomplete_p PARAMS((tree));
static tree tinfo_base_init PARAMS((tree, tree));
@ -59,15 +90,21 @@ static tree dfs_class_hint_mark PARAMS ((tree, void *));
static tree dfs_class_hint_unmark PARAMS ((tree, void *));
static int class_hint_flags PARAMS((tree));
static tree class_initializer PARAMS((tree, tree, tree));
static tree synthesize_tinfo_var PARAMS((tree, tree));
static tree create_real_tinfo_var PARAMS((tree, tree, tree, tree, int));
static tree create_pseudo_type_info PARAMS((const char *, int, ...));
static tree get_vmi_pseudo_type_info PARAMS((int));
static tree get_pseudo_ti_init PARAMS ((tree, tree, int *));
static tree get_pseudo_ti_desc PARAMS((tree));
static void create_tinfo_types PARAMS((void));
static int typeinfo_in_lib_p PARAMS((tree));
static int doing_runtime = 0;
/* Declare language defined type_info type and a pointer to const
type_info. This is incomplete here, and will be completed when
the user #includes <typeinfo>. There are language defined
restrictions on what can be done until that is included. Create
the internal versions of the ABI types. */
void
init_rtti_processing ()
{
@ -75,8 +112,11 @@ init_rtti_processing ()
type_info_type_node = xref_tag
(class_type_node, get_identifier ("type_info"), 1);
pop_namespace ();
tinfo_decl_type =
build_qualified_type (type_info_type_node, TYPE_QUAL_CONST);
type_info_ptr_type =
build_pointer_type
(build_qualified_type (type_info_type_node, TYPE_QUAL_CONST));
create_tinfo_types ();
}
/* Given the expression EXP of type `class *', return the head of the
@ -183,13 +223,12 @@ get_tinfo_decl_dynamic (exp)
/* The RTTI information is at index -1. */
index = integer_minus_one_node;
t = build_vtbl_ref (exp, index);
TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
TREE_TYPE (t) = type_info_ptr_type;
return t;
}
/* otherwise return the type_info for the static type of the expr. */
exp = get_tinfo_decl (TYPE_MAIN_VARIANT (type));
return build_unary_op (ADDR_EXPR, exp, 0);
/* Otherwise return the type_info for the static type of the expr. */
return get_tinfo_ptr (TYPE_MAIN_VARIANT (type));
}
static bool
@ -263,9 +302,9 @@ tinfo_name (type)
return name_string;
}
/* Returns a decl for the type_info variable for TYPE. You must
arrange that the decl is mark_used, if actually use it --- decls in
vtables are only used if the vtable is output. */
/* Return a VAR_DECL for the internal ABI defined type_info object for
TYPE. You must arrange that the decl is mark_used, if actually use
it --- decls in vtables are only used if the vtable is output. */
tree
get_tinfo_decl (type)
@ -278,7 +317,7 @@ get_tinfo_decl (type)
&& TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
{
error ("cannot create type information for type `%T' because its size is variable",
type);
type);
return error_mark_node;
}
@ -291,37 +330,45 @@ get_tinfo_decl (type)
name = mangle_typeinfo_for_type (type);
d = IDENTIFIER_GLOBAL_VALUE (name);
if (d)
/* OK */;
else
if (!d)
{
/* The tinfo decl is the type_info object itself. We make all
tinfo objects look as type_info, even though they will end up
being a subclass of that when emitted. This means that we'll
erroneously think we know the dynamic type -- be careful in the
runtime. */
d = build_lang_decl (VAR_DECL, name, tinfo_decl_type);
tree var_desc = get_pseudo_ti_desc (type);
d = build_lang_decl (VAR_DECL, name, TINFO_PSEUDO_TYPE (var_desc));
DECL_ARTIFICIAL (d) = 1;
DECL_ALIGN (d) = TYPE_ALIGN (ptr_type_node);
DECL_USER_ALIGN (d) = 0;
TREE_READONLY (d) = 1;
TREE_STATIC (d) = 1;
DECL_EXTERNAL (d) = 1;
TREE_PUBLIC (d) = 1;
if (flag_weak || !typeinfo_in_lib_p (type))
comdat_linkage (d);
SET_DECL_ASSEMBLER_NAME (d, name);
DECL_COMDAT (d) = 1;
cp_finish_decl (d, NULL_TREE, NULL_TREE, 0);
pushdecl_top_level (d);
/* Remember the type it is for. */
TREE_TYPE (name) = type;
TREE_USED (name) = 1;
}
return d;
}
/* Return a pointer to a type_info object describing TYPE, suitably
cast to the language defined type. */
static tree
get_tinfo_ptr (type)
tree type;
{
tree exp = get_tinfo_decl (type);
/* Convert to type_info type. */
exp = build_unary_op (ADDR_EXPR, exp, 0);
exp = ocp_convert (type_info_ptr_type, exp, CONV_REINTERPRET, 0);
return exp;
}
/* Return the type_info object for TYPE. */
tree
@ -350,7 +397,7 @@ get_typeid (type)
if (!type)
return error_mark_node;
return get_tinfo_decl (type);
return build_indirect_ref (get_tinfo_ptr (type), NULL);
}
/* Check whether TEST is null before returning RESULT. If TEST is used in
@ -683,6 +730,7 @@ tinfo_base_init (desc, target)
{
tree init = NULL_TREE;
tree name_decl;
tree vtable_ptr;
{
tree name_name;
@ -710,12 +758,40 @@ tinfo_base_init (desc, target)
cp_finish_decl (name_decl, name_string, NULL_TREE, 0);
pushdecl_top_level (name_decl);
}
if (TINFO_VTABLE_DECL (desc))
vtable_ptr = TINFO_VTABLE_DECL (desc);
if (!vtable_ptr)
{
tree vtbl_ptr = TINFO_VTABLE_DECL (desc);
init = tree_cons (NULL_TREE, vtbl_ptr, init);
tree real_type;
push_nested_namespace (abi_node);
real_type = xref_tag (class_type_node, TINFO_REAL_NAME (desc), 1);
pop_nested_namespace (abi_node);
if (!COMPLETE_TYPE_P (real_type))
{
/* We never saw a definition of this type, so we need to
tell the compiler that this is an exported class, as
indeed all of the __*_type_info classes are. */
SET_CLASSTYPE_INTERFACE_KNOWN (real_type);
CLASSTYPE_INTERFACE_ONLY (real_type) = 1;
}
vtable_ptr = get_vtable_decl (real_type, /*complete=*/1);
vtable_ptr = build_unary_op (ADDR_EXPR, vtable_ptr, 0);
/* We need to point into the middle of the vtable. */
vtable_ptr = build
(PLUS_EXPR, TREE_TYPE (vtable_ptr), vtable_ptr,
size_binop (MULT_EXPR,
size_int (2),
TYPE_SIZE_UNIT (vtable_entry_type)));
TREE_CONSTANT (vtable_ptr) = 1;
TINFO_VTABLE_DECL (desc) = vtable_ptr;
}
init = tree_cons (NULL_TREE, vtable_ptr, init);
init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
@ -764,8 +840,7 @@ ptr_initializer (desc, target, non_public_ptr)
}
init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
init = tree_cons (NULL_TREE,
build_unary_op (ADDR_EXPR,
get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
init);
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
@ -802,12 +877,11 @@ ptm_initializer (desc, target, non_public_ptr)
}
init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
init = tree_cons (NULL_TREE,
build_unary_op (ADDR_EXPR,
get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
init);
init = tree_cons (NULL_TREE,
build_unary_op (ADDR_EXPR, get_tinfo_decl (klass), 0),
init);
get_tinfo_ptr (klass),
init);
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
@ -928,77 +1002,63 @@ typeinfo_in_lib_p (type)
}
}
/* Generate a pseudo_type_info VAR_DECL suitable for the supplied
TARGET_TYPE and given the REAL_NAME. This is the structure expected by
the runtime, and therefore has additional fields. If we need not emit a
definition (because the runtime must contain it), return NULL_TREE,
otherwise return the VAR_DECL. */
/* Generate the initializer for the type info describing
TYPE. VAR_DESC is a . NON_PUBLIC_P is set non-zero, if the VAR_DECL
should not be exported from this object file. This should only be
called at the end of translation, when we know that no further
types will be completed. */
static tree
synthesize_tinfo_var (target_type, real_name)
tree target_type;
tree real_name;
get_pseudo_ti_init (type, var_desc, non_public_p)
tree type;
tree var_desc;
int *non_public_p;
{
tree var_init = NULL_TREE;
tree var_type = NULL_TREE;
int non_public = 0;
switch (TREE_CODE (target_type))
my_friendly_assert (at_eof, 20021120);
switch (TREE_CODE (type))
{
case POINTER_TYPE:
if (TYPE_PTRMEM_P (target_type))
{
var_type = ptm_desc_type_node;
var_init = ptm_initializer (var_type, target_type, &non_public);
}
if (TYPE_PTRMEM_P (type))
return ptm_initializer (var_desc, type, non_public_p);
else
{
if (typeinfo_in_lib_p (target_type) && !doing_runtime)
/* These are in the runtime. */
return NULL_TREE;
var_type = ptr_desc_type_node;
var_init = ptr_initializer (var_type, target_type, &non_public);
}
return ptr_initializer (var_desc, type, non_public_p);
break;
case ENUMERAL_TYPE:
var_type = enum_desc_type_node;
var_init = generic_initializer (var_type, target_type);
return generic_initializer (var_desc, type);
break;
case FUNCTION_TYPE:
var_type = func_desc_type_node;
var_init = generic_initializer (var_type, target_type);
return generic_initializer (var_desc, type);
break;
case ARRAY_TYPE:
var_type = ary_desc_type_node;
var_init = generic_initializer (var_type, target_type);
return generic_initializer (var_desc, type);
break;
case UNION_TYPE:
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (target_type))
if (TYPE_PTRMEMFUNC_P (type))
return ptm_initializer (var_desc, type, non_public_p);
else if (var_desc == class_desc_type_node)
{
var_type = ptm_desc_type_node;
var_init = ptm_initializer (var_type, target_type, &non_public);
}
else if (!COMPLETE_TYPE_P (target_type))
{
/* Emit a non-public class_type_info. */
non_public = 1;
var_type = class_desc_type_node;
var_init = class_initializer (var_type, target_type, NULL_TREE);
}
else if (!CLASSTYPE_N_BASECLASSES (target_type))
{
var_type = class_desc_type_node;
var_init = class_initializer (var_type, target_type, NULL_TREE);
if (!COMPLETE_TYPE_P (type))
/* Emit a non-public class_type_info. */
*non_public_p = 1;
return class_initializer (var_desc, type, NULL_TREE);
}
else if (var_desc == si_class_desc_type_node)
{
tree base_binfos = BINFO_BASETYPES (TYPE_BINFO (type));
tree base_binfo = TREE_VEC_ELT (base_binfos, 0);
tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
tree base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
return class_initializer (var_desc, type, base_inits);
}
else
{
/* if this has a single public non-virtual base, it's easier */
tree binfo = TYPE_BINFO (target_type);
int hint = class_hint_flags (type);
tree binfo = TYPE_BINFO (type);
int nbases = BINFO_N_BASETYPES (binfo);
tree base_binfos = BINFO_BASETYPES (binfo);
tree base_inits = NULL_TREE;
int is_simple = nbases == 1;
int ix;
/* Generate the base information initializer. */
@ -1012,28 +1072,19 @@ synthesize_tinfo_var (target_type, real_name)
if (TREE_PUBLIC (base_binfo))
flags |= 2;
tinfo = get_tinfo_decl (BINFO_TYPE (base_binfo));
tinfo = build_unary_op (ADDR_EXPR, tinfo, 0);
tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
if (TREE_VIA_VIRTUAL (base_binfo))
{
/* We store the vtable offset at which the virtual
base offset can be found. */
offset = BINFO_VPTR_FIELD (binfo_for_vbase (BINFO_TYPE (base_binfo),
target_type));
offset = BINFO_VPTR_FIELD
(binfo_for_vbase (BINFO_TYPE (base_binfo), type));
offset = convert (sizetype, offset);
flags |= 1;
}
else
offset = BINFO_OFFSET (base_binfo);
/* is it a single public inheritance? */
if (is_simple && flags == 2 && integer_zerop (offset))
{
base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
break;
}
is_simple = 0;
/* combine offset and flags into one field */
offset = cp_build_binary_op (LSHIFT_EXPR, offset,
build_int_2 (8, 0));
@ -1044,86 +1095,23 @@ synthesize_tinfo_var (target_type, real_name)
base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
base_inits = tree_cons (NULL_TREE, base_init, base_inits);
}
if (is_simple)
var_type = si_class_desc_type_node;
else
{
int hint = class_hint_flags (target_type);
base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits);
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
/* Prepend the number of bases. */
base_inits = tree_cons (NULL_TREE,
build_int_2 (nbases, 0), base_inits);
/* Prepend the hint flags. */
base_inits = tree_cons (NULL_TREE,
build_int_2 (hint, 0), base_inits);
var_type = get_vmi_pseudo_type_info (nbases);
}
var_init = class_initializer (var_type, target_type, base_inits);
base_inits = build (CONSTRUCTOR,
NULL_TREE, NULL_TREE, base_inits);
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
/* Prepend the number of bases. */
base_inits = tree_cons (NULL_TREE,
build_int_2 (nbases, 0), base_inits);
/* Prepend the hint flags. */
base_inits = tree_cons (NULL_TREE,
build_int_2 (hint, 0), base_inits);
return class_initializer (var_desc, type, base_inits);
}
break;
default:
if (typeinfo_in_lib_p (target_type))
{
if (!doing_runtime)
/* These are guaranteed to be in the runtime. */
return NULL_TREE;
var_type = bltn_desc_type_node;
var_init = generic_initializer (var_type, target_type);
break;
}
abort ();
return generic_initializer (var_desc, type);
}
return create_real_tinfo_var (target_type,
real_name, TINFO_PSEUDO_TYPE (var_type),
var_init, non_public);
}
/* Create the real typeinfo variable. NON_PUBLIC indicates that we cannot
make this variable public (comdat). */
static tree
create_real_tinfo_var (target_type, name, type, init, non_public)
tree target_type;
tree name;
tree type;
tree init;
int non_public;
{
static int count = 0;
tree decl;
tree hidden_name;
char hidden[30];
/* We cannot give this the name NAME, as that already is globally
bound to the tinfo_decl we originally created for this type in
get_tinfo_decl. */
sprintf (hidden, "__ti_%d", count++);
hidden_name = get_identifier (hidden);
decl = build_lang_decl (VAR_DECL, hidden_name,
build_qualified_type (type, TYPE_QUAL_CONST));
DECL_ARTIFICIAL (decl) = 1;
TREE_READONLY (decl) = 1;
TREE_STATIC (decl) = 1;
DECL_EXTERNAL (decl) = 0;
if (!non_public)
{
TREE_PUBLIC (decl) = 1;
if (flag_weak || !typeinfo_in_lib_p (target_type))
comdat_linkage (decl);
}
SET_DECL_ASSEMBLER_NAME (decl, name);
DECL_INITIAL (decl) = init;
cp_finish_decl (decl, init, NULL_TREE, 0);
pushdecl_top_level (decl);
TREE_USED (decl) = 1;
return decl;
}
/* Generate the RECORD_TYPE containing the data layout of a type_info
@ -1132,7 +1120,10 @@ create_real_tinfo_var (target_type, name, type, init, non_public)
type's vtable. We explicitly manage the vtable member, and name it for
real type as used in the runtime. The RECORD type has a different name,
to avoid collisions. Return a TREE_LIST who's TINFO_PSEUDO_TYPE
is the generated type and TINFO_VTABLE_DECL is the vtable decl.
is the generated type and TINFO_VTABLE_NAME is the name of the
vtable. We have to delay generating the VAR_DECL of the vtable
until the end of the translation, when we'll have seen the library
definition, if there was one.
REAL_NAME is the runtime's name of the type. Trailing arguments are
additional FIELD_DECL's for the structure. The final argument must be
@ -1141,9 +1132,8 @@ create_real_tinfo_var (target_type, name, type, init, non_public)
static tree
create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
{
tree real_type, pseudo_type;
tree pseudo_type;
char *pseudo_name;
tree vtable_decl;
int ix;
tree fields[10];
tree field_decl;
@ -1160,29 +1150,6 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
if (ident)
sprintf (pseudo_name + strlen (pseudo_name), "%d", ident);
/* Get the vtable decl. */
real_type = xref_tag (class_type_node, get_identifier (real_name), 1);
if (! TYPE_SIZE (real_type))
{
/* We never saw a definition of this type, so we need to tell the
compiler that this is an exported class, as indeed all of the
__*_type_info classes are. */
SET_CLASSTYPE_INTERFACE_KNOWN (real_type);
CLASSTYPE_INTERFACE_ONLY (real_type) = 1;
}
vtable_decl = get_vtable_decl (real_type, /*complete=*/1);
vtable_decl = build_unary_op (ADDR_EXPR, vtable_decl, 0);
/* We need to point into the middle of the vtable. */
vtable_decl = build (PLUS_EXPR,
TREE_TYPE (vtable_decl),
vtable_decl,
size_binop (MULT_EXPR,
size_int (2),
TYPE_SIZE_UNIT (vtable_entry_type)));
TREE_CONSTANT (vtable_decl) = 1;
/* First field is the pseudo type_info base class. */
fields[0] = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
@ -1196,53 +1163,96 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
TYPE_HAS_CONSTRUCTOR (pseudo_type) = 1;
result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
TINFO_VTABLE_DECL (result) = vtable_decl;
TINFO_PSEUDO_TYPE (result) = pseudo_type;
TINFO_REAL_NAME (result) = get_identifier (real_name);
TINFO_PSEUDO_TYPE (result) =
cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
VA_CLOSE (ap);
return result;
}
/* Return a descriptor for a vmi type with NUM_BASES bases. */
/* Return a pseudo type info type node used to describe TYPE. TYPE
must be a complete type (or cv void), except at the end of the
translation unit. */
static tree
get_vmi_pseudo_type_info (num_bases)
int num_bases;
get_pseudo_ti_desc (type)
tree type;
{
tree desc;
tree array_domain, base_array;
if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
switch (TREE_CODE (type))
{
int ix;
tree extend = make_tree_vec (num_bases + 5);
for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
TREE_VEC_ELT (extend, ix) = TREE_VEC_ELT (vmi_class_desc_type_node, ix);
vmi_class_desc_type_node = extend;
case POINTER_TYPE:
return TYPE_PTRMEM_P (type) ? ptm_desc_type_node : ptr_desc_type_node;
case ENUMERAL_TYPE:
return enum_desc_type_node;
case FUNCTION_TYPE:
return func_desc_type_node;
case ARRAY_TYPE:
return ary_desc_type_node;
case UNION_TYPE:
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (type))
return ptm_desc_type_node;
else if (!COMPLETE_TYPE_P (type))
{
my_friendly_assert (at_eof, 20020609);
return class_desc_type_node;
}
else if (!CLASSTYPE_N_BASECLASSES (type))
return class_desc_type_node;
else
{
tree base_binfo =
TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), 0);
int num_bases = BINFO_N_BASETYPES (TYPE_BINFO (type));
if (num_bases == 1
&& TREE_PUBLIC (base_binfo)
&& !TREE_VIA_VIRTUAL (base_binfo)
&& integer_zerop (BINFO_OFFSET (base_binfo)))
/* single non-virtual public. */
return si_class_desc_type_node;
else
{
tree var_desc;
tree array_domain, base_array;
if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
{
int ix;
tree extend = make_tree_vec (num_bases + 5);
for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
TREE_VEC_ELT (extend, ix)
= TREE_VEC_ELT (vmi_class_desc_type_node, ix);
vmi_class_desc_type_node = extend;
}
var_desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
if (var_desc)
return var_desc;
/* Add number of bases and trailing array of
base_class_type_info. */
array_domain = build_index_type (size_int (num_bases));
base_array =
build_array_type (base_desc_type_node, array_domain);
push_nested_namespace (abi_node);
var_desc = create_pseudo_type_info
("__vmi_class_type_info", num_bases,
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, base_array),
NULL);
pop_nested_namespace (abi_node);
TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = var_desc;
return var_desc;
}
}
default:
return bltn_desc_type_node;
}
desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
if (desc)
return desc;
/* Add number of bases and trailing array of base_class_type_info. */
array_domain = build_index_type (size_int (num_bases));
base_array = build_array_type (base_desc_type_node, array_domain);
push_nested_namespace (abi_node);
desc = create_pseudo_type_info
("__vmi_class_type_info", num_bases,
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, base_array),
NULL);
pop_nested_namespace (abi_node);
TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = desc;
return desc;
}
/* Make sure the required builtin types exist for generating the type_info
@ -1251,15 +1261,9 @@ get_vmi_pseudo_type_info (num_bases)
static void
create_tinfo_types ()
{
tree ptr_type_info;
if (bltn_desc_type_node)
return;
push_nested_namespace (abi_node);
my_friendly_assert (!ti_desc_type_node, 20020609);
ptr_type_info = build_pointer_type
(build_qualified_type
(type_info_type_node, TYPE_QUAL_CONST));
push_nested_namespace (abi_node);
/* Create the internal type_info structure. This is used as a base for
the other structures. */
@ -1299,7 +1303,7 @@ create_tinfo_types ()
This is really a descendant of __class_type_info. */
si_class_desc_type_node = create_pseudo_type_info
("__si_class_type_info", 0,
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
NULL);
/* Base class internal helper. Pointer to base type, offset to base,
@ -1307,7 +1311,7 @@ create_tinfo_types ()
{
tree fields[2];
fields[0] = build_decl (FIELD_DECL, NULL_TREE, ptr_type_info);
fields[0] = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type);
fields[1] = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
base_desc_type_node = make_aggr_type (RECORD_TYPE);
finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
@ -1324,7 +1328,7 @@ create_tinfo_types ()
ptr_desc_type_node = create_pseudo_type_info
("__pointer_type_info", 0,
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
NULL);
/* Pointer to member data type_info. Add qualifications flags,
@ -1333,8 +1337,8 @@ create_tinfo_types ()
ptm_desc_type_node = create_pseudo_type_info
("__pointer_to_member_type_info", 0,
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
NULL);
pop_nested_namespace (abi_node);
@ -1401,75 +1405,61 @@ emit_support_tinfos ()
definition emitted for it. */
int
tinfo_decl_p (t, data)
unemitted_tinfo_decl_p (t, data)
tree t;
void *data ATTRIBUTE_UNUSED;
{
return TREE_CODE (t) == VAR_DECL
&& IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == (t)
&& TREE_TYPE (t) == tinfo_decl_type
&& TREE_TYPE (DECL_NAME (t));
if (/* It's a var decl */
TREE_CODE (t) == VAR_DECL
/* whos name points back to itself */
&& IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == t
/* whos name's type is non-null */
&& TREE_TYPE (DECL_NAME (t))
/* and whos type is a struct */
&& TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE
/* with a first field of our pseudo type info */
&& TREE_TYPE (TYPE_FIELDS (TREE_TYPE (t))) == ti_desc_type_node)
return 1;
return 0;
}
/* Emit a suitable type_info definition for the type_info decl pointed to by
DECL_PTR. We emit a completely new variable, of the correct type for the
actual type this is describing. The DECL_ASSEMBLER_NAME of the generated
definition is set to that of the supplied decl, so that they can be tied
up. Mark the supplied decl as having been dealt with. Emitting one
definition might cause other definitions to be required.
We need to do things this way, because we're trying to do something like
struct B : A {
...
};
extern const A tinfo_var;
const B tinfo_var = {...};
which is not permitted. Also, we've not necessarily seen the definition of B.
So we do something like the following,
extern const A tinfo_var;
struct pseudo_A {
const void *vtable_ptr;
const char *name;
};
struct pseudo_B {
pseudo_A base;
...
};
const pseudo_B proxy_tinfo_var attribute((assembler_name="tinfo_var")) =
{
{&B::vtable, "..."},
...
};
pseudo_A and pseudo_B must be layout equivalent to the real definitions in
the runtime. */
/* Finish a type info decl. DECL_PTR is a pointer to an unemitted
tinfo decl. Determine whether it needs emitting, and if so
generate the initializer. */
int
emit_tinfo_decl (decl_ptr, data)
tree *decl_ptr;
void *data ATTRIBUTE_UNUSED;
{
tree tinfo_decl = *decl_ptr;
tree tinfo_type, decl;
tree decl = *decl_ptr;
tree type = TREE_TYPE (DECL_NAME (decl));
int non_public;
int in_library = typeinfo_in_lib_p (type);
tree var_desc, var_init;
my_friendly_assert (TREE_TYPE (tinfo_decl) == tinfo_decl_type, 20000121);
tinfo_type = TREE_TYPE (DECL_NAME (tinfo_decl));
my_friendly_assert (tinfo_type != NULL_TREE, 20000120);
if (!DECL_NEEDED_P (tinfo_decl))
import_export_tinfo (decl, type, in_library);
if (DECL_REALLY_EXTERN (decl) || !DECL_NEEDED_P (decl))
return 0;
if (!doing_runtime && in_library)
return 0;
non_public = 0;
var_desc = get_pseudo_ti_desc (type);
var_init = get_pseudo_ti_init (type, var_desc, &non_public);
DECL_EXTERNAL (decl) = 0;
TREE_PUBLIC (decl) = !non_public;
if (non_public)
DECL_COMDAT (decl) = 0;
DECL_INITIAL (decl) = var_init;
cp_finish_decl (decl, var_init, NULL_TREE, 0);
/* cp_finish_decl will have dealt with linkage. */
/* Say we've dealt with it. */
TREE_TYPE (DECL_NAME (tinfo_decl)) = NULL_TREE;
create_tinfo_types ();
decl = synthesize_tinfo_var (tinfo_type, DECL_ASSEMBLER_NAME (tinfo_decl));
return decl != 0;
TREE_TYPE (DECL_NAME (decl)) = NULL_TREE;
return 1;
}

View File

@ -1,3 +1,21 @@
2002-07-24 Roger Sayle <roger@eyesopen.com>
* gcc.c-torture/execute/memset-3.c: New testcase.
2002-06-14 Jason Merrill <jason@redhat.com>
* g++.dg/abi/layout1.C: New test.
* g++.dg/abi/layout2.C: New test.
* g++.dg/abi/mangle8.C: New test.
2002-05-14 Jason Merrill <jason@redhat.com>
* g++.dg/abi/rtti1.C: New test.
2002-01-03 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/gnu89-init-2.c: New test.
2002-07-25 Release Manager
* GCC 3.1.1 Released.

View File

@ -1,3 +1,112 @@
2002-07-26 Phil Edwards <pme@gcc.gnu.org>
* libsupc++/new (placement delete): Remove unused paramater names.
2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/7216
* include/std/std_istream.h (basic_iostream): Add typedefs for
char_type, int_type, pos_type, off_type, and traits_type.
* testsuite/27_io/iostream.cc (test01): Add typedef tests.
* testsuite/27_io/istream.cc: Same.
* testsuite/27_io/ostream.cc: Same.
* testsuite/27_io/filebuf.cc: Same.
* testsuite/27_io/stringbuf.cc: Replace content, move to...
* testsuite/27_io/stringbuf_members.cc: ...here.
* testsuite/27_io/streambuf.cc: Replace content, move to...
* testsuite/27_io/streambuf_members.cc: ...here.
* testsuite/27_io/stringstream.cc: Replace content, move to...
* testsuite/27_io/stringstream_members.cc: ...here.
* testsuite/27_io/ios.cc: New file.
* testsuite/27_io/fstream.cc: New file.
* testsuite/27_io/ifstream.cc: New file.
* testsuite/27_io/ofstream.cc: New file.
* testsuite/27_io/istringstream.cc: New file.
* testsuite/27_io/ostringstream.cc: New file.
2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/7220
* include/bits/istream.tcc (istream::ignore): Don't extract on
zero.
* testsuite/27_io/istream_unformatted.cc (test10): Add.
2002-07-24 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/7222
* src/locale.cc (locale::locale(const char*)): Use setlocale NULL.
* testsuite/22_locale/ctor_copy_dtor.cc (test02): New.
2002-07-24 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/7286
* libsupc++/new: Add placement delete.
* testsuite/18_support/new_delete_placement.cc: New.
2002-07-07 Paolo Carlini <pcarlini@unitus.it>
PR libstdc++/7186
* include/bits/stl_deque.h (_Deque_iterator::operator-):
Make non-member, as already happens for the comparison
operators in accord with DR179 (Ready).
* testsuite/23_containers/deque_operators.cc: Add test02.
2002-07-04 Benjamin Kosnik <bkoz@redhat.com>
Jack Reeves <jackw_reeves@hotmail.com>
* include/std/std_streambuf.h (basic_streambuf::_M_buf): Change to
size_t, from int_type.
(basic_streambuf::_M_buf_size_opt): Same.
(basic_streambuf::_S_pback_sizex): Same.
* include/bits/streambuf.tcc: Same.
* include/std/std_streambuf.h (basic_streambuf::snextc): Use
eq_int_type.
(basic_streambuf::uflow): Same.
* include/bits/sstream.tcc (basic_stringbuf::overflow): Use
to_char_type.
* include/bits/basic_ios.tcc (basic_ios::init): Use _CharT().
* include/bits/streambuf.tcc (basic_streambuf::xsgetn): Use
eq_int_type.
(basic_streambuf::xsputn): Same.
(__copy_streambufs): Same.
2002-07-02 Paolo Carlini <pcarlini@unitus.it>
PR libstdc++/6642
* include/bits/stl_iterator.h
(__normal_iterator::operator-(const __normal_iterator&)):
Make non-member, as already happens for the comparison
operators in accord with DR179 (Ready).
* testsuite/24_iterators/iterator.cc: Add test from the PR.
2002-07-02 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/6410
* include/bits/locale_facets.h (moneypunct::moneypunct): Add const
char* name parameter.
* config/locale/gnu/monetary_members.cc: Use it.
* config/locale/generic/monetary_members.cc: Same.
* src/localename.cc (_Impl::_Impl(const char*, size_t)): Use it.
2002-07-01 Benjamin Kosnik <bkoz@redhat.com>
* configure.in (libtool_VERSION): Bump to 5:0:0.
* configure: Regenerate.
2002-05-19 Paolo Carlini <pcarlini@unitus.it>
* testsuite/23_containers/deque_operators.cc (test01):
Fix minor typo in last commit.
2002-05-18 Paolo Carlini <pcarlini@unitus.it>
PR libstdc++/6503
* include/bits/stl_deque.h (_Deque_iterator::operator==,
operator!=, operator<, operator>, operator>=, operator<=):
Make non-member functions, to allow comparing const and
non-const iterators in any order.
* testsuite/23_containers/deque_operators.cc: New testfile.
2002-07-25 Release Manager
* GCC 3.1.1 Released.

View File

@ -45,7 +45,7 @@ namespace std
template<>
void
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale)
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*)
{
// "C" locale
_M_decimal_point = '.';
@ -61,7 +61,7 @@ namespace std
template<>
void
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale)
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*)
{
// "C" locale
_M_decimal_point = '.';
@ -86,7 +86,8 @@ namespace std
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale)
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,
const char*)
{
// "C" locale
_M_decimal_point = L'.';
@ -102,7 +103,8 @@ namespace std
template<>
void
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale)
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,
const char*)
{
// "C" locale
_M_decimal_point = L'.';

View File

@ -216,7 +216,8 @@ namespace std
template<>
void
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc)
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc,
const char*)
{
if (__cloc == _S_c_locale)
{
@ -260,7 +261,8 @@ namespace std
template<>
void
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc)
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc,
const char*)
{
if (__cloc == _S_c_locale)
{
@ -313,7 +315,8 @@ namespace std
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc)
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc,
const char* __name)
{
if (__cloc == _S_c_locale)
{
@ -331,6 +334,10 @@ namespace std
else
{
// Named locale.
// XXX Fix me. Switch to named locale so that mbsrtowcs will work.
char* __old = strdup(setlocale(LC_ALL, NULL));
setlocale(LC_ALL, __name);
_M_decimal_point = static_cast<wchar_t>(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc)}).__w);
_M_thousands_sep = static_cast<wchar_t>(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc)}).__w);
@ -391,12 +398,17 @@ namespace std
char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc));
char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn);
// XXX
setlocale(LC_ALL, __old);
free(__old);
}
}
template<>
void
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc)
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc,
const char* __name)
{
if (__cloc == _S_c_locale)
{
@ -414,6 +426,10 @@ namespace std
else
{
// Named locale.
// XXX Fix me. Switch to named locale so that mbsrtowcs will work.
char* __old = strdup(setlocale(LC_ALL, NULL));
setlocale(LC_ALL, __name);
_M_decimal_point = static_cast<wchar_t>(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc)}).__w);
_M_thousands_sep = static_cast<wchar_t>(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc)}).__w);
_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
@ -473,6 +489,10 @@ namespace std
char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn);
// XXX
setlocale(LC_ALL, __old);
free(__old);
}
}

View File

@ -599,7 +599,7 @@ ORIGINAL_LD_FOR_MULTILIBS=$LD
PACKAGE=libstdc++
# For libtool versioning info, format is CURRENT:REVISION:AGE
libtool_VERSION=4:1:0
libtool_VERSION=5:0:0

View File

@ -13,7 +13,7 @@ ORIGINAL_LD_FOR_MULTILIBS=$LD
PACKAGE=libstdc++
AC_SUBST(PACKAGE)
# For libtool versioning info, format is CURRENT:REVISION:AGE
libtool_VERSION=4:1:0
libtool_VERSION=5:0:0
AC_SUBST(libtool_VERSION)
GLIBCPP_TOPREL_CONFIGURE

View File

@ -156,7 +156,7 @@ namespace std
// unformatted input and output with non-required basic_ios
// instantiations is possible even without imbuing the expected
// ctype<char_type> facet.
_M_fill = 0;
_M_fill = _CharT();
_M_fill_init = false;
_M_exception = goodbit;

View File

@ -708,7 +708,7 @@ namespace std
{
_M_gcount = 0;
sentry __cerb(*this, true);
if (__cerb)
if (__cerb && __n > 0)
{
try
{

View File

@ -1357,8 +1357,9 @@ namespace std
{ _M_initialize_moneypunct(); }
explicit
moneypunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
{ _M_initialize_moneypunct(__cloc); }
moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0)
: locale::facet(__refs)
{ _M_initialize_moneypunct(__cloc, __s); }
char_type
decimal_point() const
@ -1438,7 +1439,8 @@ namespace std
// For use at construction time only.
void
_M_initialize_moneypunct(__c_locale __cloc = _S_c_locale);
_M_initialize_moneypunct(__c_locale __cloc = _S_c_locale,
const char* __name = NULL);
};
template<typename _CharT, bool _Intl>
@ -1455,11 +1457,11 @@ namespace std
template<>
void
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc);
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*);
template<>
void
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc);
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*);
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
@ -1470,11 +1472,13 @@ namespace std
template<>
void
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc);
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,
const char*);
template<>
void
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc);
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,
const char*);
#endif
template<typename _CharT, bool _Intl>

View File

@ -95,13 +95,13 @@ namespace std
__len *= 2;
if (__testwrite)
__ret = this->sputc(__c);
__ret = this->sputc(traits_type::to_char_type(__c));
else if (__len <= _M_string.max_size())
{
// Force-allocate, re-sync.
_M_string = this->str();
_M_string.reserve(__len);
_M_buf_size = static_cast<int_type>(__len);
_M_buf_size = __len;
_M_really_sync(_M_in_cur - _M_in_beg,
_M_out_cur - _M_out_beg);
*_M_out_cur = traits_type::to_char_type(__c);

View File

@ -130,11 +130,6 @@ struct _Deque_iterator
reference operator*() const { return *_M_cur; }
pointer operator->() const { return _M_cur; }
difference_type operator-(const _Self& __x) const {
return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) +
(_M_cur - _M_first) + (__x._M_last - __x._M_cur);
}
_Self& operator++() {
++_M_cur;
if (_M_cur == _M_last) {
@ -194,16 +189,6 @@ struct _Deque_iterator
reference operator[](difference_type __n) const { return *(*this + __n); }
bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; }
bool operator!=(const _Self& __x) const { return !(*this == __x); }
bool operator<(const _Self& __x) const {
return (_M_node == __x._M_node) ?
(_M_cur < __x._M_cur) : (_M_node < __x._M_node);
}
bool operator>(const _Self& __x) const { return __x < *this; }
bool operator<=(const _Self& __x) const { return !(__x < *this); }
bool operator>=(const _Self& __x) const { return !(*this < __x); }
/** @if maint
* Prepares to traverse new_node. Sets everything except _M_cur, which
* should therefore be set by the caller immediately afterwards, based on
@ -217,6 +202,123 @@ struct _Deque_iterator
}
};
// Note: we also provide overloads whose operands are of the same type in
// order to avoid ambiguos overload resolution when std::rel_ops operators
// are in scope (for additional details, see libstdc++/3628)
template <class _Tp, class _Ref, class _Ptr>
inline bool
operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
{
return __x._M_cur == __y._M_cur;
}
template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
inline bool
operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
{
return __x._M_cur == __y._M_cur;
}
template <class _Tp, class _Ref, class _Ptr>
inline bool
operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
{
return !(__x == __y);
}
template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
inline bool
operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
{
return !(__x == __y);
}
template <class _Tp, class _Ref, class _Ptr>
inline bool
operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
{
return (__x._M_node == __y._M_node) ?
(__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
}
template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
inline bool
operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
{
return (__x._M_node == __y._M_node) ?
(__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
}
template <class _Tp, class _Ref, class _Ptr>
inline bool
operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
{
return __y < __x;
}
template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
inline bool
operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
{
return __y < __x;
}
template <class _Tp, class _Ref, class _Ptr>
inline bool
operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
{
return !(__y < __x);
}
template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
inline bool
operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
{
return !(__y < __x);
}
template <class _Tp, class _Ref, class _Ptr>
inline bool
operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
{
return !(__x < __y);
}
template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
inline bool
operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
{
return !(__x < __y);
}
// _GLIBCPP_RESOLVE_LIB_DEFECTS
// According to the resolution of DR179 not only the various comparison
// operators but also operator- must accept mixed iterator/const_iterator
// parameters.
template <typename _Tp, typename _RefL, typename _PtrL,
typename _RefR, typename _PtrR>
inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
{
return _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
(_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) *
(__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) +
(__y._M_last - __y._M_cur);
}
template <class _Tp, class _Ref, class _Ptr>
inline _Deque_iterator<_Tp, _Ref, _Ptr>
operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)

View File

@ -629,10 +629,6 @@ namespace __gnu_cxx
operator-(const difference_type& __n) const
{ return __normal_iterator(_M_current - __n); }
difference_type
operator-(const __normal_iterator& __i) const
{ return _M_current - __i._M_current; }
const _Iterator&
base() const { return _M_current; }
};
@ -719,6 +715,16 @@ namespace __gnu_cxx
const __normal_iterator<_Iterator, _Container>& __rhs)
{ return __lhs.base() >= __rhs.base(); }
// _GLIBCPP_RESOLVE_LIB_DEFECTS
// According to the resolution of DR179 not only the various comparison
// operators but also operator- must accept mixed iterator/const_iterator
// parameters.
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline typename __normal_iterator<_IteratorL, _Container>::difference_type
operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
{ return __lhs.base() - __rhs.base(); }
template<typename _Iterator, typename _Container>
inline __normal_iterator<_Iterator, _Container>
operator+(typename __normal_iterator<_Iterator, _Container>::difference_type __n,

View File

@ -40,7 +40,7 @@
namespace std
{
template<typename _CharT, typename _Traits>
const typename basic_streambuf<_CharT, _Traits>::int_type
const size_t
basic_streambuf<_CharT, _Traits>::_S_pback_size;
template<typename _CharT, typename _Traits>
@ -138,7 +138,7 @@ namespace std
if (__ret < __n)
{
int_type __c = this->uflow();
if (__c != traits_type::eof())
if (!traits_type::eq_int_type(__c, traits_type::eof()))
{
traits_type::assign(*__s++, traits_type::to_char_type(__c));
++__ret;
@ -177,7 +177,7 @@ namespace std
if (__ret < __n)
{
int_type __c = this->overflow(traits_type::to_int_type(*__s));
if (__c != traits_type::eof())
if (!traits_type::eq_int_type(__c, traits_type::eof()))
{
++__ret;
++__s;
@ -214,7 +214,7 @@ namespace std
__sbin->_M_in_cur_move(__xtrct);
if (__xtrct == __bufsize)
{
if (__sbin->sgetc() == _Traits::eof())
if (_Traits::eq_int_type(__sbin->sgetc(), _Traits::eof()))
break;
__bufsize = __sbin->in_avail();
}

View File

@ -261,6 +261,16 @@ namespace std
public basic_ostream<_CharT, _Traits>
{
public:
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 271. basic_iostream missing typedefs
// Types (inherited):
typedef _CharT char_type;
typedef typename _Traits::int_type int_type;
typedef typename _Traits::pos_type pos_type;
typedef typename _Traits::off_type off_type;
typedef _Traits traits_type;
#endif
// Non-standard Types:
typedef basic_istream<_CharT, _Traits> __istream_type;
typedef basic_ostream<_CharT, _Traits> __ostream_type;

View File

@ -91,10 +91,10 @@ namespace std
char_type* _M_buf;
// Actual size of allocated internal buffer, in bytes.
int_type _M_buf_size;
size_t _M_buf_size;
// Optimal or preferred size of internal buffer, in bytes.
int_type _M_buf_size_opt;
size_t _M_buf_size_opt;
// True iff _M_in_* and _M_out_* buffers should always point to
// the same place. True for fstreams, false for sstreams.
@ -126,7 +126,7 @@ namespace std
// requirements. The only basic_streambuf member function that
// needs access to these data members is in_avail...
// NB: pbacks of over one character are not currently supported.
static const int_type _S_pback_size = 1;
static const size_t _S_pback_size = 1;
char_type _M_pback[_S_pback_size];
char_type* _M_pback_cur_save;
char_type* _M_pback_end_save;
@ -140,8 +140,8 @@ namespace std
{
if (!_M_pback_init)
{
int_type __dist = _M_in_end - _M_in_cur;
int_type __len = min(_S_pback_size, __dist);
size_t __dist = _M_in_end - _M_in_cur;
size_t __len = min(_S_pback_size, __dist);
traits_type::copy(_M_pback, _M_in_cur, __len);
_M_pback_cur_save = _M_in_cur;
_M_pback_end_save = _M_in_end;
@ -159,12 +159,12 @@ namespace std
if (_M_pback_init)
{
// Length _M_in_cur moved in the pback buffer.
int_type __off_cur = _M_in_cur - _M_pback;
size_t __off_cur = _M_in_cur - _M_pback;
// For in | out buffers, the end can be pushed back...
int_type __off_end = 0;
int_type __pback_len = _M_in_end - _M_pback;
int_type __save_len = _M_pback_end_save - _M_buf;
size_t __off_end = 0;
size_t __pback_len = _M_in_end - _M_pback;
size_t __save_len = _M_pback_end_save - _M_buf;
if (__pback_len > __save_len)
__off_end = __pback_len - __save_len;
@ -288,8 +288,8 @@ namespace std
{
if (_M_pback_init)
{
int_type __save_len = _M_pback_end_save - _M_pback_cur_save;
int_type __pback_len = _M_in_cur - _M_pback;
size_t __save_len = _M_pback_end_save - _M_pback_cur_save;
size_t __pback_len = _M_in_cur - _M_pback;
__ret = __save_len - __pback_len;
}
else
@ -304,7 +304,8 @@ namespace std
snextc()
{
int_type __eof = traits_type::eof();
return (this->sbumpc() == __eof ? __eof : this->sgetc());
return (traits_type::eq_int_type(this->sbumpc(), __eof)
? __eof : this->sgetc());
}
int_type
@ -342,10 +343,10 @@ namespace std
protected:
basic_streambuf()
: _M_buf(NULL), _M_buf_size(0),
_M_buf_size_opt(static_cast<int_type>(BUFSIZ)), _M_buf_unified(false),
_M_in_beg(0), _M_in_cur(0), _M_in_end(0), _M_out_beg(0), _M_out_cur(0),
_M_out_end(0), _M_mode(ios_base::openmode(0)), _M_buf_locale(locale()),
: _M_buf(NULL), _M_buf_size(0), _M_buf_size_opt(BUFSIZ),
_M_buf_unified(false), _M_in_beg(0), _M_in_cur(0), _M_in_end(0),
_M_out_beg(0), _M_out_cur(0), _M_out_end(0),
_M_mode(ios_base::openmode(0)), _M_buf_locale(locale()),
_M_buf_locale_init(false), _M_pback_cur_save(0), _M_pback_end_save(0),
_M_pback_init(false)
{ }
@ -438,7 +439,7 @@ namespace std
uflow()
{
int_type __ret = traits_type::eof();
bool __testeof = this->underflow() == __ret;
bool __testeof = traits_type::eq_int_type(this->underflow(), __ret);
bool __testpending = _M_in_cur && _M_in_cur < _M_in_end;
if (!__testeof && __testpending)
{

View File

@ -88,6 +88,10 @@ void operator delete[](void*, const std::nothrow_t&) throw();
// Default placement versions of operator new.
inline void* operator new(std::size_t, void* __p) throw() { return __p; }
inline void* operator new[](std::size_t, void* __p) throw() { return __p; }
// Default placement versions of operator delete.
inline void operator delete (void*, void*) throw() { };
inline void operator delete[](void*, void*) throw() { };
//@}
} // extern "C++"

View File

@ -202,7 +202,7 @@ namespace std
if (strcmp(__s, "C") == 0 || strcmp(__s, "POSIX") == 0)
(_M_impl = _S_classic)->_M_add_reference();
else if (strcmp(__s, "") == 0)
_M_impl = new _Impl(setlocale(LC_ALL, __s), 1);
_M_impl = new _Impl(setlocale(LC_ALL, NULL), 1);
else
_M_impl = new _Impl(__s, 1);
}

View File

@ -132,8 +132,8 @@ namespace std
_M_init_facet(new num_get<char>);
_M_init_facet(new num_put<char>);
_M_init_facet(new std::collate<char>(__cloc));
_M_init_facet(new moneypunct<char, false>(__cloc));
_M_init_facet(new moneypunct<char, true>(__cloc));
_M_init_facet(new moneypunct<char, false>(__cloc, __s));
_M_init_facet(new moneypunct<char, true>(__cloc, __s));
_M_init_facet(new money_get<char>);
_M_init_facet(new money_put<char>);
_M_init_facet(new __timepunct<char>(__cloc, __s));
@ -148,8 +148,8 @@ namespace std
_M_init_facet(new num_get<wchar_t>);
_M_init_facet(new num_put<wchar_t>);
_M_init_facet(new std::collate<wchar_t>(__cloc));
_M_init_facet(new moneypunct<wchar_t, false>(__cloc));
_M_init_facet(new moneypunct<wchar_t, true>(__cloc));
_M_init_facet(new moneypunct<wchar_t, false>(__cloc, __s));
_M_init_facet(new moneypunct<wchar_t, true>(__cloc, __s));
_M_init_facet(new money_get<wchar_t>);
_M_init_facet(new money_put<wchar_t>);
_M_init_facet(new __timepunct<wchar_t>(__cloc, __s));

View File

@ -25,7 +25,6 @@
#include <stdexcept>
#include <testsuite_hooks.h>
void test00()
{
// Should be able to do this as the first thing that happens in a
@ -238,7 +237,21 @@ void test01()
}
#endif // _GLIBCPP_USE___ENC_TRAITS
int main ()
// libstdc++/7222
void test02()
{
bool test = true;
std::locale loc_c1("C");
std::locale loc_c2 ("C");
std::locale loc_1("");
std::locale loc_2("");
VERIFY( loc_c1 == loc_c2 );
VERIFY( loc_1 == loc_2 );
}
int main()
{
test00();
@ -246,5 +259,7 @@ int main ()
test01();
#endif
test02();
return 0;
}

View File

@ -577,6 +577,17 @@ wrong_stuff()
return failures;
}
// libstdc++/6642
int
test6642()
{
std::string s;
std::string::iterator it = s.begin();
std::string::const_iterator cit = s.begin();
return it - cit;
}
int
main(int argc, char **argv)
{
@ -590,6 +601,8 @@ main(int argc, char **argv)
failures += wrong_stuff();
failures += test6642();
#ifdef DEBUG_ASSERT
assert (failures == 0);
#endif

View File

@ -19,15 +19,26 @@
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// NB: this test assumes that _M_buf_size == 40, and not the usual
// buffer_size length of BUFSIZ (8192), so that overflow/underflow can be
// simulated a bit more readily.
// 27.8.1.1 - Template class basic_filebuf
// NB: This file is for testing basic_filebuf with NO OTHER INCLUDES.
#include <fstream>
#include <testsuite_hooks.h>
// { dg-do compile }
// libstdc++/7216
void test01()
{
// Check for required typedefs
typedef std::filebuf test_type;
typedef test_type::char_type char_type;
typedef test_type::traits_type traits_type;
typedef test_type::int_type int_type;
typedef test_type::pos_type pos_type;
typedef test_type::off_type off_type;
}
// test05
// libstdc++/1886
// should be able to instantiate basic_filebuf for non-standard types.
@ -35,6 +46,7 @@ template class std::basic_filebuf<short, std::char_traits<short> >;
int main()
{
test01();
return 0;
}

View File

@ -34,6 +34,18 @@
#include <istream>
// libstdc++/7216
void test01()
{
// Check for required typedefs
typedef std::iostream test_type;
typedef test_type::char_type char_type;
typedef test_type::traits_type traits_type;
typedef test_type::int_type int_type;
typedef test_type::pos_type pos_type;
typedef test_type::off_type off_type;
}
namespace test
{
using namespace std;
@ -43,5 +55,6 @@ namespace test
int main()
{
test01();
return 0;
}

View File

@ -34,6 +34,18 @@
// { dg-do compile }
// libstdc++/7216
void test01()
{
// Check for required typedefs
typedef std::istream test_type;
typedef test_type::char_type char_type;
typedef test_type::traits_type traits_type;
typedef test_type::int_type int_type;
typedef test_type::pos_type pos_type;
typedef test_type::off_type off_type;
}
namespace test
{
using namespace std;
@ -43,5 +55,6 @@ namespace test
int main()
{
test01();
return 0;
}

View File

@ -514,6 +514,43 @@ test09()
VERIFY( test );
}
// libstdc++/70220
void
test10()
{
using namespace std;
bool test = true;
typedef string string_type;
typedef stringbuf stringbuf_type;
typedef istream istream_type;
int res = 0;
streamsize n;
string_type input("abcdefg\n");
stringbuf_type sbuf(input);
istream_type istr(&sbuf);
istr.ignore(0);
if (istr.gcount() != 0)
test = false;
VERIFY( test );
istr.ignore(0, 'b');
if (istr.gcount() != 0)
test = false;
VERIFY( test );
istr.ignore(); // Advance to next position.
istr.ignore(0, 'b');
if ((n=istr.gcount()) != 0)
test = false;
VERIFY( test );
if (istr.peek() != 'b')
test = false;
VERIFY( test );
}
int
main()
{
@ -526,6 +563,7 @@ main()
test07();
test08();
test09();
test10();
return 0;
}

View File

@ -34,6 +34,18 @@
// { dg-do compile }
// libstdc++/7216
void test01()
{
// Check for required typedefs
typedef std::ostream test_type;
typedef test_type::char_type char_type;
typedef test_type::traits_type traits_type;
typedef test_type::int_type int_type;
typedef test_type::pos_type pos_type;
typedef test_type::off_type off_type;
}
namespace test
{
using namespace std;
@ -43,5 +55,6 @@ namespace test
int main()
{
test01();
return 0;
}

View File

@ -1,6 +1,6 @@
// 2001-05-23 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 Free Software Foundation, Inc.
// Copyright (C) 2001, 2002 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
@ -97,9 +97,61 @@ void test02()
// These semantics are a joke, a serious defect, and incredibly lame.
}
// 03: sanity checks for strings, stringbufs
void
test03()
{
bool test = false;
// Empty string sanity check.
std::string str01;
std::string::iterator __i_start = str01.begin();
std::string::iterator __i_end = str01.end();
std::string::size_type len = str01.size();
test = __i_start == __i_end;
VERIFY( len == 0 );
// Full string sanity check.
std::string str02("these golden days, i spend waiting for you:\n"
"Betty Carter on Verve with I'm Yours and You're Mine.");
__i_start = str02.begin();
__i_end = str02.end();
len = str02.size();
VERIFY( __i_start != __i_end );
VERIFY( len != 0 );
// Test an empty ostringstream for sanity.
std::ostringstream ostrstream0;
std::string str03 = ostrstream0.str();
__i_start = str03.begin();
__i_end = str03.end();
len = str03.size();
VERIFY( __i_start == __i_end );
VERIFY( len == 0 );
VERIFY( str01 == str03 );
}
// user-reported error
class derived_oss: public std::ostringstream
{
public:
derived_oss() : std::ostringstream() { }
};
void
test04()
{
bool test = true;
derived_oss yy;
yy << "buena vista social club\n";
VERIFY( yy.str() == std::string("buena vista social club\n") );
}
int main()
{
test01();
test02();
test03();
test04();
return 0;
}

View File

@ -1,6 +1,6 @@
// 1999-10-11 bkoz
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
// Copyright (C) 2002 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
@ -27,352 +27,34 @@
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
// 27.5.2 template class basic_streambuf
// 27.5.2 - Template class basic_streambuf
// NB: This file is for testing basic_streambuf with NO OTHER INCLUDES.
#include <cstring> // for memset, memcmp
#include <streambuf>
#include <string>
#include <ostream>
#include <testsuite_hooks.h>
class testbuf : public std::streambuf
{
public:
// Typedefs:
typedef std::streambuf::traits_type traits_type;
typedef std::streambuf::char_type char_type;
testbuf(): std::streambuf()
{ _M_mode = (std::ios_base::in | std::ios_base::out); }
bool
check_pointers()
{
bool test = true;
VERIFY( this->eback() == NULL );
VERIFY( this->gptr() == NULL );
VERIFY( this->egptr() == NULL );
VERIFY( this->pbase() == NULL );
VERIFY( this->pptr() == NULL );
VERIFY( this->epptr() == NULL );
return test;
}
int_type
pub_uflow()
{ return (this->uflow()); }
int_type
pub_overflow(int_type __c = traits_type::eof())
{ return (this->overflow(__c)); }
int_type
pub_pbackfail(int_type __c)
{ return (this->pbackfail(__c)); }
void
pub_setg(char* beg, char* cur, char *end)
{ this->setg(beg, cur, end); }
void
pub_setp(char* beg, char* end)
{ this->setp(beg, end); }
protected:
int_type
underflow()
{
int_type __retval = traits_type::eof();
if (this->gptr() < this->egptr())
__retval = traits_type::not_eof(0);
return __retval;
}
};
// { dg-do compile }
// libstdc++/7216
void test01()
{
typedef testbuf::traits_type traits_type;
typedef testbuf::int_type int_type;
bool test = true;
char* lit01 = "chicago underground trio/possible cube on delmark";
testbuf buf01;
// 27.5.2.1 basic_streambuf ctors
// default ctor initializes
// - all pointer members to null pointers
// - locale to current global locale
VERIFY( buf01.check_pointers() );
VERIFY( buf01.getloc() == std::locale() );
// 27.5.2.3.1 get area
// 27.5.2.2.3 get area
// 27.5.2.4.3 get area
int i01 = 3;
buf01.pub_setg(lit01, lit01, (lit01 + i01));
VERIFY( i01 == buf01.in_avail() );
VERIFY( buf01.pub_uflow() == lit01[0] );
VERIFY( buf01.sgetc() == traits_type::to_int_type(lit01[1]) );
VERIFY( buf01.pub_uflow() == lit01[1] );
VERIFY( buf01.sgetc() == traits_type::to_int_type(lit01[2]) );
VERIFY( buf01.pub_uflow() == lit01[2] );
VERIFY( buf01.sgetc() == traits_type::eof() );
// pbackfail
buf01.pub_setg(lit01, lit01, (lit01 + i01));
VERIFY( i01 == buf01.in_avail() );
int_type intt01 = traits_type::to_int_type('b');
VERIFY( traits_type::eof() == buf01.pub_pbackfail(intt01) );
// overflow
VERIFY( traits_type::eof() == buf01.pub_overflow(intt01) );
VERIFY( traits_type::eof() == buf01.pub_overflow() );
VERIFY( buf01.sgetc() == traits_type::to_int_type(lit01[0]) );
// sputn/xsputn
char* lit02 = "isotope 217: the unstable molecule on thrill jockey";
int i02 = std::strlen(lit02);
char carray[i02 + 1];
std::memset(carray, 0, i02 + 1);
buf01.pub_setp(carray, (carray + i02));
buf01.sputn(lit02, 0);
VERIFY( carray[0] == 0 );
VERIFY( lit02[0] == 'i' );
buf01.sputn(lit02, 1);
VERIFY( lit02[0] == carray[0] );
VERIFY( lit02[1] == 's' );
VERIFY( carray[1] == 0 );
buf01.sputn(lit02 + 1, 10);
VERIFY( std::memcmp(lit02, carray, 10) == 0 );
buf01.sputn(lit02 + 11, 20);
VERIFY( std::memcmp(lit02, carray, 30) == 0 );
#ifdef DEBUG_ASSERT
assert(test);
#endif
// Check for required typedefs
typedef std::streambuf test_type;
typedef test_type::char_type char_type;
typedef test_type::traits_type traits_type;
typedef test_type::int_type int_type;
typedef test_type::pos_type pos_type;
typedef test_type::off_type off_type;
}
void test02()
namespace test
{
typedef testbuf::traits_type traits_type;
typedef testbuf::int_type int_type;
bool test = true;
char* lit01 = "chicago underground trio/possible cube on delmark";
testbuf buf01;
// 27.5.2.1 basic_streambuf ctors
// default ctor initializes
// - all pointer members to null pointers
// - locale to current global locale
VERIFY( buf01.check_pointers() );
VERIFY( buf01.getloc() == std::locale() );
// 27.5.2.2.5 Put area
size_t i01 = traits_type::length(lit01);
char carray01[i01];
std::memset(carray01, 0, i01);
buf01.pub_setg(lit01, lit01, lit01 + i01);
buf01.sgetn(carray01, 0);
VERIFY( carray01[0] == 0 );
buf01.sgetn(carray01, 1);
VERIFY( carray01[0] == 'c' );
buf01.sgetn(carray01 + 1, i01 - 1);
VERIFY( carray01[0] == 'c' );
VERIFY( carray01[1] == 'h' );
VERIFY( carray01[i01 - 1] == 'k' );
#ifdef DEBUG_ASSERT
assert(test);
#endif
}
// test03
// http://gcc.gnu.org/ml/libstdc++/2000-q1/msg00151.html
template<typename charT, typename traits = std::char_traits<charT> >
class basic_nullbuf : public std::basic_streambuf<charT, traits>
{
protected:
typedef typename
std::basic_streambuf<charT, traits>::int_type int_type;
virtual int_type
overflow(int_type c)
{ return traits::not_eof(c); }
};
typedef basic_nullbuf<char> nullbuf;
typedef basic_nullbuf<wchar_t> wnullbuf;
template<typename T>
char
print(const T& x)
{
nullbuf ob;
std::ostream out(&ob);
out << x << std::endl;
return (!out ? '0' : '1');
}
void test03()
{
bool test = true;
const std::string control01("11111");
std::string test01;
test01 += print(true);
test01 += print(3.14159);
test01 += print(10);
test01 += print('x');
test01 += print("pipo");
VERIFY( test01 == control01 );
#ifdef DEBUG_ASSERT
assert(test);
#endif
}
class setpbuf : public std::streambuf
{
char buffer[4];
std::string result;
public:
std::string&
get_result()
{ return result; }
setpbuf()
{
char foo [32];
setp(foo, foo + 32);
setp(buffer, buffer + 4);
}
~setpbuf()
{ sync(); }
virtual int_type
overflow(int_type n)
{
if (sync() != 0)
return traits_type::eof();
result += traits_type::to_char_type(n);
return n;
}
virtual int
sync()
{
result.append(pbase(), pptr());
setp(buffer, buffer + 4);
return 0;
}
};
// libstdc++/1057
void test04()
{
bool test = true;
std::string text = "abcdefghijklmn";
// 01
setpbuf sp1;
// Here xsputn writes over sp1.result
sp1.sputn(text.c_str(), text.length());
// This crashes when result is accessed
sp1.pubsync();
VERIFY( sp1.get_result() == text );
// 02
setpbuf sp2;
for (std::string::size_type i = 0; i < text.length(); ++i)
{
// sputc also writes over result
sp2.sputc(text[i]);
}
// Crash here
sp2.pubsync();
VERIFY( sp2.get_result() == text );
}
class nullsetpbuf : public std::streambuf
{
char foo[64];
public:
nullsetpbuf()
{
setp(foo, foo + 64);
setp(NULL, NULL);
}
};
// libstdc++/1057
void test05()
{
std::string text1 = "abcdefghijklmn";
nullsetpbuf nsp;
// Immediate crash as xsputn writes to null pointer
nsp.sputn(text1.c_str(), text1.length());
// ditto
nsp.sputc('a');
}
// test06
namespace gnu
{
class something_derived;
}
class gnu::something_derived : std::streambuf { };
// libstdc++/3599
class testbuf2 : public std::streambuf
{
public:
typedef std::streambuf::traits_type traits_type;
testbuf2() : std::streambuf() { }
protected:
int_type
overflow(int_type c = traits_type::eof())
{ return traits_type::not_eof(0); }
};
void
test07()
{
bool test = true;
testbuf2 ob;
std::ostream out(&ob);
out << "gasp";
VERIFY(out.good());
out << std::endl;
VERIFY(out.good());
}
using namespace std;
typedef short type_t;
template class basic_streambuf<type_t, char_traits<type_t> >;
} // test
int main()
{
test01();
test02();
test03();
test04();
test05();
test07();
return 0;
}

View File

@ -1,7 +1,6 @@
// 981208 bkoz test functionality of basic_stringbuf for char_type == char
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
// Free Software Foundation, Inc.
// Copyright (C) 2002 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
@ -19,472 +18,43 @@
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
// 27.7.1 - Template class basic_stringbuf
// NB: This file is for testing basic_stringbuf with NO OTHER INCLUDES.
#include <sstream>
#include <testsuite_hooks.h>
std::string str_01("mykonos. . . or what?");
std::string str_02("paris, or sainte-maxime?");
std::string str_03;
std::stringbuf strb_01(str_01);
std::stringbuf strb_02(str_02, std::ios_base::in);
std::stringbuf strb_03(str_03, std::ios_base::out);
// { dg-do compile }
// test the underlying allocator
bool test01() {
bool test = false;
std::allocator<char> alloc_01;
std::allocator<char>::size_type size_01 = alloc_01.max_size();
std::allocator<char>::pointer p_01 = alloc_01.allocate(32);
return true;
}
// test the streambuf/stringbuf locale settings
bool test02() {
std::locale loc_tmp;
loc_tmp = strb_01.getloc();
strb_01.pubimbue(loc_tmp); //This should initialize _M_init to true
strb_01.getloc(); //This should just return _M_locale
return true;
}
// test member functions
bool test03() {
bool test = true;
//stringbuf::str()
VERIFY( strb_01.str() == str_01 );
VERIFY( strb_02.str() == str_02 );
VERIFY( strb_03.str() == str_03 );
//stringbuf::str(string&)
strb_03.str("none of the above, go to the oberoi in cairo, egypt.");
strb_03.str(str_01);
std::streamsize d1 = strb_01.in_avail();
std::streamsize d2 = strb_03.in_avail();
VERIFY( d1 ); // non-zero
VERIFY( !d2 ); // zero, cuz ios_base::out
VERIFY( d1 != d2 ); //these should be the same
VERIFY( str_01.length() == d1 );
VERIFY( strb_01.str() == strb_03.str() ); //ditto
// stringbuf::str(string&) and stringbuf::stringbuf(string&), where the
// string in question contains embedded NUL characters. Note that in this
// embedded-NUL situation, the size must be passed to the string ctor.
std::string str_nulls ("eschew \0 obfuscation", 20); // tested in 21_strings
std::stringbuf strb_normal (str_01);
std::stringbuf strb_nulls (str_nulls);
strb_normal.str(str_nulls); // tried using 'strb_01' rather than declaring
// another variable, but then test04 broke!
VERIFY( strb_nulls.in_avail() == str_nulls.size() );
VERIFY( strb_nulls.str().size() == 20 );
VERIFY( strb_normal.in_avail() == str_nulls.size() );
#ifdef DEBUG_ASSERT
assert(test);
#endif
return test;
}
// test overloaded virtual functions
bool test04() {
bool test = true;
std::string str_tmp;
std::stringbuf strb_tmp;
std::streamsize strmsz_1, strmsz_2;
std::streamoff strmof_1(-1), strmof_2;
typedef std::stringbuf::int_type int_type;
typedef std::stringbuf::traits_type traits_type;
typedef std::stringbuf::pos_type pos_type;
typedef std::stringbuf::off_type off_type;
// GET
// int in_avail()
strmof_1 = strb_01.in_avail();
strmof_2 = strb_02.in_avail();
VERIFY( strmof_1 != strmof_2 );
VERIFY( strmof_1 == str_01.length() );
VERIFY( strmof_2 == str_02.length() );
strmof_1 = strb_03.in_avail();
VERIFY( strmof_1 == 0 ); // zero cuz write-only, or eof()? zero, from showmany
// int_type sbumpc()
// if read_cur not avail, return uflow(), else return *read_cur & increment
int_type c1 = strb_01.sbumpc();
int_type c2 = strb_02.sbumpc();
VERIFY( c1 != c2 );
VERIFY( c1 == str_01[0] );
VERIFY( c2 == str_02[0] ); //should equal first letter at this point
int_type c3 = strb_01.sbumpc();
int_type c4 = strb_02.sbumpc();
VERIFY( c1 != c2 );
VERIFY( c1 != c3 );
VERIFY( c2 != c4 );
int_type c5 = strb_03.sbumpc();
VERIFY( c5 == traits_type::eof() );
// int_type sgetc()
// if read_cur not avail, return uflow(), else return *read_cur
int_type c6 = strb_01.sgetc();
int_type c7 = strb_02.sgetc();
VERIFY( c6 != c3 );
VERIFY( c7 != c4 );
int_type c8 = strb_01.sgetc();
int_type c9 = strb_02.sgetc();
VERIFY( c6 == c8 );
VERIFY( c7 == c9 );
c5 = strb_03.sgetc();
VERIFY( c5 == traits_type::eof() );
// int_type snextc()
// calls sbumpc and if sbumpc != eof, return sgetc
c6 = strb_01.snextc();
c7 = strb_02.snextc();
VERIFY( c6 != c8 );
VERIFY( c7 != c9 );
VERIFY( c6 == str_01[3] );
VERIFY( c7 == str_02[3] ); //should equal fourth letter at this point
c5 = strb_03.snextc();
VERIFY( c5 == traits_type::eof() );
// int showmanyc
// streamsize sgetn(char_type *s, streamsize n)
// streamsize xsgetn(char_type *s, streamsize n)
// assign up to n chars to s from input sequence, indexing in_cur as
// approp and returning the number of chars assigned
strmsz_1 = strb_01.in_avail();
strmsz_2 = strb_02.in_avail();
test = strmsz_1 != strmsz_2;
VERIFY( strmsz_1 != str_01.length() );
VERIFY( strmsz_2 != str_02.length() ); //because now we've moved into string
char carray1[11] = "";
strmsz_1 = strb_01.sgetn(carray1, 10);
char carray2[20] = "";
strmsz_2 = strb_02.sgetn(carray2, 10);
VERIFY( strmsz_1 == strmsz_2 );
VERIFY( strmsz_1 == 10 );
c1 = strb_01.sgetc();
c2 = strb_02.sgetc();
VERIFY( c6 == c1 ); //just by co-incidence both o's
VERIFY( c7 != c2 ); // n != i
VERIFY( c1 == str_01[13] );
VERIFY( c2 == str_02[13] ); //should equal fourteenth letter at this point
strmsz_1 = strb_03.sgetn(carray1, 10);
VERIFY( !strmsz_1 ); //zero
strmsz_1 = strb_02.in_avail();
strmsz_2 = strb_02.sgetn(carray2, strmsz_1 + 5);
VERIFY( strmsz_1 == strmsz_2 ); //write off the end
c4 = strb_02.sgetc(); // should be EOF
VERIFY( c4 == traits_type::eof() );
// PUT
// int_type sputc(char_type c)
// if out_cur not avail, return overflow. Else, stores c at out_cur,
// increments out_cur, and returns c as int_type
strb_03.str(str_01); //reset
std::string::size_type sz1 = strb_03.str().length();
c1 = strb_03.sputc('a');
std::string::size_type sz2 = strb_03.str().length();
VERIFY( sz1 == sz2 ); //cuz inserting at out_cur, which is at beg to start
c2 = strb_03.sputc('b');
VERIFY( c1 != c2 );
VERIFY( strb_03.str() != str_01 );
c3 = strb_02.sputc('a'); // should be EOF because this is read-only
VERIFY( c3 == traits_type::eof() );
// streamsize sputn(const char_typs* s, streamsize n)
// write up to n chars to out_cur from s, returning number assigned
// NB *sputn will happily put '\0' into your stream if you give it a chance*
str_tmp = strb_03.str();
sz1 = str_tmp.length();
strmsz_1 = strb_03.sputn("racadabras", 10);//"abracadabras or what?"
sz2 = strb_03.str().length();
VERIFY( sz1 == sz2 ); //shouldn't have changed length
VERIFY( strmsz_1 == 10 );
VERIFY( str_tmp != strb_03.str() );
strmsz_2 = strb_03.sputn(", i wanna reach out and", 10);
VERIFY( strmsz_1 == strmsz_2 ); // should re-allocate, copy 10 chars.
VERIFY( strmsz_1 == 10 );
VERIFY( strmsz_2 == 10 );
sz2 = strb_03.str().length();
VERIFY( sz1 != sz2 ); // need to change length
VERIFY( str_tmp != strb_03.str() );
str_tmp = strb_02.str();
strmsz_1 = strb_02.sputn("racadabra", 10);
VERIFY( strmsz_1 == 0 );
VERIFY( str_tmp == strb_02.str() );
// PUTBACK
// int_type pbfail(int_type c)
// called when gptr() null, gptr() == eback(), or traits::eq(*gptr, c) false
// "pending sequence" is:
// 1) everything as defined in underflow
// 2) + if (traits::eq_int_type(c, traits::eof()), then input
// sequence is backed up one char before the pending sequence is
// determined.
// 3) + if (not 2) then c is prepended. Left unspecified is
// whether the input sequence is backedup or modified in any way
// returns traits::eof() for failure, unspecified other value for success
// int_type sputbackc(char_type c)
// if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
// otherwise decrements in_cur and returns *gptr()
strmsz_1 = strb_01.in_avail();
str_tmp = strb_01.str();
c1 = strb_01.sgetc(); //"mykonos. . . 'o'r what?"
c2 = strb_01.sputbackc('z');//"mykonos. . .zor what?"
c3 = strb_01.sgetc();
VERIFY( c1 != c2 );
VERIFY( c3 == c2 );
VERIFY( strb_01.str() == std::string("mykonos. . .zor what?") );
VERIFY( str_tmp.size() == strb_01.str().size() );
//test for _in_cur == _in_beg
strb_01.str(str_tmp);
strmsz_1 = strb_01.in_avail();
c1 = strb_01.sgetc(); //"'m'ykonos. . . or what?"
c2 = strb_01.sputbackc('z');//"mykonos. . . or what?"
c3 = strb_01.sgetc();
VERIFY( c1 != c2 );
VERIFY( c3 != c2 );
VERIFY( c1 == c3 );
VERIFY( c2 == traits_type::eof() );
VERIFY( strb_01.str() == str_tmp );
VERIFY( str_tmp.size() == strb_01.str().size() );
// test for replacing char with identical one
strb_01.str(str_01); //reset
strmsz_1 = strb_01.in_avail();
strb_01.sbumpc();
strb_01.sbumpc();
c1 = strb_01.sgetc(); //"my'k'onos. . . or what?"
c2 = strb_01.sputbackc('y');//"mykonos. . . or what?"
c3 = strb_01.sgetc();
VERIFY( c1 != c2 );
VERIFY( c3 == c2 );
VERIFY( c1 != c3 );
VERIFY( strb_01.str() == str_01 );
VERIFY( str_01.size() == strb_01.str().size() );
//test for ios_base::out
strmsz_2 = strb_03.in_avail();
c4 = strb_03.sputbackc('x');
VERIFY( c4 == traits_type::eof() );
// int_type sungetc()
// if in_cur not avail, return pbackfail(), else decrement and
// return to_int_type(*gptr())
for (int i = 0; i<12; ++i)
strb_01.sbumpc();
strmsz_1 = strb_01.in_avail();
str_tmp = strb_01.str();
c1 = strb_01.sgetc(); //"mykonos. . . 'o'r what?"
c2 = strb_01.sungetc();//"mykonos. . . or what?"
c3 = strb_01.sgetc();
VERIFY( c1 != c2 );
VERIFY( c3 == c2 );
VERIFY( c1 != c3 );
VERIFY( c2 == ' ' );
VERIFY( strb_01.str() == str_01 );
VERIFY( str_01.size() == strb_01.str().size() );
//test for _in_cur == _in_beg
strb_01.str(str_tmp);
strmsz_1 = strb_01.in_avail();
c1 = strb_01.sgetc(); //"'m'ykonos. . . or what?"
c2 = strb_01.sungetc();//"mykonos. . . or what?"
c3 = strb_01.sgetc();
VERIFY( c1 != c2 );
VERIFY( c3 != c2 );
VERIFY( c1 == c3 );
VERIFY( c2 == traits_type::eof() );
VERIFY( strb_01.str() == str_01 );
VERIFY( str_01.size() == strb_01.str().size() );
// test for replacing char with identical one
strb_01.str(str_01); //reset
strmsz_1 = strb_01.in_avail();
strb_01.sbumpc();
strb_01.sbumpc();
c1 = strb_01.sgetc(); //"my'k'onos. . . or what?"
c2 = strb_01.sungetc();//"mykonos. . . or what?"
c3 = strb_01.sgetc();
VERIFY( c1 != c2 );
VERIFY( c3 == c2 );
VERIFY( c1 != c3 );
VERIFY( strb_01.str() == str_01 );
VERIFY( str_01.size() == strb_01.str().size() );
//test for ios_base::out
strmsz_2 = strb_03.in_avail();
c4 = strb_03.sungetc();
VERIFY( c4 == traits_type::eof() );
// BUFFER MANAGEMENT & POSITIONING
// sync
// pubsync
strb_01.pubsync();
strb_02.pubsync();
strb_03.pubsync();
// setbuf
// pubsetbuf(char_type* s, streamsize n)
str_tmp = std::string("naaaah, go to cebu");
strb_01.pubsetbuf(const_cast<char*> (str_tmp.c_str()), str_tmp.size());
VERIFY( strb_01.str() == str_tmp );
strb_01.pubsetbuf(0,0);
VERIFY( strb_01.str() == str_tmp );
// seekoff
// pubseekoff(off_type off, ios_base::seekdir way, ios_base::openmode which)
// alters the stream position to off
pos_type pt_1(off_type(-1));
pos_type pt_2(off_type(0));
off_type off_1 = 0;
off_type off_2 = 0;
strb_01.str(str_01); //in|out ("mykonos. . . or what?");
strb_02.str(str_02); //in ("paris, or sainte-maxime?");
strb_03.str(str_03); //out ("")
//IN|OUT
//beg
pt_1 = strb_01.pubseekoff(2, std::ios_base::beg);
off_1 = pt_1;
VERIFY( off_1 >= 0 );
c1 = strb_01.snextc(); //current in pointer +1
VERIFY( c1 == 'o' );
c2 = strb_01.sputc('x'); //test current out pointer
str_tmp = std::string("myxonos. . . or what?");
VERIFY( strb_01.str() == str_tmp );
//cur
pt_1 = strb_01.pubseekoff(2, std::ios_base::cur);
off_1 = pt_1;
VERIFY( off_1 == -1 ); // can't seekoff for in and out + cur in sstreams
pt_1 = strb_01.pubseekoff(2, std::ios_base::cur, std::ios_base::in);
off_1 = pt_1;
pt_2 = strb_01.pubseekoff(2, std::ios_base::cur, std::ios_base::in);
off_2 = pt_2;
VERIFY( off_2 == off_1 + 2 );
c1 = strb_01.snextc(); //current in pointer + 1
VERIFY( c1 == ' ' );
c2 = strb_01.sputc('x'); //test current out pointer
str_tmp = std::string("myxxnos. . . or what?");
VERIFY( strb_01.str() == str_tmp );
//end
pt_2 = strb_01.pubseekoff(2, std::ios_base::end);
off_1 = pt_2;
VERIFY( off_1 == -1 ); // not a valid position
VERIFY( strb_01.str() == str_tmp );
// end part two (from the filebuf tests)
strb_01.pubseekoff(0, std::ios_base::end);
strmsz_1 = strb_01.in_avail(); // 0 cuz at the end
c1 = strb_01.sgetc();
c2 = strb_01.sungetc();
strmsz_2 = strb_01.in_avail(); // 1
c3 = strb_01.sgetc();
VERIFY( c1 != c2 );
VERIFY( strmsz_2 != strmsz_1 );
VERIFY( strmsz_2 == 1 );
// end part three
strmsz_1 = strb_01.str().size();
strmsz_2 = strb_01.sputn(" ravi shankar meets carlos santana in LoHa", 90);
strb_01.pubseekoff(0, std::ios_base::end);
strb_01.sputc('<');
str_tmp = strb_01.str();
VERIFY( str_tmp.size() == strmsz_1 + strmsz_2 + 1 );
// IN
// OUT
// seekpos
// pubseekpos(pos_type sp, ios_base::openmode)
// alters the stream position to sp
strb_01.str(str_01); //in|out ("mykonos. . . or what?");
strb_02.str(str_02); //in ("paris, or sainte-maxime?");
strb_03.str(str_03); //out ("")
//IN|OUT
//beg
pt_1 = strb_01.pubseekoff(2, std::ios_base::beg);
off_1 = pt_1;
VERIFY( off_1 >= 0 );
pt_1 = strb_01.pubseekoff(0, std::ios_base::cur, std::ios_base::out);
off_1 = pt_1;
c1 = strb_01.snextc(); //current in pointer +1
VERIFY( c1 == 'o' );
c2 = strb_01.sputc('x'); //test current out pointer
str_tmp = std::string("myxonos. . . or what?");
VERIFY( strb_01.str() == str_tmp );
strb_01.pubsync(); //resets pointers
pt_2 = strb_01.pubseekpos(pt_1, std::ios_base::in|std::ios_base::out);
off_2 = pt_2;
VERIFY( off_1 == off_2 );
c3 = strb_01.snextc(); //current in pointer +1
VERIFY( c1 == c3 );
c2 = strb_01.sputc('x'); //test current out pointer
str_tmp = std::string("myxonos. . . or what?");
VERIFY( strb_01.str() == str_tmp );
// VIRTUALS (indirectly tested)
// underflow
// if read position avail, returns *gptr()
// pbackfail(int_type c)
// put c back into input sequence
// overflow
// appends c to output seq
#ifdef DEBUG_ASSERT
assert(test);
#endif
return test;
}
// libstdc++/3955 -- ios_base::app overwrites from the beginning
bool test05()
// libstdc++/7216
void test01()
{
bool test = true;
std::ostringstream os ("foo");
os << "bar";
test = os.str() == "bar";
#ifdef DEBUG_ASSERT
assert(test);
#endif
return test;
// Check for required typedefs
typedef std::stringbuf test_type;
typedef test_type::char_type char_type;
typedef test_type::traits_type traits_type;
typedef test_type::int_type int_type;
typedef test_type::pos_type pos_type;
typedef test_type::off_type off_type;
}
bool test06()
namespace test
{
bool test = true;
using namespace std;
typedef short type_t;
template class basic_stringbuf<type_t, char_traits<type_t> >;
} // test
std::ostringstream os ("foo", std::ios_base::app);
os << "bar";
test = os.str() == "foobar";
#ifdef DEBUG_ASSERT
assert(test);
#endif
return test;
}
int main()
int main()
{
test01();
test02();
test03();
test04();
test05();
test06();
return 0;
}
// more candy!!!

View File

@ -1,7 +1,6 @@
// 981015 bkoz
// i,o,stringstream usage
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
// Copyright (C) 2002 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
@ -28,133 +27,34 @@
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
#include <vector>
#include <string>
// 27.7.4 - Template class basic_stringstream
// NB: This file is for testing basic_stringstream with NO OTHER INCLUDES.
#include <sstream>
#include <testsuite_hooks.h>
// 01: sanity checks for strings, stringbufs
std::string
test01()
// { dg-do compile }
// libstdc++/7216
void test01()
{
bool test = false;
// Empty string sanity check.
std::string str01;
std::string::iterator __i_start = str01.begin();
std::string::iterator __i_end = str01.end();
std::string::size_type len = str01.size();
test = __i_start == __i_end;
VERIFY( len == 0 );
// Full string sanity check.
std::string str02("these golden days, i spend waiting for you:\n"
"Betty Carter on Verve with I'm Yours and You're Mine.");
__i_start = str02.begin();
__i_end = str02.end();
len = str02.size();
VERIFY( __i_start != __i_end );
VERIFY( len != 0 );
// Test an empty ostring stream for sanity.
std::ostringstream ostrstream0;
std::string str03 = ostrstream0.str();
__i_start = str03.begin();
__i_end = str03.end();
len = str03.size();
VERIFY( __i_start == __i_end );
VERIFY( len == 0 );
VERIFY( str01 == str03 );
return str02;
// Check for required typedefs
typedef std::stringstream test_type;
typedef test_type::char_type char_type;
typedef test_type::traits_type traits_type;
typedef test_type::int_type int_type;
typedef test_type::pos_type pos_type;
typedef test_type::off_type off_type;
}
int
test02()
namespace test
{
bool test = true;
using namespace std;
typedef short type_t;
template class basic_stringstream<type_t, char_traits<type_t> >;
} // test
//
// 1: Automatic formatting of a compound string
//
int i = 1024;
int *pi = &i;
double d = 3.14159;
double *pd = &d;
std::string blank;
std::ostringstream ostrst01;
std::ostringstream ostrst02(blank);
// No buffer,so should be created.
ostrst01 << "i: " << i << " i's address: " << pi << "\n"
<< "d: " << d << " d's address: " << pd << std::endl;
// Buffer, so existing buffer should be overwritten.
ostrst02 << "i: " << i << " i's address: " << pi << "\n"
<< "d: " << d << " d's address: " << pd << std::endl;
std::string msg01 = ostrst01.str();
std::string msg02 = ostrst02.str();
VERIFY( msg01 == msg02 );
VERIFY( msg02 != blank );
//
// 2: istringstream
//
// extracts the stored ascii values, placing them in turn in the four vars
#if 0
int i2 = 0;
int *pi2 = &i2;
double d2 = 0.0;
double *pd2 = &d2;
std::istringstream istrst01(ostrst02.str());
istrst01 >> i2 >> pi2 >> d2 >> pd2;
//istrst01 >> i2;
//istrst01 >> pi2;
VERIFY( i2 == i );
VERIFY( d2 == d );
VERIFY( pd2 == pd );
VERIFY( pi2 == pi );
#endif
// stringstream
std::string str1("");
std::string str3("this is a somewhat string");
std::stringstream ss1(str1, std::ios_base::in|std::ios_base::out);
std::stringstream ss2(str3, std::ios_base::in|std::ios_base::out);
return 0;
}
// user-reported error
class derived_oss: public std::ostringstream
{
public:
derived_oss() : std::ostringstream() {}
};
int
test03()
{
bool test = true;
derived_oss yy;
yy << "buena vista social club\n";
VERIFY( yy.str() == std::string("buena vista social club\n") );
#ifdef DEBUG_ASSERT
assert(test);
#endif
return 0;
}
int
main()
int main()
{
test01();
test02();
test03();
return 0;
}

View File

@ -1,6 +1,6 @@
// 2001-05-24 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 Free Software Foundation, Inc.
// Copyright (C) 2001, 2002 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
@ -120,12 +120,67 @@ void test02()
// These semantics are a joke, a serious defect, and incredibly lame.
}
void
test03()
{
bool test = true;
//
// 1: Automatic formatting of a compound string
//
int i = 1024;
int *pi = &i;
double d = 3.14159;
double *pd = &d;
std::string blank;
std::ostringstream ostrst01;
std::ostringstream ostrst02(blank);
// No buffer, so should be created.
ostrst01 << "i: " << i << " i's address: " << pi << "\n"
<< "d: " << d << " d's address: " << pd << std::endl;
// Buffer, so existing buffer should be overwritten.
ostrst02 << "i: " << i << " i's address: " << pi << "\n"
<< "d: " << d << " d's address: " << pd << std::endl;
std::string msg01 = ostrst01.str();
std::string msg02 = ostrst02.str();
VERIFY( msg01 == msg02 );
VERIFY( msg02 != blank );
//
// 2: istringstream
//
// extracts the stored ascii values, placing them in turn in the four vars
#if 0
int i2 = 0;
//int* pi2 = &i2;
void* pi2 = &i2;
double d2 = 0.0;
// double* pd2 = &d2;
void* pd2 = &d2;
std::istringstream istrst01(ostrst02.str());
istrst01 >> i2 >> pi2 >> d2 >> pd2;
//istrst01 >> i2;
//istrst01 >> pi2;
VERIFY( i2 == i );
VERIFY( d2 == d );
VERIFY( pd2 == pd );
VERIFY( pi2 == pi );
#endif
// stringstream
std::string str1("");
std::string str3("this is a somewhat string");
std::stringstream ss1(str1, std::ios_base::in|std::ios_base::out);
std::stringstream ss2(str3, std::ios_base::in|std::ios_base::out);
}
int main()
{
test01();
test02();
test03();
return 0;
}