+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.
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))
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;
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);
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
+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.
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)))
{
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);
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,
#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]
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));
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 */
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;
/* 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
{
/* 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))
{
/* 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).
#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));
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));
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;
\f
+
+/* 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 ()
{
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
/* 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
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)
&& 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;
}
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
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
{
tree init = NULL_TREE;
tree name_decl;
+ tree vtable_ptr;
{
tree name_name;
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);
}
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));
}
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;
}
}
-/* 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))
- {
- 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))
+ if (TYPE_PTRMEMFUNC_P (type))
+ return ptm_initializer (var_desc, type, non_public_p);
+ else if (var_desc == class_desc_type_node)
{
- 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. */
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));
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
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
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;
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);
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;
- }
- desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
-
- if (desc)
- return desc;
+ 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);
-
- 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;
+ /* 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;
+ }
}
/* Make sure the required builtin types exist for generating the type_info
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. */
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,
{
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",
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,
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);
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;
-
- 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);
+ 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;
- if (!DECL_NEEDED_P (tinfo_decl))
+ import_export_tinfo (decl, type, in_library);
+ if (DECL_REALLY_EXTERN (decl) || !DECL_NEEDED_P (decl))
return 0;
- /* Say we've dealt with it. */
- TREE_TYPE (DECL_NAME (tinfo_decl)) = NULL_TREE;
+
+ 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);
- create_tinfo_types ();
- decl = synthesize_tinfo_var (tinfo_type, DECL_ASSEMBLER_NAME (tinfo_decl));
+ 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. */
- return decl != 0;
+ /* Say we've dealt with it. */
+ TREE_TYPE (DECL_NAME (decl)) = NULL_TREE;
+
+ return 1;
}
+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.
+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.
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 = '.';
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 = '.';
#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'.';
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'.';
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)
{
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)
{
#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)
{
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);
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)
{
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);
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);
}
}
PACKAGE=libstdc++
# For libtool versioning info, format is CURRENT:REVISION:AGE
-libtool_VERSION=4:1:0
+libtool_VERSION=5:0:0
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
// 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;
{
_M_gcount = 0;
sentry __cerb(*this, true);
- if (__cerb)
+ if (__cerb && __n > 0)
{
try
{
{ _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
// 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>
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<>
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>
__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);
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) {
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
}
};
+// 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)
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; }
};
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,
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>
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;
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;
__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();
}
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;
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.
// 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;
{
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;
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;
{
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
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
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)
{ }
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)
{
// 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++"
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);
}
_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));
_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));
#include <stdexcept>
#include <testsuite_hooks.h>
-
void test00()
{
// Should be able to do this as the first thing that happens in a
}
#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();
test01();
#endif
+ test02();
+
return 0;
}
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)
{
failures += wrong_stuff();
+ failures += test6642();
+
#ifdef DEBUG_ASSERT
assert (failures == 0);
#endif
// 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.
int main()
{
+ test01();
return 0;
}
#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;
int main()
{
+ test01();
return 0;
}
// { 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;
int main()
{
+ test01();
return 0;
}
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()
{
test07();
test08();
test09();
+ test10();
return 0;
}
// { 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;
int main()
{
+ test01();
return 0;
}
// 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
// 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;
}
-// 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
// 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
-}
-
-void test02()
-{
- 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
+ // 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;
}
-
-// 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()
+namespace test
{
- 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;
}
-// 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
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
-#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);
-
-
-// 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
+// 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.
- // 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() );
+// 27.7.1 - Template class basic_stringbuf
+// NB: This file is for testing basic_stringbuf with NO OTHER INCLUDES.
- // 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;
-}
+#include <sstream>
+// { dg-do compile }
-// 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;
-
- std::ostringstream os ("foo", std::ios_base::app);
- os << "bar";
-
- test = os.str() == "foobar";
-
-#ifdef DEBUG_ASSERT
- assert(test);
-#endif
+ using namespace std;
+ typedef short type_t;
+ template class basic_stringbuf<type_t, char_traits<type_t> >;
+} // test
- return test;
-}
-
-int main()
+int main()
{
test01();
- test02();
- test03();
- test04();
- test05();
- test06();
-
return 0;
}
-
-
-
-// more candy!!!
-// 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
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
-#include <vector>
-#include <string>
-#include <sstream>
-#include <testsuite_hooks.h>
-
-// 01: sanity checks for strings, stringbufs
-std::string
-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 );
+// 27.7.4 - Template class basic_stringstream
+// NB: This file is for testing basic_stringstream with NO OTHER INCLUDES.
- return str02;
-}
+#include <sstream>
+// { dg-do compile }
-int
-test02()
+// libstdc++/7216
+void test01()
{
- 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;
- 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;
+ // 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;
}
-// user-reported error
-class derived_oss: public std::ostringstream
-{
-public:
- derived_oss() : std::ostringstream() {}
-};
-
-int
-test03()
+namespace test
{
- 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;
-}
+ using namespace std;
+ typedef short type_t;
+ template class basic_stringstream<type_t, char_traits<type_t> >;
+} // test
-int
-main()
+int main()
{
test01();
- test02();
- test03();
-
return 0;
}
// 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
// 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;
}
-
-
-