From: Jakub Jelinek Date: Fri, 26 Jul 2002 23:23:45 +0000 (+0200) Subject: re PR rtl-optimization/7291 (off-by-one in generated inline bzero code for i386 ... X-Git-Tag: releases/gcc-3.2.0~49 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a7580e63a7099fb93f8169ca97c1bb5ee68a0bd7;p=thirdparty%2Fgcc.git re PR rtl-optimization/7291 (off-by-one in generated inline bzero code for i386 (64bit)) gcc/ChangeLog 2002-07-24 Frank van der Linden PR optimization/7291 * config/i386/i386.c (ix86_expand_clrstr): Fix bzero alignment problem on x86_64. 2002-05-16 Jason Merrill * config/mips/mips.c (mips_output_external): Don't do sdata optimization for a variable with DECL_COMDAT set. 2002-01-03 Jakub Jelinek * c-decl.c (build_compound_literal): Set decl TREE_READONLY from TYPE. * c-decl.c (build_compound_literal): Defer compound literal decls until until file end to emit them only if they are actually used. gcc/cp/ChangeLog 2002-07-17 Scott Snyder PR c++/7320 * rtti.c (get_tinfo_decl): Set DECL_COMDAT. 2002-07-05 Nathan Sidwell 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 * 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 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 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 * rtti.c (get_tinfo_decl): Don't call comdat_linkage. Do set DECL_COMDAT. (synthesize_tinfo_var): Take the public decl. (create_real_tinfo_var): Likewise. Check DECL_COMDAT. (emit_tinfo_decl): Adjust. Call import_export_decl. * decl2.c (import_export_decl): Simplify tinfo decl handling. gcc/testsuite/ChangeLog 2002-07-24 Roger Sayle * gcc.c-torture/execute/memset-3.c: New testcase. 2002-06-14 Jason Merrill * 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 * g++.dg/abi/rtti1.C: New test. 2002-01-03 Jakub Jelinek * gcc.dg/gnu89-init-2.c: New test. libstdc++-v3/ChangeLog 2002-07-26 Phil Edwards * libsupc++/new (placement delete): Remove unused paramater names. 2002-07-25 Benjamin Kosnik 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 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 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 PR libstdc++/7286 * libsupc++/new: Add placement delete. * testsuite/18_support/new_delete_placement.cc: New. 2002-07-07 Paolo Carlini 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 Jack Reeves * 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 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 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 * configure.in (libtool_VERSION): Bump to 5:0:0. * configure: Regenerate. 2002-05-19 Paolo Carlini * testsuite/23_containers/deque_operators.cc (test01): Fix minor typo in last commit. 2002-05-18 Paolo Carlini PR libstdc++/6503 * include/bits/stl_deque.h (_Deque_iterator::operator==, operator!=, operator<, operator>, operator>=, operator<=): Make non-member functions, to allow comparing const and non-const iterators in any order. * testsuite/23_containers/deque_operators.cc: New testfile. From-SVN: r55786 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d083356e321d..97bd68527f51 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2002-07-24 Frank van der Linden + + PR optimization/7291 + * config/i386/i386.c (ix86_expand_clrstr): Fix bzero alignment + problem on x86_64. + +2002-05-16 Jason Merrill + + * config/mips/mips.c (mips_output_external): Don't do sdata + optimization for a variable with DECL_COMDAT set. + +2002-01-03 Jakub Jelinek + + * 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. diff --git a/gcc/c-decl.c b/gcc/c-decl.c index a851ed993600..a6e010bafe0f 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -3911,6 +3911,7 @@ build_compound_literal (type, init) DECL_CONTEXT (decl) = current_function_decl; TREE_USED (decl) = 1; TREE_TYPE (decl) = type; + TREE_READONLY (decl) = TREE_READONLY (type); store_init_value (decl, init); if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type)) @@ -3933,12 +3934,18 @@ build_compound_literal (type, init) if (TREE_STATIC (decl)) { /* This decl needs a name for the assembler output. We also need - a unique suffix to be added to the name, for which DECL_CONTEXT - must be set. */ - DECL_NAME (decl) = get_identifier ("__compound_literal"); - DECL_CONTEXT (decl) = complit; + a unique suffix to be added to the name. */ + char *name; + extern int var_labelno; + + ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal", var_labelno); + var_labelno++; + DECL_NAME (decl) = get_identifier (name); + DECL_DEFER_OUTPUT (decl) = 1; + DECL_COMDAT (decl) = 1; + DECL_ARTIFICIAL (decl) = 1; + pushdecl (decl); rest_of_decl_compilation (decl, NULL, 1, 0); - DECL_CONTEXT (decl) = NULL_TREE; } return complit; diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index a34831ed4c74..274c9a0632a9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -9505,7 +9505,7 @@ ix86_expand_clrstr (src, count_exp, align_exp) gen_rtx_SUBREG (SImode, zeroreg, 0))); if (TARGET_64BIT && (align <= 4 || count == 0)) { - rtx label = ix86_expand_aligntest (countreg, 2); + rtx label = ix86_expand_aligntest (countreg, 4); emit_insn (gen_strsetsi (destreg, gen_rtx_SUBREG (SImode, zeroreg, 0))); emit_label (label); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index a230c9e32d16..4c8bfb916e79 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -5854,6 +5854,7 @@ mips_output_external (file, decl, name) if (TARGET_GP_OPT && TREE_CODE (decl) != FUNCTION_DECL + && !DECL_COMDAT (decl) && (len = int_size_in_bytes (TREE_TYPE (decl))) > 0 && ((section_name = DECL_SECTION_NAME (decl)) == NULL || strcmp (TREE_STRING_POINTER (section_name), ".sbss") == 0 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d45bb09540d2..a226d36d01fb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,72 @@ +2002-07-17 Scott Snyder + + PR c++/7320 + * rtti.c (get_tinfo_decl): Set DECL_COMDAT. + +2002-07-05 Nathan Sidwell + + 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 + + * 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 + + 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 + + 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 + + * 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. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 998eec04a7c5..036d7f72178b 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3830,6 +3830,8 @@ build_base_field (rli, binfo, empty_p, offsets, t) DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype); DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype); DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype); + /* Tell the backend not to round up to TYPE_ALIGN. */ + DECL_PACKED (decl) = 1; if (!integer_zerop (DECL_SIZE (decl))) { @@ -4971,6 +4973,12 @@ layout_class_type (t, empty_p, vfuns_p, CLASSTYPE_SIZE (t) = bitsize_zero_node; CLASSTYPE_SIZE_UNIT (t) = size_zero_node; } + /* If this is a POD, we can't reuse its tail padding. */ + else if (!CLASSTYPE_NON_POD_P (t)) + { + CLASSTYPE_SIZE (t) = TYPE_SIZE (t); + CLASSTYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (t); + } else { CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index bfc6e339bce0..6fe5875ada74 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -539,7 +539,7 @@ enum cp_tree_index CPTI_STD, CPTI_ABI, CPTI_TYPE_INFO_TYPE, - CPTI_TINFO_DECL_TYPE, + CPTI_TYPE_INFO_PTR_TYPE, CPTI_ABORT_FNDECL, CPTI_GLOBAL_DELETE_FNDECL, CPTI_AGGR_TAG, @@ -626,7 +626,7 @@ extern tree cp_global_trees[CPTI_MAX]; #define std_node cp_global_trees[CPTI_STD] #define abi_node cp_global_trees[CPTI_ABI] #define type_info_type_node cp_global_trees[CPTI_TYPE_INFO_TYPE] -#define tinfo_decl_type cp_global_trees[CPTI_TINFO_DECL_TYPE] +#define type_info_ptr_type cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE] #define abort_fndecl cp_global_trees[CPTI_ABORT_FNDECL] #define global_delete_fndecl cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL] #define current_aggr cp_global_trees[CPTI_AGGR_TAG] @@ -3819,6 +3819,7 @@ extern tree coerce_delete_type PARAMS ((tree)); extern void comdat_linkage PARAMS ((tree)); extern void import_export_vtable PARAMS ((tree, tree, int)); extern void import_export_decl PARAMS ((tree)); +extern void import_export_tinfo PARAMS ((tree, tree, int)); extern tree build_cleanup PARAMS ((tree)); extern void finish_file PARAMS ((void)); extern tree reparse_absdcl_as_expr PARAMS ((tree, tree)); @@ -4051,7 +4052,7 @@ extern tree get_tinfo_decl PARAMS((tree)); extern tree get_typeid PARAMS((tree)); extern tree build_dynamic_cast PARAMS((tree, tree)); extern void emit_support_tinfos PARAMS((void)); -extern int tinfo_decl_p PARAMS((tree, void *)); +extern int unemitted_tinfo_decl_p PARAMS((tree, void *)); extern int emit_tinfo_decl PARAMS((tree *, void *)); /* in search.c */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index c5ed336b6250..499ff73b9f59 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2529,48 +2529,53 @@ import_export_decl (decl) else comdat_linkage (decl); } - else if (tinfo_decl_p (decl, 0)) - { - tree ctype = TREE_TYPE (DECL_NAME (decl)); - - if (IS_AGGR_TYPE (ctype)) - import_export_class (ctype); - - if (IS_AGGR_TYPE (ctype) && CLASSTYPE_INTERFACE_KNOWN (ctype) - && TYPE_POLYMORPHIC_P (ctype) - /* If -fno-rtti, we're not necessarily emitting this stuff with - the class, so go ahead and emit it now. This can happen - when a class is used in exception handling. */ - && flag_rtti - /* If the type is a cv-qualified variant of a type, then we - must emit the tinfo function in this translation unit - since it will not be emitted when the vtable for the type - is output (which is when the unqualified version is - generated). */ - && same_type_p (ctype, TYPE_MAIN_VARIANT (ctype))) - { - DECL_NOT_REALLY_EXTERN (decl) - = ! (CLASSTYPE_INTERFACE_ONLY (ctype) - || (DECL_DECLARED_INLINE_P (decl) - && ! flag_implement_inlines - && !DECL_VINDEX (decl))); - - /* Always make artificials weak. */ - if (flag_weak) - comdat_linkage (decl); - } - else if (TYPE_BUILT_IN (ctype) - && same_type_p (ctype, TYPE_MAIN_VARIANT (ctype))) - DECL_NOT_REALLY_EXTERN (decl) = 0; - else - comdat_linkage (decl); - } else comdat_linkage (decl); DECL_INTERFACE_KNOWN (decl) = 1; } +/* Here, we only decide whether or not the tinfo node should be + emitted with the vtable. IS_IN_LIBRARY is non-zero iff the + typeinfo for TYPE should be in the runtime library. */ + +void +import_export_tinfo (decl, type, is_in_library) + tree decl; + tree type; + int is_in_library; +{ + if (DECL_INTERFACE_KNOWN (decl)) + return; + + if (IS_AGGR_TYPE (type)) + import_export_class (type); + + if (IS_AGGR_TYPE (type) && CLASSTYPE_INTERFACE_KNOWN (type) + && TYPE_POLYMORPHIC_P (type) + /* If -fno-rtti, we're not necessarily emitting this stuff with + the class, so go ahead and emit it now. This can happen when + a class is used in exception handling. */ + && flag_rtti) + { + DECL_NOT_REALLY_EXTERN (decl) = !CLASSTYPE_INTERFACE_ONLY (type); + DECL_COMDAT (decl) = 0; + } + else + { + DECL_NOT_REALLY_EXTERN (decl) = 1; + DECL_COMDAT (decl) = 1; + } + + /* Now override some cases. */ + if (flag_weak) + DECL_COMDAT (decl) = 1; + else if (is_in_library) + DECL_COMDAT (decl) = 0; + + DECL_INTERFACE_KNOWN (decl) = 1; +} + tree build_cleanup (decl) tree decl; @@ -3364,7 +3369,7 @@ finish_file () /* Write out needed type info variables. Writing out one variable might cause others to be needed. */ - if (walk_globals (tinfo_decl_p, emit_tinfo_decl, /*data=*/0)) + if (walk_globals (unemitted_tinfo_decl_p, emit_tinfo_decl, /*data=*/0)) reconsider = 1; /* The list of objects with static storage duration is built up diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 7bfbb4bc4605..ba312b709953 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -982,8 +982,17 @@ write_unqualified_name (decl) { /* Conversion operator. Handle it right here. ::= cv */ + 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)) { diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 8c9b1c14f7fd..ae23234ee66b 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -1,5 +1,5 @@ /* RunTime Type Identification - Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Mostly written by Jason Merrill (jason@cygnus.com). @@ -30,16 +30,46 @@ Boston, MA 02111-1307, USA. */ #include "assert.h" #include "toplev.h" +/* C++ returns type information to the user in struct type_info + objects. We also use type information to implement dynamic_cast and + exception handlers. Type information for a particular type is + indicated with an ABI defined structure derived from type_info. + This would all be very straight forward, but for the fact that the + runtime library provides the definitions of the type_info structure + and the ABI defined derived classes. We cannot build declarations + of them directly in the compiler, but we need to layout objects of + their type. Somewhere we have to lie. + + We define layout compatible POD-structs with compiler-defined names + and generate the appropriate initializations for them (complete + with explicit mention of their vtable). When we have to provide a + type_info to the user we reinterpret_cast the internal compiler + type to type_info. A well formed program can only explicitly refer + to the type_infos of complete types (& cv void). However, we chain + pointer type_infos to the pointed-to-type, and that can be + incomplete. We only need the addresses of such incomplete + type_info objects for static initialization. + + The type information VAR_DECL of a type is held on the + IDENTIFIER_GLOBAL_VALUE of the type's mangled name. That VAR_DECL + will be the internal type. It will usually have the correct + internal type reflecting the kind of type it represents (pointer, + array, function, class, inherited class, etc). When the type it + represents is incomplete, it will have the internal type + corresponding to type_info. That will only happen at the end of + translation, when we are emitting the type info objects. */ + /* Accessors for the type_info objects. We need to remember several things about each of the type_info types. The global tree nodes such as bltn_desc_type_node are TREE_LISTs, and these macros are used to access the required information. */ /* The RECORD_TYPE of a type_info derived class. */ #define TINFO_PSEUDO_TYPE(NODE) TREE_TYPE (NODE) -/* The VAR_DECL of the vtable for the type_info derived class. */ +/* The VAR_DECL of the vtable for the type_info derived class. + This is only filled in at the end of the translation. */ #define TINFO_VTABLE_DECL(NODE) TREE_VALUE (NODE) - -extern struct obstack permanent_obstack; +/* The IDENTIFIER_NODE naming the real class. */ +#define TINFO_REAL_NAME(NODE) TREE_PURPOSE (NODE) static tree build_headof PARAMS((tree)); static tree ifnonnull PARAMS((tree, tree)); @@ -48,7 +78,8 @@ static tree build_dynamic_cast_1 PARAMS((tree, tree)); static tree throw_bad_cast PARAMS((void)); static tree throw_bad_typeid PARAMS((void)); static tree get_tinfo_decl_dynamic PARAMS((tree)); -static bool typeid_ok_p PARAMS ((void)); +static tree get_tinfo_ptr PARAMS((tree)); +static bool typeid_ok_p PARAMS((void)); static int qualifier_flags PARAMS((tree)); static int target_incomplete_p PARAMS((tree)); static tree tinfo_base_init PARAMS((tree, tree)); @@ -59,15 +90,21 @@ static tree dfs_class_hint_mark PARAMS ((tree, void *)); static tree dfs_class_hint_unmark PARAMS ((tree, void *)); static int class_hint_flags PARAMS((tree)); static tree class_initializer PARAMS((tree, tree, tree)); -static tree synthesize_tinfo_var PARAMS((tree, tree)); -static tree create_real_tinfo_var PARAMS((tree, tree, tree, tree, int)); static tree create_pseudo_type_info PARAMS((const char *, int, ...)); -static tree get_vmi_pseudo_type_info PARAMS((int)); +static tree get_pseudo_ti_init PARAMS ((tree, tree, int *)); +static tree get_pseudo_ti_desc PARAMS((tree)); static void create_tinfo_types PARAMS((void)); static int typeinfo_in_lib_p PARAMS((tree)); static int doing_runtime = 0; + +/* Declare language defined type_info type and a pointer to const + type_info. This is incomplete here, and will be completed when + the user #includes . There are language defined + restrictions on what can be done until that is included. Create + the internal versions of the ABI types. */ + void init_rtti_processing () { @@ -75,8 +112,11 @@ init_rtti_processing () type_info_type_node = xref_tag (class_type_node, get_identifier ("type_info"), 1); pop_namespace (); - tinfo_decl_type = - build_qualified_type (type_info_type_node, TYPE_QUAL_CONST); + type_info_ptr_type = + build_pointer_type + (build_qualified_type (type_info_type_node, TYPE_QUAL_CONST)); + + create_tinfo_types (); } /* Given the expression EXP of type `class *', return the head of the @@ -183,13 +223,12 @@ get_tinfo_decl_dynamic (exp) /* The RTTI information is at index -1. */ index = integer_minus_one_node; t = build_vtbl_ref (exp, index); - TREE_TYPE (t) = build_pointer_type (tinfo_decl_type); + TREE_TYPE (t) = type_info_ptr_type; return t; } - /* otherwise return the type_info for the static type of the expr. */ - exp = get_tinfo_decl (TYPE_MAIN_VARIANT (type)); - return build_unary_op (ADDR_EXPR, exp, 0); + /* Otherwise return the type_info for the static type of the expr. */ + return get_tinfo_ptr (TYPE_MAIN_VARIANT (type)); } static bool @@ -263,9 +302,9 @@ tinfo_name (type) return name_string; } -/* Returns a decl for the type_info variable for TYPE. You must - arrange that the decl is mark_used, if actually use it --- decls in - vtables are only used if the vtable is output. */ +/* Return a VAR_DECL for the internal ABI defined type_info object for + TYPE. You must arrange that the decl is mark_used, if actually use + it --- decls in vtables are only used if the vtable is output. */ tree get_tinfo_decl (type) @@ -278,7 +317,7 @@ get_tinfo_decl (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) { error ("cannot create type information for type `%T' because its size is variable", - type); + type); return error_mark_node; } @@ -291,37 +330,45 @@ get_tinfo_decl (type) name = mangle_typeinfo_for_type (type); d = IDENTIFIER_GLOBAL_VALUE (name); - if (d) - /* OK */; - else + if (!d) { - /* The tinfo decl is the type_info object itself. We make all - tinfo objects look as type_info, even though they will end up - being a subclass of that when emitted. This means that we'll - erroneously think we know the dynamic type -- be careful in the - runtime. */ - d = build_lang_decl (VAR_DECL, name, tinfo_decl_type); + tree var_desc = get_pseudo_ti_desc (type); + + d = build_lang_decl (VAR_DECL, name, TINFO_PSEUDO_TYPE (var_desc)); DECL_ARTIFICIAL (d) = 1; - DECL_ALIGN (d) = TYPE_ALIGN (ptr_type_node); - DECL_USER_ALIGN (d) = 0; TREE_READONLY (d) = 1; TREE_STATIC (d) = 1; DECL_EXTERNAL (d) = 1; - TREE_PUBLIC (d) = 1; - if (flag_weak || !typeinfo_in_lib_p (type)) - comdat_linkage (d); SET_DECL_ASSEMBLER_NAME (d, name); + DECL_COMDAT (d) = 1; cp_finish_decl (d, NULL_TREE, NULL_TREE, 0); pushdecl_top_level (d); + /* Remember the type it is for. */ TREE_TYPE (name) = type; - TREE_USED (name) = 1; } + return d; } +/* Return a pointer to a type_info object describing TYPE, suitably + cast to the language defined type. */ + +static tree +get_tinfo_ptr (type) + tree type; +{ + tree exp = get_tinfo_decl (type); + + /* Convert to type_info type. */ + exp = build_unary_op (ADDR_EXPR, exp, 0); + exp = ocp_convert (type_info_ptr_type, exp, CONV_REINTERPRET, 0); + + return exp; +} + /* Return the type_info object for TYPE. */ tree @@ -350,7 +397,7 @@ get_typeid (type) if (!type) return error_mark_node; - return get_tinfo_decl (type); + return build_indirect_ref (get_tinfo_ptr (type), NULL); } /* Check whether TEST is null before returning RESULT. If TEST is used in @@ -683,6 +730,7 @@ tinfo_base_init (desc, target) { tree init = NULL_TREE; tree name_decl; + tree vtable_ptr; { tree name_name; @@ -710,12 +758,40 @@ tinfo_base_init (desc, target) cp_finish_decl (name_decl, name_string, NULL_TREE, 0); pushdecl_top_level (name_decl); } - - if (TINFO_VTABLE_DECL (desc)) + + vtable_ptr = TINFO_VTABLE_DECL (desc); + if (!vtable_ptr) { - tree vtbl_ptr = TINFO_VTABLE_DECL (desc); - init = tree_cons (NULL_TREE, vtbl_ptr, init); + tree real_type; + + push_nested_namespace (abi_node); + real_type = xref_tag (class_type_node, TINFO_REAL_NAME (desc), 1); + pop_nested_namespace (abi_node); + + if (!COMPLETE_TYPE_P (real_type)) + { + /* We never saw a definition of this type, so we need to + tell the compiler that this is an exported class, as + indeed all of the __*_type_info classes are. */ + SET_CLASSTYPE_INTERFACE_KNOWN (real_type); + CLASSTYPE_INTERFACE_ONLY (real_type) = 1; + } + + vtable_ptr = get_vtable_decl (real_type, /*complete=*/1); + vtable_ptr = build_unary_op (ADDR_EXPR, vtable_ptr, 0); + + /* We need to point into the middle of the vtable. */ + vtable_ptr = build + (PLUS_EXPR, TREE_TYPE (vtable_ptr), vtable_ptr, + size_binop (MULT_EXPR, + size_int (2), + TYPE_SIZE_UNIT (vtable_entry_type))); + TREE_CONSTANT (vtable_ptr) = 1; + + TINFO_VTABLE_DECL (desc) = vtable_ptr; } + + init = tree_cons (NULL_TREE, vtable_ptr, init); init = tree_cons (NULL_TREE, decay_conversion (name_decl), init); @@ -764,8 +840,7 @@ ptr_initializer (desc, target, non_public_ptr) } init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init); init = tree_cons (NULL_TREE, - build_unary_op (ADDR_EXPR, - get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0), + get_tinfo_ptr (TYPE_MAIN_VARIANT (to)), init); init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init)); @@ -802,12 +877,11 @@ ptm_initializer (desc, target, non_public_ptr) } init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init); init = tree_cons (NULL_TREE, - build_unary_op (ADDR_EXPR, - get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0), + get_tinfo_ptr (TYPE_MAIN_VARIANT (to)), init); init = tree_cons (NULL_TREE, - build_unary_op (ADDR_EXPR, get_tinfo_decl (klass), 0), - init); + get_tinfo_ptr (klass), + init); init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init)); TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1; @@ -928,77 +1002,63 @@ typeinfo_in_lib_p (type) } } -/* Generate a pseudo_type_info VAR_DECL suitable for the supplied - TARGET_TYPE and given the REAL_NAME. This is the structure expected by - the runtime, and therefore has additional fields. If we need not emit a - definition (because the runtime must contain it), return NULL_TREE, - otherwise return the VAR_DECL. */ +/* Generate the initializer for the type info describing + TYPE. VAR_DESC is a . NON_PUBLIC_P is set non-zero, if the VAR_DECL + should not be exported from this object file. This should only be + called at the end of translation, when we know that no further + types will be completed. */ static tree -synthesize_tinfo_var (target_type, real_name) - tree target_type; - tree real_name; +get_pseudo_ti_init (type, var_desc, non_public_p) + tree type; + tree var_desc; + int *non_public_p; { - tree var_init = NULL_TREE; - tree var_type = NULL_TREE; - int non_public = 0; - - switch (TREE_CODE (target_type)) + my_friendly_assert (at_eof, 20021120); + switch (TREE_CODE (type)) { case POINTER_TYPE: - if (TYPE_PTRMEM_P (target_type)) - { - var_type = ptm_desc_type_node; - var_init = ptm_initializer (var_type, target_type, &non_public); - } + if (TYPE_PTRMEM_P (type)) + return ptm_initializer (var_desc, type, non_public_p); else - { - if (typeinfo_in_lib_p (target_type) && !doing_runtime) - /* These are in the runtime. */ - return NULL_TREE; - var_type = ptr_desc_type_node; - var_init = ptr_initializer (var_type, target_type, &non_public); - } + return ptr_initializer (var_desc, type, non_public_p); break; case ENUMERAL_TYPE: - var_type = enum_desc_type_node; - var_init = generic_initializer (var_type, target_type); + return generic_initializer (var_desc, type); break; case FUNCTION_TYPE: - var_type = func_desc_type_node; - var_init = generic_initializer (var_type, target_type); + return generic_initializer (var_desc, type); break; case ARRAY_TYPE: - var_type = ary_desc_type_node; - var_init = generic_initializer (var_type, target_type); + return generic_initializer (var_desc, type); break; case UNION_TYPE: case RECORD_TYPE: - if (TYPE_PTRMEMFUNC_P (target_type)) - { - 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. */ @@ -1012,28 +1072,19 @@ synthesize_tinfo_var (target_type, real_name) if (TREE_PUBLIC (base_binfo)) flags |= 2; - tinfo = get_tinfo_decl (BINFO_TYPE (base_binfo)); - tinfo = build_unary_op (ADDR_EXPR, tinfo, 0); + tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo)); if (TREE_VIA_VIRTUAL (base_binfo)) { /* We store the vtable offset at which the virtual base offset can be found. */ - offset = BINFO_VPTR_FIELD (binfo_for_vbase (BINFO_TYPE (base_binfo), - target_type)); + offset = BINFO_VPTR_FIELD + (binfo_for_vbase (BINFO_TYPE (base_binfo), type)); offset = convert (sizetype, offset); flags |= 1; } else offset = BINFO_OFFSET (base_binfo); - /* is it a single public inheritance? */ - if (is_simple && flags == 2 && integer_zerop (offset)) - { - base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE); - break; - } - is_simple = 0; - /* combine offset and flags into one field */ offset = cp_build_binary_op (LSHIFT_EXPR, offset, build_int_2 (8, 0)); @@ -1044,86 +1095,23 @@ synthesize_tinfo_var (target_type, real_name) base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init); base_inits = tree_cons (NULL_TREE, base_init, base_inits); } - - if (is_simple) - var_type = si_class_desc_type_node; - else - { - int hint = class_hint_flags (target_type); - - base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits); - base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE); - /* Prepend the number of bases. */ - base_inits = tree_cons (NULL_TREE, - build_int_2 (nbases, 0), base_inits); - /* Prepend the hint flags. */ - base_inits = tree_cons (NULL_TREE, - build_int_2 (hint, 0), base_inits); - var_type = get_vmi_pseudo_type_info (nbases); - } - var_init = class_initializer (var_type, target_type, base_inits); + base_inits = build (CONSTRUCTOR, + NULL_TREE, NULL_TREE, base_inits); + base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE); + /* Prepend the number of bases. */ + base_inits = tree_cons (NULL_TREE, + build_int_2 (nbases, 0), base_inits); + /* Prepend the hint flags. */ + base_inits = tree_cons (NULL_TREE, + build_int_2 (hint, 0), base_inits); + + return class_initializer (var_desc, type, base_inits); } break; default: - if (typeinfo_in_lib_p (target_type)) - { - if (!doing_runtime) - /* These are guaranteed to be in the runtime. */ - return NULL_TREE; - var_type = bltn_desc_type_node; - var_init = generic_initializer (var_type, target_type); - break; - } - abort (); + return generic_initializer (var_desc, type); } - - return create_real_tinfo_var (target_type, - real_name, TINFO_PSEUDO_TYPE (var_type), - var_init, non_public); -} - -/* Create the real typeinfo variable. NON_PUBLIC indicates that we cannot - make this variable public (comdat). */ - -static tree -create_real_tinfo_var (target_type, name, type, init, non_public) - tree target_type; - tree name; - tree type; - tree init; - int non_public; -{ - static int count = 0; - tree decl; - tree hidden_name; - char hidden[30]; - - /* We cannot give this the name NAME, as that already is globally - bound to the tinfo_decl we originally created for this type in - get_tinfo_decl. */ - sprintf (hidden, "__ti_%d", count++); - hidden_name = get_identifier (hidden); - - decl = build_lang_decl (VAR_DECL, hidden_name, - build_qualified_type (type, TYPE_QUAL_CONST)); - DECL_ARTIFICIAL (decl) = 1; - TREE_READONLY (decl) = 1; - TREE_STATIC (decl) = 1; - DECL_EXTERNAL (decl) = 0; - - if (!non_public) - { - TREE_PUBLIC (decl) = 1; - if (flag_weak || !typeinfo_in_lib_p (target_type)) - comdat_linkage (decl); - } - SET_DECL_ASSEMBLER_NAME (decl, name); - DECL_INITIAL (decl) = init; - cp_finish_decl (decl, init, NULL_TREE, 0); - pushdecl_top_level (decl); - TREE_USED (decl) = 1; - return decl; } /* Generate the RECORD_TYPE containing the data layout of a type_info @@ -1132,7 +1120,10 @@ create_real_tinfo_var (target_type, name, type, init, non_public) type's vtable. We explicitly manage the vtable member, and name it for real type as used in the runtime. The RECORD type has a different name, to avoid collisions. Return a TREE_LIST who's TINFO_PSEUDO_TYPE - is the generated type and TINFO_VTABLE_DECL is the vtable decl. + is the generated type and TINFO_VTABLE_NAME is the name of the + vtable. We have to delay generating the VAR_DECL of the vtable + until the end of the translation, when we'll have seen the library + definition, if there was one. REAL_NAME is the runtime's name of the type. Trailing arguments are additional FIELD_DECL's for the structure. The final argument must be @@ -1141,9 +1132,8 @@ create_real_tinfo_var (target_type, name, type, init, non_public) static tree create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...)) { - tree real_type, pseudo_type; + tree pseudo_type; char *pseudo_name; - tree vtable_decl; int ix; tree fields[10]; tree field_decl; @@ -1160,29 +1150,6 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...)) if (ident) sprintf (pseudo_name + strlen (pseudo_name), "%d", ident); - /* Get the vtable decl. */ - real_type = xref_tag (class_type_node, get_identifier (real_name), 1); - if (! TYPE_SIZE (real_type)) - { - /* We never saw a definition of this type, so we need to tell the - compiler that this is an exported class, as indeed all of the - __*_type_info classes are. */ - SET_CLASSTYPE_INTERFACE_KNOWN (real_type); - CLASSTYPE_INTERFACE_ONLY (real_type) = 1; - } - - vtable_decl = get_vtable_decl (real_type, /*complete=*/1); - vtable_decl = build_unary_op (ADDR_EXPR, vtable_decl, 0); - - /* We need to point into the middle of the vtable. */ - vtable_decl = build (PLUS_EXPR, - TREE_TYPE (vtable_decl), - vtable_decl, - size_binop (MULT_EXPR, - size_int (2), - TYPE_SIZE_UNIT (vtable_entry_type))); - TREE_CONSTANT (vtable_decl) = 1; - /* First field is the pseudo type_info base class. */ fields[0] = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node); @@ -1196,53 +1163,96 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...)) TYPE_HAS_CONSTRUCTOR (pseudo_type) = 1; result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); - TINFO_VTABLE_DECL (result) = vtable_decl; - TINFO_PSEUDO_TYPE (result) = pseudo_type; + TINFO_REAL_NAME (result) = get_identifier (real_name); + TINFO_PSEUDO_TYPE (result) = + cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST); VA_CLOSE (ap); return result; } -/* Return a descriptor for a vmi type with NUM_BASES bases. */ +/* Return a pseudo type info type node used to describe TYPE. TYPE + must be a complete type (or cv void), except at the end of the + translation unit. */ static tree -get_vmi_pseudo_type_info (num_bases) - int num_bases; +get_pseudo_ti_desc (type) + tree type; { - tree desc; - tree array_domain, base_array; - - if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases) + switch (TREE_CODE (type)) { - int ix; - tree extend = make_tree_vec (num_bases + 5); - - for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;) - TREE_VEC_ELT (extend, ix) = TREE_VEC_ELT (vmi_class_desc_type_node, ix); - vmi_class_desc_type_node = extend; - } - 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 @@ -1251,15 +1261,9 @@ get_vmi_pseudo_type_info (num_bases) static void create_tinfo_types () { - tree ptr_type_info; - - if (bltn_desc_type_node) - return; - push_nested_namespace (abi_node); + my_friendly_assert (!ti_desc_type_node, 20020609); - ptr_type_info = build_pointer_type - (build_qualified_type - (type_info_type_node, TYPE_QUAL_CONST)); + push_nested_namespace (abi_node); /* Create the internal type_info structure. This is used as a base for the other structures. */ @@ -1299,7 +1303,7 @@ create_tinfo_types () This is really a descendant of __class_type_info. */ si_class_desc_type_node = create_pseudo_type_info ("__si_class_type_info", 0, - build_decl (FIELD_DECL, NULL_TREE, ptr_type_info), + build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type), NULL); /* Base class internal helper. Pointer to base type, offset to base, @@ -1307,7 +1311,7 @@ create_tinfo_types () { tree fields[2]; - fields[0] = build_decl (FIELD_DECL, NULL_TREE, ptr_type_info); + fields[0] = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type); fields[1] = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]); base_desc_type_node = make_aggr_type (RECORD_TYPE); finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo", @@ -1324,7 +1328,7 @@ create_tinfo_types () ptr_desc_type_node = create_pseudo_type_info ("__pointer_type_info", 0, build_decl (FIELD_DECL, NULL_TREE, integer_type_node), - build_decl (FIELD_DECL, NULL_TREE, ptr_type_info), + build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type), NULL); /* Pointer to member data type_info. Add qualifications flags, @@ -1333,8 +1337,8 @@ create_tinfo_types () ptm_desc_type_node = create_pseudo_type_info ("__pointer_to_member_type_info", 0, build_decl (FIELD_DECL, NULL_TREE, integer_type_node), - build_decl (FIELD_DECL, NULL_TREE, ptr_type_info), - build_decl (FIELD_DECL, NULL_TREE, ptr_type_info), + build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type), + build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type), NULL); pop_nested_namespace (abi_node); @@ -1401,75 +1405,61 @@ emit_support_tinfos () definition emitted for it. */ int -tinfo_decl_p (t, data) +unemitted_tinfo_decl_p (t, data) tree t; void *data ATTRIBUTE_UNUSED; { - return TREE_CODE (t) == VAR_DECL - && IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == (t) - && TREE_TYPE (t) == tinfo_decl_type - && TREE_TYPE (DECL_NAME (t)); + if (/* It's a var decl */ + TREE_CODE (t) == VAR_DECL + /* whos name points back to itself */ + && IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == t + /* whos name's type is non-null */ + && TREE_TYPE (DECL_NAME (t)) + /* and whos type is a struct */ + && TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE + /* with a first field of our pseudo type info */ + && TREE_TYPE (TYPE_FIELDS (TREE_TYPE (t))) == ti_desc_type_node) + return 1; + return 0; } -/* Emit a suitable type_info definition for the type_info decl pointed to by - DECL_PTR. We emit a completely new variable, of the correct type for the - actual type this is describing. The DECL_ASSEMBLER_NAME of the generated - definition is set to that of the supplied decl, so that they can be tied - up. Mark the supplied decl as having been dealt with. Emitting one - definition might cause other definitions to be required. - - We need to do things this way, because we're trying to do something like - - struct B : A { - ... - }; - - extern const A tinfo_var; - - const B tinfo_var = {...}; - - which is not permitted. Also, we've not necessarily seen the definition of B. - So we do something like the following, - - extern const A tinfo_var; - - struct pseudo_A { - const void *vtable_ptr; - const char *name; - }; - struct pseudo_B { - pseudo_A base; - ... - }; - - const pseudo_B proxy_tinfo_var attribute((assembler_name="tinfo_var")) = - { - {&B::vtable, "..."}, - ... - }; - - pseudo_A and pseudo_B must be layout equivalent to the real definitions in - the runtime. */ +/* Finish a type info decl. DECL_PTR is a pointer to an unemitted + tinfo decl. Determine whether it needs emitting, and if so + generate the initializer. */ int emit_tinfo_decl (decl_ptr, data) tree *decl_ptr; void *data ATTRIBUTE_UNUSED; { - tree tinfo_decl = *decl_ptr; - tree tinfo_type, decl; - - 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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7ba9393db787..1ad507e6b87f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,21 @@ +2002-07-24 Roger Sayle + + * gcc.c-torture/execute/memset-3.c: New testcase. + +2002-06-14 Jason Merrill + + * 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 + + * g++.dg/abi/rtti1.C: New test. + +2002-01-03 Jakub Jelinek + + * gcc.dg/gnu89-init-2.c: New test. + 2002-07-25 Release Manager * GCC 3.1.1 Released. diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 45bea70fcdbe..f1ac5ece41cf 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,112 @@ +2002-07-26 Phil Edwards + + * libsupc++/new (placement delete): Remove unused paramater names. + +2002-07-25 Benjamin Kosnik + + 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 + + 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 + + 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 + + PR libstdc++/7286 + * libsupc++/new: Add placement delete. + * testsuite/18_support/new_delete_placement.cc: New. + +2002-07-07 Paolo Carlini + + 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 + Jack Reeves + + * 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 + + 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 + + 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 + + * configure.in (libtool_VERSION): Bump to 5:0:0. + * configure: Regenerate. + +2002-05-19 Paolo Carlini + + * testsuite/23_containers/deque_operators.cc (test01): + Fix minor typo in last commit. + +2002-05-18 Paolo Carlini + + 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. diff --git a/libstdc++-v3/config/locale/generic/monetary_members.cc b/libstdc++-v3/config/locale/generic/monetary_members.cc index 7c2e13b62df9..1921f46e98cf 100644 --- a/libstdc++-v3/config/locale/generic/monetary_members.cc +++ b/libstdc++-v3/config/locale/generic/monetary_members.cc @@ -45,7 +45,7 @@ namespace std template<> void - moneypunct::_M_initialize_moneypunct(__c_locale) + moneypunct::_M_initialize_moneypunct(__c_locale, const char*) { // "C" locale _M_decimal_point = '.'; @@ -61,7 +61,7 @@ namespace std template<> void - moneypunct::_M_initialize_moneypunct(__c_locale) + moneypunct::_M_initialize_moneypunct(__c_locale, const char*) { // "C" locale _M_decimal_point = '.'; @@ -86,7 +86,8 @@ namespace std #ifdef _GLIBCPP_USE_WCHAR_T template<> void - moneypunct::_M_initialize_moneypunct(__c_locale) + moneypunct::_M_initialize_moneypunct(__c_locale, + const char*) { // "C" locale _M_decimal_point = L'.'; @@ -102,7 +103,8 @@ namespace std template<> void - moneypunct::_M_initialize_moneypunct(__c_locale) + moneypunct::_M_initialize_moneypunct(__c_locale, + const char*) { // "C" locale _M_decimal_point = L'.'; diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc index bf9b50cbb951..6a797ffbc25f 100644 --- a/libstdc++-v3/config/locale/gnu/monetary_members.cc +++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc @@ -216,7 +216,8 @@ namespace std template<> void - moneypunct::_M_initialize_moneypunct(__c_locale __cloc) + moneypunct::_M_initialize_moneypunct(__c_locale __cloc, + const char*) { if (__cloc == _S_c_locale) { @@ -260,7 +261,8 @@ namespace std template<> void - moneypunct::_M_initialize_moneypunct(__c_locale __cloc) + moneypunct::_M_initialize_moneypunct(__c_locale __cloc, + const char*) { if (__cloc == _S_c_locale) { @@ -313,7 +315,8 @@ namespace std #ifdef _GLIBCPP_USE_WCHAR_T template<> void - moneypunct::_M_initialize_moneypunct(__c_locale __cloc) + moneypunct::_M_initialize_moneypunct(__c_locale __cloc, + const char* __name) { if (__cloc == _S_c_locale) { @@ -331,6 +334,10 @@ namespace std else { // Named locale. + // XXX Fix me. Switch to named locale so that mbsrtowcs will work. + char* __old = strdup(setlocale(LC_ALL, NULL)); + setlocale(LC_ALL, __name); + _M_decimal_point = static_cast(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc)}).__w); _M_thousands_sep = static_cast(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc)}).__w); @@ -391,12 +398,17 @@ namespace std char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc)); char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc)); _M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn); + + // XXX + setlocale(LC_ALL, __old); + free(__old); } } template<> void - moneypunct::_M_initialize_moneypunct(__c_locale __cloc) + moneypunct::_M_initialize_moneypunct(__c_locale __cloc, + const char* __name) { if (__cloc == _S_c_locale) { @@ -414,6 +426,10 @@ namespace std else { // Named locale. + // XXX Fix me. Switch to named locale so that mbsrtowcs will work. + char* __old = strdup(setlocale(LC_ALL, NULL)); + setlocale(LC_ALL, __name); + _M_decimal_point = static_cast(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc)}).__w); _M_thousands_sep = static_cast(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc)}).__w); _M_grouping = __nl_langinfo_l(GROUPING, __cloc); @@ -473,6 +489,10 @@ namespace std char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc)); char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc)); _M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn); + + // XXX + setlocale(LC_ALL, __old); + free(__old); } } diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 553f21b6f5db..d2f0ca3164d7 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -599,7 +599,7 @@ ORIGINAL_LD_FOR_MULTILIBS=$LD PACKAGE=libstdc++ # For libtool versioning info, format is CURRENT:REVISION:AGE -libtool_VERSION=4:1:0 +libtool_VERSION=5:0:0 diff --git a/libstdc++-v3/configure.in b/libstdc++-v3/configure.in index eaa09cddaf11..9dbdf6e792c9 100644 --- a/libstdc++-v3/configure.in +++ b/libstdc++-v3/configure.in @@ -13,7 +13,7 @@ ORIGINAL_LD_FOR_MULTILIBS=$LD PACKAGE=libstdc++ AC_SUBST(PACKAGE) # For libtool versioning info, format is CURRENT:REVISION:AGE -libtool_VERSION=4:1:0 +libtool_VERSION=5:0:0 AC_SUBST(libtool_VERSION) GLIBCPP_TOPREL_CONFIGURE diff --git a/libstdc++-v3/include/bits/basic_ios.tcc b/libstdc++-v3/include/bits/basic_ios.tcc index 1e345dc21172..a38a95b58a0f 100644 --- a/libstdc++-v3/include/bits/basic_ios.tcc +++ b/libstdc++-v3/include/bits/basic_ios.tcc @@ -156,7 +156,7 @@ namespace std // unformatted input and output with non-required basic_ios // instantiations is possible even without imbuing the expected // ctype facet. - _M_fill = 0; + _M_fill = _CharT(); _M_fill_init = false; _M_exception = goodbit; diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc index 2658866ec578..fc0adea69e37 100644 --- a/libstdc++-v3/include/bits/istream.tcc +++ b/libstdc++-v3/include/bits/istream.tcc @@ -708,7 +708,7 @@ namespace std { _M_gcount = 0; sentry __cerb(*this, true); - if (__cerb) + if (__cerb && __n > 0) { try { diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h index d63eb5dd2d5f..241c4655dc28 100644 --- a/libstdc++-v3/include/bits/locale_facets.h +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -1357,8 +1357,9 @@ namespace std { _M_initialize_moneypunct(); } explicit - moneypunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs) - { _M_initialize_moneypunct(__cloc); } + moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0) + : locale::facet(__refs) + { _M_initialize_moneypunct(__cloc, __s); } char_type decimal_point() const @@ -1438,7 +1439,8 @@ namespace std // For use at construction time only. void - _M_initialize_moneypunct(__c_locale __cloc = _S_c_locale); + _M_initialize_moneypunct(__c_locale __cloc = _S_c_locale, + const char* __name = NULL); }; template @@ -1455,11 +1457,11 @@ namespace std template<> void - moneypunct::_M_initialize_moneypunct(__c_locale __cloc); + moneypunct::_M_initialize_moneypunct(__c_locale, const char*); template<> void - moneypunct::_M_initialize_moneypunct(__c_locale __cloc); + moneypunct::_M_initialize_moneypunct(__c_locale, const char*); #ifdef _GLIBCPP_USE_WCHAR_T template<> @@ -1470,11 +1472,13 @@ namespace std template<> void - moneypunct::_M_initialize_moneypunct(__c_locale __cloc); + moneypunct::_M_initialize_moneypunct(__c_locale, + const char*); template<> void - moneypunct::_M_initialize_moneypunct(__c_locale __cloc); + moneypunct::_M_initialize_moneypunct(__c_locale, + const char*); #endif template diff --git a/libstdc++-v3/include/bits/sstream.tcc b/libstdc++-v3/include/bits/sstream.tcc index e7419504d3e5..fd56347a7a4a 100644 --- a/libstdc++-v3/include/bits/sstream.tcc +++ b/libstdc++-v3/include/bits/sstream.tcc @@ -95,13 +95,13 @@ namespace std __len *= 2; if (__testwrite) - __ret = this->sputc(__c); + __ret = this->sputc(traits_type::to_char_type(__c)); else if (__len <= _M_string.max_size()) { // Force-allocate, re-sync. _M_string = this->str(); _M_string.reserve(__len); - _M_buf_size = static_cast(__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); diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index 5fa8d125e756..ce6be7e4ce2f 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -130,11 +130,6 @@ struct _Deque_iterator reference operator*() const { return *_M_cur; } pointer operator->() const { return _M_cur; } - difference_type operator-(const _Self& __x) const { - return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) + - (_M_cur - _M_first) + (__x._M_last - __x._M_cur); - } - _Self& operator++() { ++_M_cur; if (_M_cur == _M_last) { @@ -194,16 +189,6 @@ struct _Deque_iterator reference operator[](difference_type __n) const { return *(*this + __n); } - bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; } - bool operator!=(const _Self& __x) const { return !(*this == __x); } - bool operator<(const _Self& __x) const { - return (_M_node == __x._M_node) ? - (_M_cur < __x._M_cur) : (_M_node < __x._M_node); - } - bool operator>(const _Self& __x) const { return __x < *this; } - bool operator<=(const _Self& __x) const { return !(__x < *this); } - bool operator>=(const _Self& __x) const { return !(*this < __x); } - /** @if maint * Prepares to traverse new_node. Sets everything except _M_cur, which * should therefore be set by the caller immediately afterwards, based on @@ -217,6 +202,123 @@ struct _Deque_iterator } }; +// Note: we also provide overloads whose operands are of the same type in +// order to avoid ambiguos overload resolution when std::rel_ops operators +// are in scope (for additional details, see libstdc++/3628) +template +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 +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 +inline bool +operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) +{ + return !(__x == __y); +} + +template +inline bool +operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) +{ + return !(__x == __y); +} + +template +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 +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 +inline bool +operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) +{ + return __y < __x; +} + +template +inline bool +operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) +{ + return __y < __x; +} + +template +inline bool +operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) +{ + return !(__y < __x); +} + +template +inline bool +operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) +{ + return !(__y < __x); +} + +template +inline bool +operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) +{ + return !(__x < __y); +} + +template +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 +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 inline _Deque_iterator<_Tp, _Ref, _Ptr> operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index d8a6d8ca374a..6fb0d81339f0 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -629,10 +629,6 @@ namespace __gnu_cxx operator-(const difference_type& __n) const { return __normal_iterator(_M_current - __n); } - difference_type - operator-(const __normal_iterator& __i) const - { return _M_current - __i._M_current; } - const _Iterator& base() const { return _M_current; } }; @@ -719,6 +715,16 @@ namespace __gnu_cxx const __normal_iterator<_Iterator, _Container>& __rhs) { return __lhs.base() >= __rhs.base(); } + // _GLIBCPP_RESOLVE_LIB_DEFECTS + // According to the resolution of DR179 not only the various comparison + // operators but also operator- must accept mixed iterator/const_iterator + // parameters. + template + 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 inline __normal_iterator<_Iterator, _Container> operator+(typename __normal_iterator<_Iterator, _Container>::difference_type __n, diff --git a/libstdc++-v3/include/bits/streambuf.tcc b/libstdc++-v3/include/bits/streambuf.tcc index 292999cfba31..2f790e902cb7 100644 --- a/libstdc++-v3/include/bits/streambuf.tcc +++ b/libstdc++-v3/include/bits/streambuf.tcc @@ -40,7 +40,7 @@ namespace std { template - const typename basic_streambuf<_CharT, _Traits>::int_type + const size_t basic_streambuf<_CharT, _Traits>::_S_pback_size; template @@ -138,7 +138,7 @@ namespace std if (__ret < __n) { int_type __c = this->uflow(); - if (__c != traits_type::eof()) + if (!traits_type::eq_int_type(__c, traits_type::eof())) { traits_type::assign(*__s++, traits_type::to_char_type(__c)); ++__ret; @@ -177,7 +177,7 @@ namespace std if (__ret < __n) { int_type __c = this->overflow(traits_type::to_int_type(*__s)); - if (__c != traits_type::eof()) + if (!traits_type::eq_int_type(__c, traits_type::eof())) { ++__ret; ++__s; @@ -214,7 +214,7 @@ namespace std __sbin->_M_in_cur_move(__xtrct); if (__xtrct == __bufsize) { - if (__sbin->sgetc() == _Traits::eof()) + if (_Traits::eq_int_type(__sbin->sgetc(), _Traits::eof())) break; __bufsize = __sbin->in_avail(); } diff --git a/libstdc++-v3/include/std/std_istream.h b/libstdc++-v3/include/std/std_istream.h index 40f4b67fb9f7..8aa9123ed5c5 100644 --- a/libstdc++-v3/include/std/std_istream.h +++ b/libstdc++-v3/include/std/std_istream.h @@ -261,6 +261,16 @@ namespace std public basic_ostream<_CharT, _Traits> { public: +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS +// 271. basic_iostream missing typedefs + // Types (inherited): + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; +#endif + // Non-standard Types: typedef basic_istream<_CharT, _Traits> __istream_type; typedef basic_ostream<_CharT, _Traits> __ostream_type; diff --git a/libstdc++-v3/include/std/std_streambuf.h b/libstdc++-v3/include/std/std_streambuf.h index 012bf4e6cf6b..0270c181c126 100644 --- a/libstdc++-v3/include/std/std_streambuf.h +++ b/libstdc++-v3/include/std/std_streambuf.h @@ -91,10 +91,10 @@ namespace std char_type* _M_buf; // Actual size of allocated internal buffer, in bytes. - int_type _M_buf_size; + size_t _M_buf_size; // Optimal or preferred size of internal buffer, in bytes. - int_type _M_buf_size_opt; + size_t _M_buf_size_opt; // True iff _M_in_* and _M_out_* buffers should always point to // the same place. True for fstreams, false for sstreams. @@ -126,7 +126,7 @@ namespace std // requirements. The only basic_streambuf member function that // needs access to these data members is in_avail... // NB: pbacks of over one character are not currently supported. - static const int_type _S_pback_size = 1; + static const size_t _S_pback_size = 1; char_type _M_pback[_S_pback_size]; char_type* _M_pback_cur_save; char_type* _M_pback_end_save; @@ -140,8 +140,8 @@ namespace std { if (!_M_pback_init) { - int_type __dist = _M_in_end - _M_in_cur; - int_type __len = min(_S_pback_size, __dist); + size_t __dist = _M_in_end - _M_in_cur; + size_t __len = min(_S_pback_size, __dist); traits_type::copy(_M_pback, _M_in_cur, __len); _M_pback_cur_save = _M_in_cur; _M_pback_end_save = _M_in_end; @@ -159,12 +159,12 @@ namespace std if (_M_pback_init) { // Length _M_in_cur moved in the pback buffer. - int_type __off_cur = _M_in_cur - _M_pback; + size_t __off_cur = _M_in_cur - _M_pback; // For in | out buffers, the end can be pushed back... - int_type __off_end = 0; - int_type __pback_len = _M_in_end - _M_pback; - int_type __save_len = _M_pback_end_save - _M_buf; + size_t __off_end = 0; + size_t __pback_len = _M_in_end - _M_pback; + size_t __save_len = _M_pback_end_save - _M_buf; if (__pback_len > __save_len) __off_end = __pback_len - __save_len; @@ -288,8 +288,8 @@ namespace std { if (_M_pback_init) { - int_type __save_len = _M_pback_end_save - _M_pback_cur_save; - int_type __pback_len = _M_in_cur - _M_pback; + size_t __save_len = _M_pback_end_save - _M_pback_cur_save; + size_t __pback_len = _M_in_cur - _M_pback; __ret = __save_len - __pback_len; } else @@ -304,7 +304,8 @@ namespace std snextc() { int_type __eof = traits_type::eof(); - return (this->sbumpc() == __eof ? __eof : this->sgetc()); + return (traits_type::eq_int_type(this->sbumpc(), __eof) + ? __eof : this->sgetc()); } int_type @@ -342,10 +343,10 @@ namespace std protected: basic_streambuf() - : _M_buf(NULL), _M_buf_size(0), - _M_buf_size_opt(static_cast(BUFSIZ)), _M_buf_unified(false), - _M_in_beg(0), _M_in_cur(0), _M_in_end(0), _M_out_beg(0), _M_out_cur(0), - _M_out_end(0), _M_mode(ios_base::openmode(0)), _M_buf_locale(locale()), + : _M_buf(NULL), _M_buf_size(0), _M_buf_size_opt(BUFSIZ), + _M_buf_unified(false), _M_in_beg(0), _M_in_cur(0), _M_in_end(0), + _M_out_beg(0), _M_out_cur(0), _M_out_end(0), + _M_mode(ios_base::openmode(0)), _M_buf_locale(locale()), _M_buf_locale_init(false), _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false) { } @@ -438,7 +439,7 @@ namespace std uflow() { int_type __ret = traits_type::eof(); - bool __testeof = this->underflow() == __ret; + bool __testeof = traits_type::eq_int_type(this->underflow(), __ret); bool __testpending = _M_in_cur && _M_in_cur < _M_in_end; if (!__testeof && __testpending) { diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new index 74f14b5a4a25..475083be3fc1 100644 --- a/libstdc++-v3/libsupc++/new +++ b/libstdc++-v3/libsupc++/new @@ -88,6 +88,10 @@ void operator delete[](void*, const std::nothrow_t&) throw(); // Default placement versions of operator new. inline void* operator new(std::size_t, void* __p) throw() { return __p; } inline void* operator new[](std::size_t, void* __p) throw() { return __p; } + +// Default placement versions of operator delete. +inline void operator delete (void*, void*) throw() { }; +inline void operator delete[](void*, void*) throw() { }; //@} } // extern "C++" diff --git a/libstdc++-v3/src/locale.cc b/libstdc++-v3/src/locale.cc index 26c2834eb7d6..3cb9d1b4cbfd 100644 --- a/libstdc++-v3/src/locale.cc +++ b/libstdc++-v3/src/locale.cc @@ -202,7 +202,7 @@ namespace std if (strcmp(__s, "C") == 0 || strcmp(__s, "POSIX") == 0) (_M_impl = _S_classic)->_M_add_reference(); else if (strcmp(__s, "") == 0) - _M_impl = new _Impl(setlocale(LC_ALL, __s), 1); + _M_impl = new _Impl(setlocale(LC_ALL, NULL), 1); else _M_impl = new _Impl(__s, 1); } diff --git a/libstdc++-v3/src/localename.cc b/libstdc++-v3/src/localename.cc index 824d9790cef9..8fa911891705 100644 --- a/libstdc++-v3/src/localename.cc +++ b/libstdc++-v3/src/localename.cc @@ -132,8 +132,8 @@ namespace std _M_init_facet(new num_get); _M_init_facet(new num_put); _M_init_facet(new std::collate(__cloc)); - _M_init_facet(new moneypunct(__cloc)); - _M_init_facet(new moneypunct(__cloc)); + _M_init_facet(new moneypunct(__cloc, __s)); + _M_init_facet(new moneypunct(__cloc, __s)); _M_init_facet(new money_get); _M_init_facet(new money_put); _M_init_facet(new __timepunct(__cloc, __s)); @@ -148,8 +148,8 @@ namespace std _M_init_facet(new num_get); _M_init_facet(new num_put); _M_init_facet(new std::collate(__cloc)); - _M_init_facet(new moneypunct(__cloc)); - _M_init_facet(new moneypunct(__cloc)); + _M_init_facet(new moneypunct(__cloc, __s)); + _M_init_facet(new moneypunct(__cloc, __s)); _M_init_facet(new money_get); _M_init_facet(new money_put); _M_init_facet(new __timepunct(__cloc, __s)); diff --git a/libstdc++-v3/testsuite/22_locale/ctor_copy_dtor.cc b/libstdc++-v3/testsuite/22_locale/ctor_copy_dtor.cc index 8735799c7a83..732ec1714aa2 100644 --- a/libstdc++-v3/testsuite/22_locale/ctor_copy_dtor.cc +++ b/libstdc++-v3/testsuite/22_locale/ctor_copy_dtor.cc @@ -25,7 +25,6 @@ #include #include - void test00() { // Should be able to do this as the first thing that happens in a @@ -238,7 +237,21 @@ void test01() } #endif // _GLIBCPP_USE___ENC_TRAITS -int main () +// libstdc++/7222 +void test02() +{ + bool test = true; + std::locale loc_c1("C"); + std::locale loc_c2 ("C"); + + std::locale loc_1(""); + std::locale loc_2(""); + + VERIFY( loc_c1 == loc_c2 ); + VERIFY( loc_1 == loc_2 ); +} + +int main() { test00(); @@ -246,5 +259,7 @@ int main () test01(); #endif + test02(); + return 0; } diff --git a/libstdc++-v3/testsuite/24_iterators/iterator.cc b/libstdc++-v3/testsuite/24_iterators/iterator.cc index 98aa8c0b2589..7acd1ec26e1a 100644 --- a/libstdc++-v3/testsuite/24_iterators/iterator.cc +++ b/libstdc++-v3/testsuite/24_iterators/iterator.cc @@ -577,6 +577,17 @@ wrong_stuff() return failures; } +// libstdc++/6642 +int +test6642() +{ + std::string s; + std::string::iterator it = s.begin(); + std::string::const_iterator cit = s.begin(); + + return it - cit; +} + int main(int argc, char **argv) { @@ -590,6 +601,8 @@ main(int argc, char **argv) failures += wrong_stuff(); + failures += test6642(); + #ifdef DEBUG_ASSERT assert (failures == 0); #endif diff --git a/libstdc++-v3/testsuite/27_io/filebuf.cc b/libstdc++-v3/testsuite/27_io/filebuf.cc index 558d196f9fb3..9919365a552b 100644 --- a/libstdc++-v3/testsuite/27_io/filebuf.cc +++ b/libstdc++-v3/testsuite/27_io/filebuf.cc @@ -19,15 +19,26 @@ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. -// NB: this test assumes that _M_buf_size == 40, and not the usual -// buffer_size length of BUFSIZ (8192), so that overflow/underflow can be -// simulated a bit more readily. +// 27.8.1.1 - Template class basic_filebuf +// NB: This file is for testing basic_filebuf with NO OTHER INCLUDES. #include #include // { dg-do compile } +// libstdc++/7216 +void test01() +{ + // Check for required typedefs + typedef std::filebuf test_type; + typedef test_type::char_type char_type; + typedef test_type::traits_type traits_type; + typedef test_type::int_type int_type; + typedef test_type::pos_type pos_type; + typedef test_type::off_type off_type; +} + // test05 // libstdc++/1886 // should be able to instantiate basic_filebuf for non-standard types. @@ -35,6 +46,7 @@ template class std::basic_filebuf >; int main() { + test01(); return 0; } diff --git a/libstdc++-v3/testsuite/27_io/iostream.cc b/libstdc++-v3/testsuite/27_io/iostream.cc index 26849ac0fd2f..943819bf82fd 100644 --- a/libstdc++-v3/testsuite/27_io/iostream.cc +++ b/libstdc++-v3/testsuite/27_io/iostream.cc @@ -34,6 +34,18 @@ #include +// libstdc++/7216 +void test01() +{ + // Check for required typedefs + typedef std::iostream test_type; + typedef test_type::char_type char_type; + typedef test_type::traits_type traits_type; + typedef test_type::int_type int_type; + typedef test_type::pos_type pos_type; + typedef test_type::off_type off_type; +} + namespace test { using namespace std; @@ -43,5 +55,6 @@ namespace test int main() { + test01(); return 0; } diff --git a/libstdc++-v3/testsuite/27_io/istream.cc b/libstdc++-v3/testsuite/27_io/istream.cc index ef88a39f727e..05db50ed461f 100644 --- a/libstdc++-v3/testsuite/27_io/istream.cc +++ b/libstdc++-v3/testsuite/27_io/istream.cc @@ -34,6 +34,18 @@ // { dg-do compile } +// libstdc++/7216 +void test01() +{ + // Check for required typedefs + typedef std::istream test_type; + typedef test_type::char_type char_type; + typedef test_type::traits_type traits_type; + typedef test_type::int_type int_type; + typedef test_type::pos_type pos_type; + typedef test_type::off_type off_type; +} + namespace test { using namespace std; @@ -43,5 +55,6 @@ namespace test int main() { + test01(); return 0; } diff --git a/libstdc++-v3/testsuite/27_io/istream_unformatted.cc b/libstdc++-v3/testsuite/27_io/istream_unformatted.cc index da2cdeb739ed..0e98dced1082 100644 --- a/libstdc++-v3/testsuite/27_io/istream_unformatted.cc +++ b/libstdc++-v3/testsuite/27_io/istream_unformatted.cc @@ -514,6 +514,43 @@ test09() VERIFY( test ); } +// libstdc++/70220 +void +test10() +{ + using namespace std; + bool test = true; + typedef string string_type; + typedef stringbuf stringbuf_type; + typedef istream istream_type; + + int res = 0; + streamsize n; + string_type input("abcdefg\n"); + stringbuf_type sbuf(input); + istream_type istr(&sbuf); + + istr.ignore(0); + if (istr.gcount() != 0) + test = false; + VERIFY( test ); + + istr.ignore(0, 'b'); + if (istr.gcount() != 0) + test = false; + VERIFY( test ); + + istr.ignore(); // Advance to next position. + istr.ignore(0, 'b'); + if ((n=istr.gcount()) != 0) + test = false; + VERIFY( test ); + + if (istr.peek() != 'b') + test = false; + VERIFY( test ); +} + int main() { @@ -526,6 +563,7 @@ main() test07(); test08(); test09(); + test10(); return 0; } diff --git a/libstdc++-v3/testsuite/27_io/ostream.cc b/libstdc++-v3/testsuite/27_io/ostream.cc index cbc4a6739c2b..ae524ec61f29 100644 --- a/libstdc++-v3/testsuite/27_io/ostream.cc +++ b/libstdc++-v3/testsuite/27_io/ostream.cc @@ -34,6 +34,18 @@ // { dg-do compile } +// libstdc++/7216 +void test01() +{ + // Check for required typedefs + typedef std::ostream test_type; + typedef test_type::char_type char_type; + typedef test_type::traits_type traits_type; + typedef test_type::int_type int_type; + typedef test_type::pos_type pos_type; + typedef test_type::off_type off_type; +} + namespace test { using namespace std; @@ -43,5 +55,6 @@ namespace test int main() { + test01(); return 0; } diff --git a/libstdc++-v3/testsuite/27_io/ostringstream_members.cc b/libstdc++-v3/testsuite/27_io/ostringstream_members.cc index 4e7f861b516f..bf823697c830 100644 --- a/libstdc++-v3/testsuite/27_io/ostringstream_members.cc +++ b/libstdc++-v3/testsuite/27_io/ostringstream_members.cc @@ -1,6 +1,6 @@ // 2001-05-23 Benjamin Kosnik -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -97,9 +97,61 @@ void test02() // These semantics are a joke, a serious defect, and incredibly lame. } +// 03: sanity checks for strings, stringbufs +void +test03() +{ + bool test = false; + + // Empty string sanity check. + std::string str01; + std::string::iterator __i_start = str01.begin(); + std::string::iterator __i_end = str01.end(); + std::string::size_type len = str01.size(); + test = __i_start == __i_end; + VERIFY( len == 0 ); + + // Full string sanity check. + std::string str02("these golden days, i spend waiting for you:\n" + "Betty Carter on Verve with I'm Yours and You're Mine."); + __i_start = str02.begin(); + __i_end = str02.end(); + len = str02.size(); + VERIFY( __i_start != __i_end ); + VERIFY( len != 0 ); + + // Test an empty ostringstream for sanity. + std::ostringstream ostrstream0; + std::string str03 = ostrstream0.str(); + __i_start = str03.begin(); + __i_end = str03.end(); + len = str03.size(); + VERIFY( __i_start == __i_end ); + VERIFY( len == 0 ); + VERIFY( str01 == str03 ); +} + +// user-reported error +class derived_oss: public std::ostringstream +{ +public: + derived_oss() : std::ostringstream() { } +}; + +void +test04() +{ + bool test = true; + derived_oss yy; + yy << "buena vista social club\n"; + VERIFY( yy.str() == std::string("buena vista social club\n") ); +} + int main() { test01(); test02(); + test03(); + test04(); return 0; } diff --git a/libstdc++-v3/testsuite/27_io/streambuf.cc b/libstdc++-v3/testsuite/27_io/streambuf.cc index 3f9a3192b7e0..905dee089de8 100644 --- a/libstdc++-v3/testsuite/27_io/streambuf.cc +++ b/libstdc++-v3/testsuite/27_io/streambuf.cc @@ -1,6 +1,6 @@ -// 1999-10-11 bkoz +// 2002-07-25 Benjamin Kosnik -// Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2002 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -27,352 +27,34 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -// 27.5.2 template class basic_streambuf +// 27.5.2 - Template class basic_streambuf +// NB: This file is for testing basic_streambuf with NO OTHER INCLUDES. -#include // for memset, memcmp #include -#include -#include -#include -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 > - class basic_nullbuf : public std::basic_streambuf - { - protected: - typedef typename - std::basic_streambuf::int_type int_type; - virtual int_type - overflow(int_type c) - { return traits::not_eof(c); } - }; - -typedef basic_nullbuf nullbuf; -typedef basic_nullbuf wnullbuf; - -template - 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 >; +} // test int main() { test01(); - test02(); - test03(); - - test04(); - test05(); - - test07(); return 0; } diff --git a/libstdc++-v3/testsuite/27_io/stringbuf.cc b/libstdc++-v3/testsuite/27_io/stringbuf.cc index bc0bbb4dd8e1..00825b6b69c7 100644 --- a/libstdc++-v3/testsuite/27_io/stringbuf.cc +++ b/libstdc++-v3/testsuite/27_io/stringbuf.cc @@ -1,7 +1,6 @@ -// 981208 bkoz test functionality of basic_stringbuf for char_type == char +// 2002-07-25 Benjamin Kosnik -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 -// Free Software Foundation, Inc. +// Copyright (C) 2002 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -19,472 +18,43 @@ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. -#include -#include - -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 alloc_01; - std::allocator::size_type size_01 = alloc_01.max_size(); - std::allocator::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 (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 +// { 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 >; +} // test - return test; -} - -int main() +int main() { test01(); - test02(); - test03(); - test04(); - test05(); - test06(); - return 0; } - - - -// more candy!!! diff --git a/libstdc++-v3/testsuite/27_io/stringstream.cc b/libstdc++-v3/testsuite/27_io/stringstream.cc index 45ca438a5903..1a1b01780741 100644 --- a/libstdc++-v3/testsuite/27_io/stringstream.cc +++ b/libstdc++-v3/testsuite/27_io/stringstream.cc @@ -1,7 +1,6 @@ -// 981015 bkoz -// i,o,stringstream usage +// 2002-07-25 Benjamin Kosnik -// Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. +// Copyright (C) 2002 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -28,133 +27,34 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#include -#include -#include -#include - -// 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 +// { 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 >; +} // test -int -main() +int main() { test01(); - test02(); - test03(); - return 0; } diff --git a/libstdc++-v3/testsuite/27_io/stringstream_members.cc b/libstdc++-v3/testsuite/27_io/stringstream_members.cc index 4de7b8c52411..91ee79bcf40b 100644 --- a/libstdc++-v3/testsuite/27_io/stringstream_members.cc +++ b/libstdc++-v3/testsuite/27_io/stringstream_members.cc @@ -1,6 +1,6 @@ // 2001-05-24 Benjamin Kosnik -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -120,12 +120,67 @@ void test02() // These semantics are a joke, a serious defect, and incredibly lame. } +void +test03() +{ + bool test = true; + + // + // 1: Automatic formatting of a compound string + // + int i = 1024; + int *pi = &i; + double d = 3.14159; + double *pd = &d; + std::string blank; + std::ostringstream ostrst01; + std::ostringstream ostrst02(blank); + + // No buffer, so should be created. + ostrst01 << "i: " << i << " i's address: " << pi << "\n" + << "d: " << d << " d's address: " << pd << std::endl; + // Buffer, so existing buffer should be overwritten. + ostrst02 << "i: " << i << " i's address: " << pi << "\n" + << "d: " << d << " d's address: " << pd << std::endl; + + std::string msg01 = ostrst01.str(); + std::string msg02 = ostrst02.str(); + VERIFY( msg01 == msg02 ); + VERIFY( msg02 != blank ); + + // + // 2: istringstream + // + // extracts the stored ascii values, placing them in turn in the four vars +#if 0 + int i2 = 0; + //int* pi2 = &i2; + void* pi2 = &i2; + double d2 = 0.0; + // double* pd2 = &d2; + void* pd2 = &d2; + std::istringstream istrst01(ostrst02.str()); + + istrst01 >> i2 >> pi2 >> d2 >> pd2; + //istrst01 >> i2; + //istrst01 >> pi2; + VERIFY( i2 == i ); + VERIFY( d2 == d ); + VERIFY( pd2 == pd ); + VERIFY( pi2 == pi ); +#endif + + // stringstream + std::string str1(""); + std::string str3("this is a somewhat string"); + std::stringstream ss1(str1, std::ios_base::in|std::ios_base::out); + std::stringstream ss2(str3, std::ios_base::in|std::ios_base::out); +} + int main() { test01(); test02(); + test03(); return 0; } - - -