diff -Nrcpad gcc-4.1.1/gcc/cp/ChangeLog gcc-4.1.2/gcc/cp/ChangeLog
*** gcc-4.1.1/gcc/cp/ChangeLog	Wed May 24 23:42:03 2006
--- gcc-4.1.2/gcc/cp/ChangeLog	Wed Feb 14 05:11:31 2007
***************
*** 1,3 ****
--- 1,900 ----
+ 2007-02-13  Release Manager
+ 
+ 	* GCC 4.1.2 released.
+ 
+ 2007-02-06  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR target/29487
+ 	* decl.c (finish_function): Use DECL_REPLACEABLE.
+ 	* tree.c (cp_cannot_inline_tree_fn): Likewise.
+ 
+ 2007-01-28  Andrew Pinski  <pinskia@gmail.com>
+ 
+ 	PR C++/28988
+ 	* semantics.c (finish_pseudo_destructor_expr): Check the
+ 	destrutor name by calling check_dtor_name.
+ 
+ 2007-01-10  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28999
+ 	* decl.c (make_typename_type): If the qualified name is not a
+ 	type, issue an error.
+ 
+ 2007-01-05  Jakub Jelinek  <jakub@redhat.com>
+ 
+ 	PR c++/30382
+ 	Backported from mainline
+ 	2006-06-29  Jason Merrill  <jason@redhat.com>
+ 	* parser.c (cp_parser_enum_specifier): Return early if
+ 	type is error_mark_node.
+ 
+ 2007-01-03  Jakub Jelinek  <jakub@redhat.com>
+ 
+ 	Backported from mainline
+ 	2006-07-12  Jason Merrill  <jason@redhat.com>
+ 	PR c++/28217
+ 	* semantics.c (note_decl_for_pch): Don't premangle templates.
+ 
+ 2007-01-03  Jakub Jelinek  <jakub@redhat.com>
+ 
+ 	PR c++/29054
+ 	* decl.c (revert_static_member_fn): Don't remove first
+ 	argument without checking it is "this".
+ 
+ 	PR c++/29535
+ 	Backported from mainline
+ 	2006-10-17  Mark Mitchell  <mark@codesourcery.com>
+ 	PR c++/28261
+ 	* parser.c (cp_lexer_next_token_is_decl_specifier_keyword): New
+ 	function.
+ 	(cp_parser_constructor_declarator_p): Use it.
+ 	(cp_parser_check_type_definition): Return a value indicating
+ 	whether or not the definition is valid.
+ 	(cp_parser_enum_specifier): Skip invalid enum definitions.
+ 
+ 2006-12-10  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29732
+ 	* cp-tree.h (DECL_USE_TEMPLATE): Mention partial specializations.
+ 	(explicit_class_specialization_p): Declare.
+ 	* pt.c (explicit_class_specialization_p): New function.
+ 	* parser.c (cp_parser_init_declarator): Check correct number of
+ 	template parameters for in-class function definitions.
+ 	(cp_parser_check_declarator_template_parameters): Stop looking for
+ 	template classes when we find an explicit specialization.
+ 
+ 2006-12-06  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29730
+ 	* parser.c (cp_parser_init_declarator): Reject initialization of
+ 	functions.
+ 
+ 2006-12-05  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29729
+ 	* decl2.c (check_member_template): Move check for member
+ 	templates in local classes to ...
+ 	* parser.c (cp_parser_template_declaration_after_export):
+ 	... here.
+ 
+ 2006-12-05  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29728
+ 	* decl.c (check_array_designated_initializer): New function.
+ 	(maybe_deduce_size_from_array_init): Use it.
+ 	(reshape_init_array): Likewise.
+ 
+ 2006-12-05  Richard Henderson  <rth@redhat.com>
+             Andrew Pinski  <pinskia@gmail.com>
+ 
+ 	PR C++/14329
+ 	* error.c (cp_printer) <'D'>: Handle DECL_DEBUG_EXPR.
+ 
+ 2006-12-04  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29632
+ 	* call.c (add_builtin_candidate): Do not permit NULL pointer
+ 	constants to be compared with template parameters.
+ 
+ 	PR c++/29733
+ 	* pt.c (tsubst_decl): Disallow variables of function type.
+ 
+ 2006-12-03  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	Backport:
+ 	2006-08-27  Simon Martin  <simartin@users.sourceforge.net>
+ 
+ 	PR c++/28284
+ 	* pt.c (fold_non_dependent_expr): Make sure expr is not dereferenced if it
+ 	is NULL.
+ 
+ 2006-12-01  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/30022
+ 	* typeck.c (type_after_usual_arithmetic_conversions):
+ 	Fix assertion for vector types.
+ 	(build_binary_op): Use temporary for inner type of vector types.
+ 
+ 2006-11-29  Lee Millward  <lee.millward@codesourcery.com> 
+ 
+ 	PR c++/29022
+ 	* parser.c (cp_parser_class_head): Move processing
+ 	of any base classes to...
+ 	(cp_parser_class_specifier) ...here. Take an extra
+ 	tree* parameter for any base classes. Only process
+ 	them if the opening brace was found.
+ 	
+ 2006-11-28  Jakub Jelinek  <jakub@redhat.com>
+ 
+ 	PR c++/29735
+ 	* decl.c (grokfndecl): Check main's type after applying
+ 	attributes, not before.
+ 
+ 2006-11-26  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29886
+ 	* parser.c (cp_parser): Add in_function_body.
+ 	(cp_parser_new): Initialize it.
+ 	(cp_parser_primary_expression): Use parser->in_function_body
+ 	instead of at_function_scope_p.
+ 	(cp_parser_asm_definition): Likewise.
+ 	(cp_parser_direct_declarator): Likewise.
+ 	(cp_parser_class_specifier): Clear parser->in_function_body.
+ 	(cp_parser_constructor_declarator_p): Use parser->in_function_body
+ 	instead of at_function_scope_p.
+ 	(cp_parser_function_body_after_declarator): Set
+ 	parser->in_function_body.
+ 
+ 2006-11-21  Jakub Jelinek  <jakub@redhat.com>
+ 
+ 	PR c++/29570
+ 	* decl.c (cp_finish_decl): Check for value dependent brace enclosed
+ 	scalar initializer.
+ 
+ 	PR c++/29734
+ 	* cp-tree.h (WANT_VECTOR): Define.
+ 	(WANT_ARITH): Add WANT_VECTOR.
+ 	* cvt.c (build_expr_type_conversion): Handle vector types.
+ 	* typeck.c (build_unary_op): Add WANT_VECTOR to
+ 	build_expr_type_conversion flags.
+ 
+ 2006-11-13  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29106
+ 	* init.c (constant_value_1): Treat a DECL_INITIAL of
+ 	error_mark_node as meaning that the variable is uninitialized,
+ 	rather than erroneously initialized.
+ 
+ 	PR c++/29518
+ 	* pt.c (coerce_template_parms): Do not skip_evaluation while
+ 	substituting template arguments.
+ 
+ 2006-10-22  Nathan Sidwell  <nathan@codesourcery.com>
+ 
+ 	PR c++/20647
+ 	* rtti.c (tinfo_base_init): The type info string is always global.
+ 
+ 2006-10-18  Mark Shinwell  <shinwell@codesourcery.com>
+ 
+ 	PR c++/26884
+ 	* typeck2.c (digest_init): Raise error upon attempts to
+ 	initialize arrays with variables.
+ 
+ 2006-10-18  Richard Guenther  <rguenther@suse.de>
+ 
+ 	PR C++/25878
+ 	Backport from mainline:
+ 	2006-08-25  Nathan Sidwell  <nathan@codesourcery.com>
+ 
+ 	PR c++/27787
+ 	* decl.c (make_typename_type): Only try and resolve it when
+ 	context is not dependent.  Refactor.
+ 	* decl2.c (check_classfn): Push to class scope before looking for
+ 	the function.
+ 
+ 2006-10-17  Richard Guenther  <rguenther@suse.de>
+ 
+ 	Backport from mainline:
+ 	2006-09-07  Andrew Pinski  <pinskia@physics.uc.edu>
+ 
+ 	PR C++/28906
+ 	* init.c (build_new_1): Build a distinct type copy
+ 	for the array type that was returned from
+ 	build_cplus_array_type.
+ 
+ 2006-10-16  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29435
+ 	* typeck.c (cxx_sizeof_or_alignof_type): Complete non-dependent
+ 	types when their sizes are required.  Refine test for VLAs.
+ 
+ 2006-10-16  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29408
+ 	* parser.c (cp_parser_using_declaration): Stop parsing when
+ 	something goes wrong with an access declaration.
+ 
+ 2006-10-14  Richard Guenther  <rguenther@suse.de>
+ 
+ 	PR rtl-optimization/29323
+ 	* decl.c (finish_function): Set TREE_NOTHROW only for
+ 	functions that bind local.
+ 
+ 2006-10-13  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28506
+ 	* parser.c (function_declarator_p): New function.
+ 	(cp_parser_init_declarator): Use it.
+ 	(cp_parser_member_declaration): Likewise.
+ 
+ 2006-10-12  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29318
+ 	* rtti.c (get_tinfo_decl): Refuse to create type info objects for
+ 	variably modified types.
+ 
+ 2006-10-12  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29175
+ 	* decl.c (check_initializer): Issue errors about trying to
+ 	initialize arrays whose elements have variable size.
+ 
+ 2006-10-07 Andrew Pinski  <pinskia@physics.uc.edu>
+ 
+ 	PR C++/29002
+ 	* init.c (build_zero_init): If we have an error mark node for
+ 	the array size, return.
+ 
+ 2006-10-06  Andrew Pinski  <pinskia@physics.uc.edu>
+ 
+ 	PR c++/28302
+ 	* typeck.c (build_unary_op <case BIT_NOT_EXPR:>): Don't call
+ 	perform_integral_promotions for non integral type
+ 
+ 2006-10-06  Andrew Pinski  <pinskia@physics.uc.edu>
+ 
+ 	PR C++/28450
+ 	* cp/init.c (build_zero_init): Handle VECTOR_TYPE and
+ 	COMPLEX_TYPEs.
+ 
+ 2006-10-05  Andrew Pinski  <pinskia@physics.uc.edu>
+ 
+ 	PR C++/28349
+ 	* call.c (build_x_va_arg): Remove the reference type
+ 	from the type before creating the pointer type.
+ 
+ 2006-10-03  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29138
+ 	* decl2.c (grokfield): Don't handle access declarations here.
+ 	* parser.c (cp_parser_using_declaration): Handle access
+ 	declarations too.
+ 	(cp_parser_block_declaration): Adjust calls to
+ 	cp_parser_using_declaration.
+ 	(cp_parser_member_declaration): Likewise.  Use
+ 	cp_parser_using_declaration to look for access_declarations.
+ 
+ 2006-10-02  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29226
+ 	* typeck.c (cxx_sizeof_or_alignof_type): Tidy.  In templates, do
+ 	not try to actually evaluate sizeof for a VLA type.
+ 
+ 2006-10-01  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29080
+ 	* parser.c (cp_parser_postfix_dot_deref_expression): Use
+ 	BASELINK_ACCESS_BINFO as the qualifying scope when calling
+ 	adjust_result_of_qualified_name_lookup. 
+ 
+ 2006-09-22  Jason Merrill  <jason@redhat.com>
+ 
+ 	PR c++/28996
+ 	* cvt.c (convert_to_void): Strip COMPONENT_REF to functions.
+ 
+ 2006-09-21  Steven Bosscher  <steven@gcc.gnu.org>
+ 
+ 	PR c++/29087
+ 	Backport from mainline:
+ 	* parser.c (cp_parser_labeled_statement): Return nothing.  Do
+ 	not take in_statement_expr and in_compound as arguments.  Rename
+ 	to cp_parser_label_for_labeled_statement.  Parse only the label,
+ 	not the statement.
+ 	(cp_parser_statement): Parse the statement of a labeled-statement
+ 	from here, using tail recursion.
+ 
+ 2006-09-07  Jason Merrill  <jason@redhat.com>
+ 
+ 	PR c++/26957
+ 	* method.c (use_thunk): Clear DECL_HAS_VALUE_EXPR_P on copied
+ 	parms.
+ 
+ 2006-09-06  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28886
+ 	* pt.c (unify): Avoid unnecessary calls to fold_build2 for array
+ 	dimensions.
+ 
+ 2006-09-06  Zak Kipling  <zak@transversal.com>
+ 
+ 	PR c++/26195
+ 	* decl.c (make_rtl_for_nonlocal_decl),
+ 	(start_preparsed_function): Don't use lbasename on
+ 	input_filename when calling get_fileinfo.
+ 	* semantics.c (begin_class_definition): Likewise.
+ 	* lex.c (cxx_make_type): Likewise.
+ 	(handle_pragma_interface): Call get_fileinfo on input_filename,
+ 	not on the parameter to the directive.
+ 
+ 2006-09-06  Jason Merrill  <jason@redhat.com>
+ 
+ 	PR c++/26696
+ 	* cvt.c (convert_to_void): Replace a subexpression with no side 
+ 	effects with void_zero_node.
+ 	* tree.c (is_overloaded_fn): Look through COMPONENT_REF.
+ 	(get_first_fn): Ditto.
+ 	* decl.c (grokdeclarator): No need to look through COMPONENT_REF.
+ 
+ 2006-09-05  Jason Merrill  <jason@redhat.com>
+ 
+ 	PR c++/26571
+ 	* parser.c (cp_parser_diagnose_invalid_type_name): Handle the case
+ 	where the name is a type used incorrectly.
+ 
+ 	PR c++/26671
+ 	* typeck.c (maybe_warn_about_returning_address_of_local): Look 
+ 	through COMPONENT_REF and ARRAY_REF.	
+ 
+ 	PR c++/26102
+ 	* name-lookup.c (do_class_using_decl): Try to find the base even
+ 	if bases_dependent_p.
+ 	* pt.c (type_dependent_expression_p): A USING_DECL is dependent.	
+ 
+ 	PR c++/19809
+ 	* pt.c (tsubst_friend_function): Set DECL_INITIAL before pushdecl.
+ 
+ 2006-09-02  Jakub Jelinek  <jakub@redhat.com>
+ 
+ 	PR c++/28878
+ 	* except.c (build_throw): Only set current_function_returns_abnormally
+ 	if cfun is not NULL.
+ 
+ 	PR c++/26917
+ 	* repo.c (repo_file): Remove.
+ 	(open_repo_file, reopen_repo_file_for_write): Return fopened
+ 	FILE * instead of setting global repo_file variable.
+ 	(init_repo): Adjust caller.
+ 	(finish_repo): Likewise.  Return instead of goto out before
+ 	reopen_repo_file_for_write has been called.
+ 
+ 2006-08-30  Jason Merrill  <jason@redhat.com>
+ 
+ 	PR c++/26670
+ 	* class.c (check_field_decls): Don't unset TYPE_PACKED until all
+ 	the fields have been processed.
+ 
+ 	PR c++/26670
+ 	* class.c (check_field_decls): Unset TYPE_PACKED (t) if one of the
+ 	fields can't be packed.
+ 
+ 2006-08-28  Jason Merrill  <jason@redhat.com>
+ 
+ 	PR c++/26577
+ 	* cvt.c (convert_to_void): Don't automatically load from volatiles 
+ 	of TREE_ADDRESSABLE type.
+ 
+ 2006-08-28  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/28860
+ 	* cp-tree.h (maybe_process_partial_specialization): Return
+ 	tree instead of void.
+ 	* parser.c (cp_parser_class_head): Use return value of
+ 	maybe_process_partial_specialization.
+ 	* pt.c (maybe_process_partial_specialization): Return error_mark_node
+ 	for broken specializations, TYPE otherwise.  Check for template
+ 	template parameters.
+ 
+ 2006-08-27  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28058
+ 	* pt.c (register_specialization): Return error_mark_node for
+ 	specialization-after-instantiation.
+ 	* decl2.c (mark_used): Mark the main function used when one of its
+ 	clones is used.
+ 	
+ 2006-08-26  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28595
+ 	* pt.c (tsubst): Issue errors about attempts to create VLAs at
+ 	template-instantiation time.
+ 
+ 2006-08-25  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/28853
+ 	* typeck2.c (cxx_incomplete_type_diagnostic): Handle template
+ 	template parameters.  Improve error message for template type
+ 	parameters.
+ 
+ 2006-08-25  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28056
+ 	* decl.c (grokdeclarator): Disallow declarations with qualified
+ 	names in local scopes.
+ 
+ 2006-08-23  Jason Merrill  <jason@redhat.com>
+ 
+ 	PR c++/27714
+ 	* pt.c (push_template_decl_real): A friend template with class 
+ 	scope isn't primary.
+ 
+ 2006-08-22  Jason Merrill  <jason@redhat.com>
+ 
+ 	PR c++/23372
+ 	* call.c (build_over_call): Don't make a copy here if build_call 
+ 	will make one too.
+ 
+ 2006-08-20  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28346
+ 	* pt.c (tsubst_qualified_id): Do not strip references from
+ 	OFFSET_REFs. 
+ 
+ 2006-08-17  Jason Merrill  <jason@redhat.com>
+ 
+ 	PR c++/28385
+ 	* pt.c (tsubst) [TEMPLATE_TYPE_PARM]: Ignore quals from template
+ 	if arg is a function.
+ 
+ 2006-08-17  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/28606
+ 	* parser.c (cp_parser_diagnose_invalid_type_name): Handle BIT_NOT_EXPR.
+ 	Fix formatting.
+ 	(cp_parser_parse_and_diagnose_invalid_type_name): Tighten condition
+ 	for valid type-names.
+ 	(cp_parser_unqualified_id): Fix error handling for destructors.
+ 
+ 	PR c++/28710
+ 	* decl.c (xref_tag): Improve error message.  Return early on error.
+ 
+ 2006-08-16  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/28593
+ 	* init.c (build_new): Return early on invalid placement.
+ 
+ 2006-08-13  Jakub Jelinek  <jakub@redhat.com>
+ 
+ 	PR c++/28677
+ 	PR middle-end/27793
+ 	* cp-tree.h (cxx_int_tree_map): New struct.
+ 	(struct language_function): Add extern_decl_map field.
+ 	* name-lookup.c (pushdecl_maybe_friend): Add x -> t mapping
+ 	to cp_function_chain->extern_decl_map hash table instead of
+ 	copying over DECL_UID.
+ 	* cp-gimplify.c (cxx_int_tree_map_eq, cxx_int_tree_map_hash): New
+ 	functions.
+ 	(cp_genericize_r): Remap DECL_EXTERN local decls using
+ 	cp_function_chain->extern_decl_map hash table.
+ 	* decl.c (finish_function): Clear extern_decl_map.
+ 
+ 2006-08-10  Lee Millward  <lee.millward@codesourcery.com>
+ 
+ 	PR c++/28594
+ 	PR c++/28637
+ 	PR c++/28638
+ 	PR c++/28639
+ 	PR c++/28640
+ 	PR c++/28641
+ 
+ 	Revert
+ 	2006-07-28  Lee Millward  <lee.millward@codesourcery.com>
+ 
+         PR c++/27668
+         PR c++/27962
+         * pt.c (process_template_parm) Store invalid template
+         parameters as error_mark_node in the paramater list.
+         (push_inline_template_parms_recursive): Handle invalid
+         template parameters.
+         (comp_template_parms): Likewise.
+         (check_default_tmpl_args): Likewise.
+         (coerce_template_template_parms): Likewise.
+         (coerce_template_parms): Likewise.
+         (mangle_class_name_for_template): Likewise.
+         (tsubst_template_parms): Likewise.
+         * error.c (dump_template_argument_list): Likewise.
+ 	
+ 2006-08-07  Lee Millward  <lee.millward@codesourcery.com>
+ 
+ 	* pt.c (coerce_template_parms): Fix misplaced parenthesis.
+ 	
+ 2006-08-03  Lee Millward  <lee.millward@codesourcery.com>
+ 
+        PR c++/28347
+        * decl.c (start_decl): Return error_mark_node if a
+        diagnostic was issed for an invalid typedef initialization
+ 	
+ 2006-08-03  Steve Ellcey  <sje@cup.hp.com>
+ 
+ 	PR c++/28432
+ 	* decl2.c (check_classfn): Remove early return.
+ 	* search.c (lookup_member): Return NULL with bad type.
+ 
+ 2006-08-03  Steve Ellcey  <sje@cup.hp.com>
+ 
+ 	PR c++/28256
+ 	* decl.c (check_initializer): Check for 1 initializer on scalar types.
+ 
+ 2006-08-03  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/27508
+ 	* parser.c (cp_parser_unqualified_id): Check for invalid scopes
+ 	when parsing destructor names.
+ 
+ 	PR c++/28274
+ 	* decl.c (duplicate_decls): Call check_default_args here.
+ 	(start_preparsed_function): Do not call check_default_args.
+ 	* name-lookup.c (pushdecl_maybe_friend): Only call
+ 	check_default_args if duplicate_decls got bypassed.
+ 
+ 2006-08-02  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28557
+ 	* pt.c (tsubst_baselink): Substitute into BASELINK_OPTYPE.
+ 
+ 2006-07-31  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28523
+ 	* tree.c (stabilize_expr): Tweak documentation.  Add assertion.
+ 	(stabilize_call): Tweak documentation.
+ 	(stabilize_init): Only call stabilize_call for calls.
+ 
+ 2006-07-28  Lee Millward  <lee.millward@codesourcery.com>
+ 
+         PR c++/27668
+         PR c++/27962
+         * pt.c (process_template_parm) Store invalid template
+         parameters as error_mark_node in the paramater list.
+         (push_inline_template_parms_recursive): Handle invalid
+         template parameters.
+         (comp_template_parms): Likewise.
+         (check_default_tmpl_args): Likewise.
+         (coerce_template_template_parms): Likewise.
+         (coerce_template_parms): Likewise.
+         (mangle_class_name_for_template): Likewise.
+         (tsubst_template_parms): Likewise.
+         * error.c (dump_template_argument_list): Likewise.
+ 	
+ 2006-07-24  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/27572
+ 	* decl.c (grokdeclarator): Return error_mark_node after invalid
+ 	typedef.
+ 
+ 2006-07-23  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28025
+ 	* cp-tree.h (LOOKUP_HIDDEN): New macro.  Reformat comments.
+ 	* name-lookup.c (unqualified_namespace_lookup): There is no way to
+ 	have a hidden name in non-namespace scopes.
+ 	* pt.c (tsubst_friend_class): Look for hidden names.
+ 	* decl.c (lookup_and_check_tag): Fix typo in comment.
+ 
+ 	* semantics.c (finish_compound_literal): Fix typo in comment.
+ 
+ 2006-07-22  Lee Millward  <lee.millward@gmail.com>
+ 
+ 	PR c++/28258
+ 	* method.c (locate_copy): Check for non_reference
+ 	returning error_mark_node.
+ 	
+ 2006-07-21  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/28363
+ 	* semantics.c (check_template_template_default_arg): Simplify
+ 	error handling.
+ 
+ 2006-07-20  Steve Ellcey  <sje@cup.hp.com>
+ 
+ 	PR c++/27495
+ 	* search.c (adjust_result_of_qualified_name_lookup): Change
+ 	assert to part of if statement.
+ 
+ 2006-07-19  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28338
+ 	* decl.c (layout_var_decl): Don't call push_local_name here.
+ 	(initialize_artificial_var): Assert artificiality.
+ 	(cp_finish_decl): Call push_local_name here.
+ 
+ 2006-07-18  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28337
+ 	* typeck.c (build_binary_op): Short-circuit pointer arithmetic in
+ 	templates.
+ 	
+ 	PR c++/28048
+ 	* semantics.c (check_accessibility_of_qualified_id): Robustify.
+ 
+ 2006-07-18  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28235
+ 	* pt.c (tsubst_decl): Handling substitutions into a static data
+ 	member from within the scope of the tempalte itself.
+ 
+ 2006-07-18  Steve Ellcey  <sje@cup.hp.com>
+ 
+ 	PR c++/28291
+ 	* decl.c (reshape_init_class): Return error_mark_node on error.
+ 
+ 2006-07-18  Steve Ellcey  <sje@cup.hp.com>
+ 
+ 	PR c++/28304
+ 	* decl2.c (check_classfn): Return NULL_TREE on error.
+ 
+ 2006-07-15  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/28249
+ 	* parser.c (cp_parser_check_decl_spec): New function.
+ 	(cp_parser_decl_specifier_seq): Factor out check for repeated
+ 	decl-specifiers into cp_parser_check_decl_spec. Use it.
+ 	(cp_parser_type_specifier_seq): Use it.
+ 
+ 	PR c++/28294
+ 	* semantics.c (finish_offsetof): Use TREE_OPERAND for COMPONENT_REFs
+ 	only.
+ 
+ 2006-07-14  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/28343
+ 	* decl.c (cp_finish_decl): Check asmspec_tree for error_mark_node.
+ 	* decl2.c (grokfield): Likewise.
+ 
+ 2006-06-16  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/28016
+ 	* decl.c (cp_finsh_decl): Do not emit uninstantiated static data
+ 	members.
+ 
+ 2006-07-11  Lee Millward  <lee.millward@gmail.com>
+ 
+ 	PR c++/28051
+ 	* mangle.c (mangle_conv_op_name_for_type): Check for
+ 	invalid types.
+ 	* name-lookup.c (push_class_level_binding): Robustify.
+ 	(do_class_using_decl): Return early if name is
+ 	error_mark_node. 
+ 	
+ 2006-07-10  Steve Ellcey  <sje@cup.hp.com>
+ 
+ 	PR c++/27019
+ 	* typeck2.c (process_init_constructor_array): Set ce->value on errors.
+ 
+ 2006-07-10  Steve Ellcey  <sje@cup.hp.com>
+ 
+ 	PR c++/28114
+ 	* name-lookup.c (pushtag): Return if we have error_mark_node.
+ 
+ 2006-07-08  Lee Millward  <lee.millward@gmail.com>
+ 	    Andrew Pinski  <pinskia@gmail.com>
+ 
+ 	PR c++/27820
+ 	* decl.c (define_label): Return error_mark_node on error.
+ 	* semantics.c (finish_label_stmt): Don't call
+ 	add_stmt for invalid labels.
+ 	
+ 2006-07-05  Jason Merrill  <jason@redhat.com>
+ 
+ 	PR c++/13983
+ 	PR c++/17519
+ 	* class.c (check_field_decls): Check TYPE_PACKED after
+ 	stripping array types.
+ 
+ 	PR c++/18681
+ 	* friend.c (is_friend): Fix DR 45 implementation.
+ 
+ 2006-06-30  Jason Merrill  <jason@redhat.com>
+ 
+ 	PR c++/26577
+ 	* call.c (build_new_method_call): Force evaluation of the 
+ 	instance pointer, not the object.
+ 
+ 	PR c++/18698
+ 	* decl2.c (grokfield): Only try to treat the decl as an access 
+ 	declaration if the scope is a class.
+ 
+ 2006-06-28  Jason Merrill  <jason@redhat.com>
+ 
+ 	PR c++/27424
+ 	* pt.c (convert_template_argument): Pass all template arguments 
+ 	on to coerce_template_template_parms.
+ 
+ 2006-06-25  Lee Millward  <lee.millward@gmail.com>
+ 
+ 	PR c++/27821
+ 	* decl.c (grokdeclarator): Return error_mark_node on
+ 	invalid uses of the scope resolution operator.
+ 	
+ 2006-06-23  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/28112
+ 	* parser.c (cp_parser_attribute_list): Skip attributes with invalid
+ 	arguments.  Fix comment.
+ 
+ 2006-06-22  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/28110
+ 	* pt.c (unify) <case TEMPLATE_PARM_INDEX>: Check for invalid
+ 	parameters.
+ 
+ 	PR c++/28109
+ 	* rtti.c (get_tinfo_decl_dynamic): Robustify.
+ 
+ 2006-06-16  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/27884
+ 	* decl.c (have_extern_spec): Remove.
+ 	(start_decl): Do not check have_extern_spec.
+ 	(start_function): Likewise.
+ 	* cp-tree.h (have_extern_spec): Remove.
+ 	* parser.c (cp_parser_linkage_specification): Don't set
+ 	have_extern_spec.
+ 	(cp_parser_init_declarator): Likewise.
+ 	(cp_parser_parameter_declaration): Do not treat parameters as
+ 	within the scope of an unbraced linkage specification.
+ 
+ 2006-06-15  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/27689
+ 	* cp-tree.h (CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P): New
+ 	macro.
+ 	* pt.c (unify): Use it.
+ 
+ 2006-06-15  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/27666
+ 	* call.c (build_conditional_expr): Robustify.
+ 
+ 2006-06-15  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/27665
+ 	* parser.c (cp_parser_unqualified_id): Use constructor_name_p to
+ 	identify destructors.
+ 	(cp_parser_nested_name_specifier_opt): Remove invalid
+ 	optimization.
+ 	(cp_parser_template_id): Refine heuristic for determining whether
+ 	we are entering a scope.
+ 
+ 2006-06-14  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/27648
+ 	* parser.c (cp_parser_declarator): Robustify.
+ 
+ 2006-06-14  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/26559
+ 	* pt.c (value_dependent_expression_p): All CALL_EXPRs are dependent.
+ 
+ 2006-06-13  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/27227
+ 	* decl.c (decls_match): Allow an extern "C" variable declarations
+ 	from different namespaces to match.
+ 	(duplicate_decls): Disallow redeclaring a variable with a
+ 	different linkage specification.
+ 
+ 2006-06-14  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+ 
+ 	* cp-tree.def: Fix typo.
+ 
+ 2006-06-13  Roger Sayle  <roger@eyesopen.com>
+ 
+ 	PR c++/21210
+ 	* typeck2.c (build_functional_cast): Use cp_convert to construct
+ 	non-aggregate initializers instead of the user-level build_c_cast.
+ 
+ 2006-06-12  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/27601
+ 	* semantics.c (finish_offsetof): Handle pseudo-destructors.
+ 
+ 	PR c++/27933
+ 	* name-lookup.c (lookup_qualified_name): Always return error_mark_node
+ 	if lookup fails.
+ 
+ 	PR c++/27951
+ 	* decl2.c (finish_anon_union): Return early if build_anon_union_vars
+ 	fails.
+ 
+ 2006-06-07  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/27601
+ 	* cp-tree.h (finish_offsetof): Add prototype.
+ 	* semantics.c (finish_offsetof): New function.
+ 	* parser.c (cp_parser_builtin_offsetof): Call it instead of
+ 	fold_offsetof.
+ 	* pt.c (tsubst_copy_and_build): Likewise.
+ 
+ 2006-06-06  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/27177
+ 	* call.c (standard_conversion): Require that the derived type be
+ 	complete when performing a derived-to-base conversion.
+ 
+ 2006-06-04  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/27819
+ 	* decl.c (cp_finish_decl): Process initializers for static data
+ 	members with non-dependent initializers, even in templates.
+ 
+ 	PR c++/27722
+ 	* decl.c (maybe_deduce_size_from_array_init): If the declaration
+ 	is erroneous, give it an erroneous type.
+ 	(layout_var_decl): If the type is erroneous, give up.
+ 	(check_initializer): Likewise.
+ 
+ 	PR c++/27807
+ 	* cp-tree.h (TYPE_OBJ_P): New macro.
+ 	(TYPE_PTROB_P): Use it.
+ 	(TYPE_REF_OBJ_P): Likewise.
+ 	* semantics.c (finish_compound_literal): Do not permit compound
+ 	literals of non-object types.
+ 
+ 	PR c++/27806
+ 	* typeck.c (original_type): Robustify.
+ 
+ 2006-05-31  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/27801
+ 	* call.c (perform_implicit_conversion): Do not actually perform
+ 	conversions in templates.
+ 
+ 	PR c++/26496
+ 	* call.c (resolve_args): Check for invalid uses of bound
+ 	non-static member functions.
+ 	* init.c (build_offset_ref): Return error_mark_node for errors.
+ 
+ 	PR c++/27385
+ 	* decl.c (reshape_init): Robustify.
+ 	(reshape_init_array_1): Likewise.
+ 
+ 2006-05-30  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/26433
+ 	* cp-tree.h (begin_function_try_block): Change prototype.
+ 	(finish_function_handler_sequence): Likewise.
+ 	* parser.c (cp_parser_function_try_block): Adjust calls.
+ 	* pt.c (tsubst_expr): Adjust calls.
+ 	* semantics.c (begin_function_try_block): Create an artificial
+ 	outer scope.
+ 	(finish_function_handler_sequence): Close it.
+ 
+ 2006-05-30  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/26068
+ 	* parser.c (cp_parser_set_storage_class): Check for 
+ 	invalid uses of storage classes on unbraced linkage
+ 	specifications.
+ 	(cp_parser_decl_specifier_seq): Pass keywords, not storage classes,
+ 	to cp_parser_set_storage_class.
+ 
+ 2006-05-30  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/20173
+ 	* pt.c (determine_specialization): Disallow partial
+ 	specializations of templates.
+ 
+ 2006-05-29  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+ 
+ 	PR c++/27713
+ 	* pt.c (push_template_decl_real): Return error_mark_node instead
+ 	of broken decl.
+ 
+ 	PR c++/27447
+ 	* decl2.c (grok_method_quals): Skip invalid functions and class types.
+ 
+ 	PR c++/27716
+ 	* typeck.c (build_modify_expr): Test arguments for error_operand_p.
+ 
  2006-05-24  Release Manager
  
  	* GCC 4.1.1 released.
diff -Nrcpad gcc-4.1.1/gcc/cp/call.c gcc-4.1.2/gcc/cp/call.c
*** gcc-4.1.1/gcc/cp/call.c	Tue Jan 24 21:38:56 2006
--- gcc-4.1.2/gcc/cp/call.c	Mon Dec  4 23:21:03 2006
*************** standard_conversion (tree to, tree from,
*** 714,720 ****
  		  that necessitates this conversion is ill-formed.
  		  Therefore, we use DERIVED_FROM_P, and do not check
  		  access or uniqueness.  */
! 	       && DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
  	{
  	  from =
  	    cp_build_qualified_type (TREE_TYPE (to),
--- 714,732 ----
  		  that necessitates this conversion is ill-formed.
  		  Therefore, we use DERIVED_FROM_P, and do not check
  		  access or uniqueness.  */
! 	       && DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from))
! 	       /* If FROM is not yet complete, then we must be parsing
! 		  the body of a class.  We know what's derived from
! 		  what, but we can't actually perform a
! 		  derived-to-base conversion.  For example, in:
! 
! 		     struct D : public B { 
!                        static const int i = sizeof((B*)(D*)0);
!                      };
! 
!                   the D*-to-B* conversion is a reinterpret_cast, not a
! 		  static_cast.  */
! 	       && COMPLETE_TYPE_P (TREE_TYPE (from)))
  	{
  	  from =
  	    cp_build_qualified_type (TREE_TYPE (to),
*************** add_builtin_candidate (struct z_candidat
*** 1785,1798 ****
  	break;
        if (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
  	break;
!       if (TREE_CODE (type1) == ENUMERAL_TYPE && TREE_CODE (type2) == ENUMERAL_TYPE)
  	break;
!       if (TYPE_PTR_P (type1) && null_ptr_cst_p (args[1]))
  	{
  	  type2 = type1;
  	  break;
  	}
!       if (null_ptr_cst_p (args[0]) && TYPE_PTR_P (type2))
  	{
  	  type1 = type2;
  	  break;
--- 1797,1815 ----
  	break;
        if (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
  	break;
!       if (TREE_CODE (type1) == ENUMERAL_TYPE 
! 	  && TREE_CODE (type2) == ENUMERAL_TYPE)
  	break;
!       if (TYPE_PTR_P (type1) 
! 	  && null_ptr_cst_p (args[1])
! 	  && !uses_template_parms (type1))
  	{
  	  type2 = type1;
  	  break;
  	}
!       if (null_ptr_cst_p (args[0]) 
! 	  && TYPE_PTR_P (type2)
! 	  && !uses_template_parms (type2))
  	{
  	  type1 = type2;
  	  break;
*************** resolve_args (tree args)
*** 2693,2698 ****
--- 2710,2717 ----
  	  error ("invalid use of void expression");
  	  return error_mark_node;
  	}
+       else if (invalid_nonstatic_memfn_p (arg))
+ 	return error_mark_node;
      }
    return args;
  }
*************** build_conditional_expr (tree arg1, tree 
*** 3283,3294 ****
--- 3302,3322 ----
  	  arg2 = convert_like (conv2, arg2);
  	  arg2 = convert_from_reference (arg2);
  	  arg2_type = TREE_TYPE (arg2);
+ 	  /* Even if CONV2 is a valid conversion, the result of the
+ 	     conversion may be invalid.  For example, if ARG3 has type
+ 	     "volatile X", and X does not have a copy constructor
+ 	     accepting a "volatile X&", then even if ARG2 can be
+ 	     converted to X, the conversion will fail.  */
+ 	  if (error_operand_p (arg2))
+ 	    result = error_mark_node;
  	}
        else if (conv3 && (!conv3->bad_p || !conv2))
  	{
  	  arg3 = convert_like (conv3, arg3);
  	  arg3 = convert_from_reference (arg3);
  	  arg3_type = TREE_TYPE (arg3);
+ 	  if (error_operand_p (arg3))
+ 	    result = error_mark_node;
  	}
  
        /* Free all the conversions we allocated.  */
*************** build_x_va_arg (tree expr, tree type)
*** 4495,4504 ****
  
    if (! pod_type_p (type))
      {
        /* Undefined behavior [expr.call] 5.2.2/7.  */
        warning (0, "cannot receive objects of non-POD type %q#T through %<...%>; "
  	       "call will abort at runtime", type);
!       expr = convert (build_pointer_type (type), null_node);
        expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr),
  		     call_builtin_trap (), expr);
        expr = build_indirect_ref (expr, NULL);
--- 4523,4534 ----
  
    if (! pod_type_p (type))
      {
+       /* Remove reference types so we don't ICE later on.  */
+       tree type1 = non_reference (type);
        /* Undefined behavior [expr.call] 5.2.2/7.  */
        warning (0, "cannot receive objects of non-POD type %q#T through %<...%>; "
  	       "call will abort at runtime", type);
!       expr = convert (build_pointer_type (type1), null_node);
        expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr),
  		     call_builtin_trap (), expr);
        expr = build_indirect_ref (expr, NULL);
*************** build_over_call (struct z_candidate *can
*** 4798,4803 ****
--- 4828,4839 ----
        tree type = TREE_VALUE (parm);
  
        conv = convs[i];
+ 
+       /* Don't make a copy here if build_call is going to.  */
+       if (conv->kind == ck_rvalue
+ 	  && !TREE_ADDRESSABLE (complete_type (type)))
+ 	conv = conv->u.next;
+ 
        val = convert_like_with_context
  	(conv, TREE_VALUE (arg), fn, i - is_method);
  
*************** build_new_method_call (tree instance, tr
*** 5442,5450 ****
  		 none-the-less evaluated.  */
  	      if (TREE_CODE (TREE_TYPE (cand->fn)) != METHOD_TYPE
  		  && !is_dummy_object (instance_ptr)
! 		  && TREE_SIDE_EFFECTS (instance))
  		call = build2 (COMPOUND_EXPR, TREE_TYPE (call),
! 			       instance, call);
  	    }
  	}
      }
--- 5478,5486 ----
  		 none-the-less evaluated.  */
  	      if (TREE_CODE (TREE_TYPE (cand->fn)) != METHOD_TYPE
  		  && !is_dummy_object (instance_ptr)
! 		  && TREE_SIDE_EFFECTS (instance_ptr))
  		call = build2 (COMPOUND_EXPR, TREE_TYPE (call),
! 			       instance_ptr, call);
  	    }
  	}
      }
*************** perform_implicit_conversion (tree type, 
*** 6353,6358 ****
--- 6389,6402 ----
        error ("could not convert %qE to %qT", expr, type);
        expr = error_mark_node;
      }
+   else if (processing_template_decl)
+     {
+       /* In a template, we are only concerned about determining the
+ 	 type of non-dependent expressions, so we do not have to
+ 	 perform the actual conversion.  */
+       if (TREE_TYPE (expr) != type)
+ 	expr = build_nop (type, expr);
+     }
    else
      expr = convert_like (conv, expr);
  
diff -Nrcpad gcc-4.1.1/gcc/cp/class.c gcc-4.1.2/gcc/cp/class.c
*** gcc-4.1.1/gcc/cp/class.c	Sat Feb 18 08:37:34 2006
--- gcc-4.1.2/gcc/cp/class.c	Wed Aug 30 15:52:12 2006
*************** check_field_decls (tree t, tree *access_
*** 2800,2805 ****
--- 2800,2806 ----
    tree *next;
    bool has_pointers;
    int any_default_members;
+   int cant_pack = 0;
  
    /* Assume there are no access declarations.  */
    *access_decls = NULL_TREE;
*************** check_field_decls (tree t, tree *access_
*** 2816,2855 ****
  
        next = &TREE_CHAIN (x);
  
-       if (TREE_CODE (x) == FIELD_DECL)
- 	{
- 	  if (TYPE_PACKED (t))
- 	    {
- 	      if (!pod_type_p (TREE_TYPE (x)) && !TYPE_PACKED (TREE_TYPE (x)))
- 		warning
- 		  (0,
- 		   "ignoring packed attribute on unpacked non-POD field %q+#D",
- 		   x);
- 	      else if (TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
- 		DECL_PACKED (x) = 1;
- 	    }
- 
- 	  if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
- 	    /* We don't treat zero-width bitfields as making a class
- 	       non-empty.  */
- 	    ;
- 	  else
- 	    {
- 	      tree element_type;
- 
- 	      /* The class is non-empty.  */
- 	      CLASSTYPE_EMPTY_P (t) = 0;
- 	      /* The class is not even nearly empty.  */
- 	      CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
- 	      /* If one of the data members contains an empty class,
- 		 so does T.  */
- 	      element_type = strip_array_types (type);
- 	      if (CLASS_TYPE_P (element_type)
- 		  && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))
- 		CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
- 	    }
- 	}
- 
        if (TREE_CODE (x) == USING_DECL)
  	{
  	  /* Prune the access declaration from the list of fields.  */
--- 2817,2822 ----
*************** check_field_decls (tree t, tree *access_
*** 2946,2951 ****
--- 2913,2949 ----
  
        type = strip_array_types (type);
  
+       if (TYPE_PACKED (t))
+ 	{
+ 	  if (!pod_type_p (type) && !TYPE_PACKED (type))
+ 	    {
+ 	      warning
+ 		(0,
+ 		 "ignoring packed attribute because of unpacked non-POD field %q+#D",
+ 		 x);
+ 	      cant_pack = 1;
+ 	    }
+ 	  else if (TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
+ 	    DECL_PACKED (x) = 1;
+ 	}
+ 
+       if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
+ 	/* We don't treat zero-width bitfields as making a class
+ 	   non-empty.  */
+ 	;
+       else
+ 	{
+ 	  /* The class is non-empty.  */
+ 	  CLASSTYPE_EMPTY_P (t) = 0;
+ 	  /* The class is not even nearly empty.  */
+ 	  CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+ 	  /* If one of the data members contains an empty class,
+ 	     so does T.  */
+ 	  if (CLASS_TYPE_P (type)
+ 	      && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
+ 	    CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
+ 	}
+ 
        /* This is used by -Weffc++ (see below). Warn only for pointers
  	 to members which might hold dynamic memory. So do not warn
  	 for pointers to functions or pointers to members.  */
*************** check_field_decls (tree t, tree *access_
*** 3030,3040 ****
  	is needed to free dynamic memory.
  
       This seems enough for practical purposes.  */
!     if (warn_ecpp
! 	&& has_pointers
! 	&& TYPE_HAS_CONSTRUCTOR (t)
! 	&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
! 	&& !(TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
      {
        warning (0, "%q#T has pointer data members", t);
  
--- 3028,3038 ----
  	is needed to free dynamic memory.
  
       This seems enough for practical purposes.  */
!   if (warn_ecpp
!       && has_pointers
!       && TYPE_HAS_CONSTRUCTOR (t)
!       && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
!       && !(TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
      {
        warning (0, "%q#T has pointer data members", t);
  
*************** check_field_decls (tree t, tree *access_
*** 3048,3053 ****
--- 3046,3054 ----
  	warning (0, "  but does not override %<operator=(const %T&)%>", t);
      }
  
+   /* If any of the fields couldn't be packed, unset TYPE_PACKED.  */
+   if (cant_pack)
+     TYPE_PACKED (t) = 0;
  
    /* Check anonymous struct/anonymous union fields.  */
    finish_struct_anon (t);
diff -Nrcpad gcc-4.1.1/gcc/cp/cp-gimplify.c gcc-4.1.2/gcc/cp/cp-gimplify.c
*** gcc-4.1.1/gcc/cp/cp-gimplify.c	Fri Feb 10 17:32:10 2006
--- gcc-4.1.2/gcc/cp/cp-gimplify.c	Sun Aug 13 19:26:38 2006
*************** is_invisiref_parm (tree t)
*** 589,594 ****
--- 589,612 ----
  	  && DECL_BY_REFERENCE (t));
  }
  
+ /* Return true if the uid in both int tree maps are equal.  */
+ 
+ int
+ cxx_int_tree_map_eq (const void *va, const void *vb)
+ {
+   const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va;
+   const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb;
+   return (a->uid == b->uid);
+ }
+ 
+ /* Hash a UID in a cxx_int_tree_map.  */
+ 
+ unsigned int
+ cxx_int_tree_map_hash (const void *item)
+ {
+   return ((const struct cxx_int_tree_map *)item)->uid;
+ }
+ 
  /* Perform any pre-gimplification lowering of C++ front end trees to
     GENERIC.  */
  
*************** cp_genericize_r (tree *stmt_p, int *walk
*** 608,613 ****
--- 626,650 ----
        return NULL;
      }
  
+   /* Map block scope extern declarations to visible declarations with the
+      same name and type in outer scopes if any.  */
+   if (cp_function_chain->extern_decl_map
+       && (TREE_CODE (stmt) == FUNCTION_DECL || TREE_CODE (stmt) == VAR_DECL)
+       && DECL_EXTERNAL (stmt))
+     {
+       struct cxx_int_tree_map *h, in;
+       in.uid = DECL_UID (stmt);
+       h = (struct cxx_int_tree_map *)
+ 	  htab_find_with_hash (cp_function_chain->extern_decl_map,
+ 			       &in, in.uid);
+       if (h)
+ 	{
+ 	  *stmt_p = h->to;
+ 	  *walk_subtrees = 0;
+ 	  return NULL;
+ 	}
+     }
+ 
    /* Other than invisiref parms, don't walk the same tree twice.  */
    if (pointer_set_contains (p_set, stmt))
      {
diff -Nrcpad gcc-4.1.1/gcc/cp/cp-tree.def gcc-4.1.2/gcc/cp/cp-tree.def
*** gcc-4.1.1/gcc/cp/cp-tree.def	Fri Sep 16 06:50:56 2005
--- gcc-4.1.2/gcc/cp/cp-tree.def	Wed Jun 14 19:08:08 2006
*************** DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "te
*** 168,174 ****
     BOUND_TEMPLATE_TEMPLATE_PARM.  */
  
  /* Index into a template parameter list.  This parameter must be a type.
!    The type.value field will be a TEMPLATE_PARM_INDEX.  */
  DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", tcc_type, 0)
  
  /* A type designated by `typename T::t'.  TYPE_CONTEXT is `T',
--- 168,174 ----
     BOUND_TEMPLATE_TEMPLATE_PARM.  */
  
  /* Index into a template parameter list.  This parameter must be a type.
!    The type.values field will be a TEMPLATE_PARM_INDEX.  */
  DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", tcc_type, 0)
  
  /* A type designated by `typename T::t'.  TYPE_CONTEXT is `T',
diff -Nrcpad gcc-4.1.1/gcc/cp/cp-tree.h gcc-4.1.2/gcc/cp/cp-tree.h
*** gcc-4.1.1/gcc/cp/cp-tree.h	Tue May 16 14:54:55 2006
--- gcc-4.1.2/gcc/cp/cp-tree.h	Sun Dec 10 23:48:13 2006
*************** struct saved_scope GTY(())
*** 719,724 ****
--- 719,733 ----
  
  extern GTY(()) struct saved_scope *scope_chain;
  
+ struct cxx_int_tree_map GTY(())
+ {
+   unsigned int uid;
+   tree to;
+ };
+ 
+ extern unsigned int cxx_int_tree_map_hash (const void *);
+ extern int cxx_int_tree_map_eq (const void *, const void *);
+ 
  /* Global state pertinent to the current function.  */
  
  struct language_function GTY(())
*************** struct language_function GTY(())
*** 746,751 ****
--- 755,761 ----
    struct named_label_list *x_named_labels;
    struct cp_binding_level *bindings;
    VEC(tree,gc) *x_local_names;
+   htab_t GTY((param_is (struct cxx_int_tree_map))) extern_decl_map;
  };
  
  /* The current C++-specific per-function global variables.  */
*************** struct lang_type GTY(())
*** 1106,1119 ****
  
  #endif /* ENABLE_TREE_CHECKING */
  
- /* Indicates whether or not (and how) a template was expanded for this class.
-      0=no information yet/non-template class
-      1=implicit template instantiation
-      2=explicit template specialization
-      3=explicit template instantiation  */
- #define CLASSTYPE_USE_TEMPLATE(NODE) \
-   (LANG_TYPE_CLASS_CHECK (NODE)->use_template)
- 
  /* Fields used for storing information before the class is defined.
     After the class is defined, these fields hold other information.  */
  
--- 1116,1121 ----
*************** extern void decl_shadowed_for_var_insert
*** 2072,2086 ****
    (DECL_LANG_SPECIFIC (DECL)->decl_flags.deferred)
  
  /* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or
!    TEMPLATE_DECL, the entity is a template specialization.  In that
!    case, DECL_TEMPLATE_INFO is a TREE_LIST, whose TREE_PURPOSE is the
!    TEMPLATE_DECL of which this entity is a specialization.  The TREE_
!    TREE_VALUE is the template arguments used to specialize the
!    template.  
  
!    In general, DECL_TEMPLATE_INFO is non-NULL only if
!    DECL_USE_TEMPLATE is nonzero.  However, for friends, we sometimes
!    have DECL_TEMPLATE_INFO even when DECL_USE_TEMPLATE is zero.
     Consider:
  
        template <typename T> struct S { friend void f(T) {} };
--- 2074,2088 ----
    (DECL_LANG_SPECIFIC (DECL)->decl_flags.deferred)
  
  /* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or
!    TEMPLATE_DECL, the entity is either a template specialization (if
!    DECL_USE_TEMPLATE is non-zero) or the abstract instance of the
!    template itself.
  
!    In either case, DECL_TEMPLATE_INFO is a TREE_LIST, whose
!    TREE_PURPOSE is the TEMPLATE_DECL of which this entity is a
!    specialization or abstract instance.  The TREE_VALUE is the
!    template arguments used to specialize the template.
!    
     Consider:
  
        template <typename T> struct S { friend void f(T) {} };
*************** extern void decl_shadowed_for_var_insert
*** 2088,2094 ****
     In this case, S<int>::f is, from the point of view of the compiler,
     an instantiation of a template -- but, from the point of view of
     the language, each instantiation of S results in a wholly unrelated
!    global function f.  */ 
  #define DECL_TEMPLATE_INFO(NODE) \
    (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \
     ->decl_flags.u.template_info)
--- 2090,2097 ----
     In this case, S<int>::f is, from the point of view of the compiler,
     an instantiation of a template -- but, from the point of view of
     the language, each instantiation of S results in a wholly unrelated
!    global function f.  In this case, DECL_TEMPLATE_INFO for S<int>::f
!    will be non-NULL, but DECL_USE_TEMPLATE will be zero.  */
  #define DECL_TEMPLATE_INFO(NODE) \
    (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \
     ->decl_flags.u.template_info)
*************** extern void decl_shadowed_for_var_insert
*** 2216,2221 ****
--- 2219,2234 ----
     are always the full set of arguments required to instantiate this
     declaration from the most general template specialized here.  */
  #define DECL_TI_ARGS(NODE)	    TI_ARGS (DECL_TEMPLATE_INFO (NODE))
+ 
+ /* The TEMPLATE_DECL associated with NODE, a class type.  Even if NODE
+    will be generated from a partial specialization, the TEMPLATE_DECL
+    referred to here will be the original template.  For example,
+    given:
+ 
+       template <typename T> struct S {};
+       template <typename T> struct S<T*> {};
+       
+    the CLASSTPYE_TI_TEMPLATE for S<int*> will be S, not the S<T*>.  */
  #define CLASSTYPE_TI_TEMPLATE(NODE) TI_TEMPLATE (CLASSTYPE_TEMPLATE_INFO (NODE))
  #define CLASSTYPE_TI_ARGS(NODE)     TI_ARGS (CLASSTYPE_TEMPLATE_INFO (NODE))
  
*************** extern void decl_shadowed_for_var_insert
*** 2228,2234 ****
  				      (CLASSTYPE_TI_TEMPLATE ((TYPE))))) \
     : (TYPE))
  
! /* Like DECL_TI_TEMPLATE, but for an ENUMERAL_, RECORD_, or UNION_TYPE.  */
  #define TYPE_TI_TEMPLATE(NODE)			\
    (TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE)))
  
--- 2241,2247 ----
  				      (CLASSTYPE_TI_TEMPLATE ((TYPE))))) \
     : (TYPE))
  
! /* Like CLASS_TI_TEMPLATE, but also works for ENUMERAL_TYPEs.  */
  #define TYPE_TI_TEMPLATE(NODE)			\
    (TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE)))
  
*************** extern void decl_shadowed_for_var_insert
*** 2498,2527 ****
  /* Returns true if NODE is a pointer.  */
  #define TYPE_PTR_P(NODE)			\
    (TREE_CODE (NODE) == POINTER_TYPE)
  /* Returns true if NODE is a pointer to an object.  Keep these checks
     in ascending tree code order.  */
  #define TYPE_PTROB_P(NODE)					\
!   (TYPE_PTR_P (NODE)						\
!    && !(TREE_CODE (TREE_TYPE (NODE)) == VOID_TYPE		\
! 	|| TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE	\
! 	|| TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE))
  /* Returns true if NODE is a reference to an object.  Keep these checks
     in ascending tree code order.  */
  #define TYPE_REF_OBJ_P(NODE)					\
!   (TREE_CODE (NODE) == REFERENCE_TYPE				\
!    && !(TREE_CODE (TREE_TYPE (NODE)) == VOID_TYPE		\
! 	|| TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE	\
! 	|| TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE))
  /* Returns true if NODE is a pointer to an object, or a pointer to
     void.  Keep these checks in ascending tree code order.  */
  #define TYPE_PTROBV_P(NODE)					\
    (TYPE_PTR_P (NODE)						\
     && !(TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE		\
  	|| TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE))
  /* Returns true if NODE is a pointer to function.  */
  #define TYPE_PTRFN_P(NODE)				\
    (TREE_CODE (NODE) == POINTER_TYPE			\
     && TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)
  /* Returns true if NODE is a reference to function.  */
  #define TYPE_REFFN_P(NODE)				\
    (TREE_CODE (NODE) == REFERENCE_TYPE			\
--- 2511,2553 ----
  /* Returns true if NODE is a pointer.  */
  #define TYPE_PTR_P(NODE)			\
    (TREE_CODE (NODE) == POINTER_TYPE)
+ 
+ /* Returns true if NODE is an object type:
+ 
+      [basic.types]
+ 
+      An object type is a (possibly cv-qualified) type that is not a
+      function type, not a reference type, and not a void type.  
+ 
+    Keep these checks in ascending order, for speed.  */
+ #define TYPE_OBJ_P(NODE)			\
+   (TREE_CODE (NODE) != REFERENCE_TYPE		\
+    && TREE_CODE (NODE) != VOID_TYPE		\
+    && TREE_CODE (NODE) != FUNCTION_TYPE		\
+    && TREE_CODE (NODE) != METHOD_TYPE)
+ 
  /* Returns true if NODE is a pointer to an object.  Keep these checks
     in ascending tree code order.  */
  #define TYPE_PTROB_P(NODE)					\
!   (TYPE_PTR_P (NODE) && TYPE_OBJ_P (TREE_TYPE (NODE)))
! 
  /* Returns true if NODE is a reference to an object.  Keep these checks
     in ascending tree code order.  */
  #define TYPE_REF_OBJ_P(NODE)					\
!   (TREE_CODE (NODE) == REFERENCE_TYPE && TYPE_OBJ_P (TREE_TYPE (NODE)))
! 
  /* Returns true if NODE is a pointer to an object, or a pointer to
     void.  Keep these checks in ascending tree code order.  */
  #define TYPE_PTROBV_P(NODE)					\
    (TYPE_PTR_P (NODE)						\
     && !(TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE		\
  	|| TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE))
+ 
  /* Returns true if NODE is a pointer to function.  */
  #define TYPE_PTRFN_P(NODE)				\
    (TREE_CODE (NODE) == POINTER_TYPE			\
     && TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)
+ 
  /* Returns true if NODE is a reference to function.  */
  #define TYPE_REFFN_P(NODE)				\
    (TREE_CODE (NODE) == REFERENCE_TYPE			\
*************** extern void decl_shadowed_for_var_insert
*** 2805,2821 ****
  /* Returns nonzero if NODE is a primary template.  */
  #define PRIMARY_TEMPLATE_P(NODE) (DECL_PRIMARY_TEMPLATE (NODE) == (NODE))
  
! /* Indicates whether or not (and how) a template was expanded for this
!    FUNCTION_DECL or VAR_DECL.
!      0=normal declaration, e.g. int min (int, int);
!      1=implicit template instantiation
!      2=explicit template specialization, e.g. int min<int> (int, int);
!      3=explicit template instantiation, e.g. template int min<int> (int, int);
  
!    If DECL_USE_TEMPLATE is nonzero, then DECL_TEMPLATE_INFO will also
     be non-NULL.  */
  #define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.use_template)
  
  #define DECL_TEMPLATE_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) & 1)
  #define CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \
    (CLASSTYPE_USE_TEMPLATE (NODE) & 1)
--- 2831,2874 ----
  /* Returns nonzero if NODE is a primary template.  */
  #define PRIMARY_TEMPLATE_P(NODE) (DECL_PRIMARY_TEMPLATE (NODE) == (NODE))
  
! /* Non-zero iff NODE is a specialization of a template.  The value
!    indicates the type of specializations:
  
!      1=implicit instantiation
! 
!      2=partial or explicit specialization, e.g.:
! 
!         template <> int min<int> (int, int),
! 
!      3=explicit instantiation, e.g.:
!   
!         template int min<int> (int, int);
! 
!    Note that NODE will be marked as a specialization even if the
!    template it is instantiating is not a primary template.  For
!    example, given:
! 
!      template <typename T> struct O { 
!        void f();
!        struct I {}; 
!      };
!     
!    both O<int>::f and O<int>::I will be marked as instantiations.
! 
!    If DECL_USE_TEMPLATE is non-zero, then DECL_TEMPLATE_INFO will also
     be non-NULL.  */
  #define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.use_template)
  
+ /* Like DECL_USE_TEMPLATE, but for class types.  */
+ #define CLASSTYPE_USE_TEMPLATE(NODE) \
+   (LANG_TYPE_CLASS_CHECK (NODE)->use_template)
+ 
+ /* True if NODE is a specialization of a primary template.  */
+ #define CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P(NODE)	\
+   (CLASS_TYPE_P (NODE)						\
+    && CLASSTYPE_USE_TEMPLATE (NODE)				\
+    && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (arg)))  
+ 
  #define DECL_TEMPLATE_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) & 1)
  #define CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \
    (CLASSTYPE_USE_TEMPLATE (NODE) & 1)
*************** extern GTY(()) tree static_dtors;
*** 3301,3346 ****
  
  enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
  
! /* These are uses as bits in flags passed to build_new_method_call
!    to control its error reporting behavior.
! 
!    LOOKUP_PROTECT means flag access violations.
!    LOOKUP_COMPLAIN mean complain if no suitable member function
!      matching the arguments is found.
!    LOOKUP_NORMAL is just a combination of these two.
!    LOOKUP_NONVIRTUAL means make a direct call to the member function found
!    LOOKUP_ONLYCONVERTING means that non-conversion constructors are not tried.
!    DIRECT_BIND means that if a temporary is created, it should be created so
!      that it lives as long as the current variable bindings; otherwise it
!      only lives until the end of the complete-expression.  It also forces
!      direct-initialization in cases where other parts of the compiler have
!      already generated a temporary, such as reference initialization and the
!      catch parameter.
!    LOOKUP_NO_CONVERSION means that user-defined conversions are not
!      permitted.  Built-in conversions are permitted.
!    LOOKUP_DESTRUCTOR means explicit call to destructor.
!    LOOKUP_NO_TEMP_BIND means temporaries will not be bound to references.
! 
!    These are used in global lookup to support elaborated types and
!    qualifiers.
! 
!    LOOKUP_PREFER_TYPES means not to accept objects, and possibly namespaces.
!    LOOKUP_PREFER_NAMESPACES means not to accept objects, and possibly types.
!    LOOKUP_PREFER_BOTH means class-or-namespace-name.  */
! 
  #define LOOKUP_PROTECT (1 << 0)
  #define LOOKUP_COMPLAIN (1 << 1)
  #define LOOKUP_NORMAL (LOOKUP_PROTECT | LOOKUP_COMPLAIN)
  #define LOOKUP_NONVIRTUAL (1 << 2)
  #define LOOKUP_ONLYCONVERTING (1 << 3)
  #define DIRECT_BIND (1 << 4)
  #define LOOKUP_NO_CONVERSION (1 << 5)
  #define LOOKUP_DESTRUCTOR (1 << 6)
  #define LOOKUP_NO_TEMP_BIND (1 << 7)
  #define LOOKUP_PREFER_TYPES (1 << 8)
  #define LOOKUP_PREFER_NAMESPACES (1 << 9)
  #define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES)
  #define LOOKUP_CONSTRUCTOR_CALLABLE (1 << 10)
  
  #define LOOKUP_NAMESPACES_ONLY(F)  \
    (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
--- 3354,3404 ----
  
  enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
  
! /* These are uses as bits in flags passed to various functions to
!    control their behavior.  Despite the LOOKUP_ prefix, many of these
!    do not control name lookup.  ??? Functions using these flags should
!    probably be modified to accept explicit boolean flags for the
!    behaviors relevant to them.  */
! /* Check for access violations.  */
  #define LOOKUP_PROTECT (1 << 0)
+ /* Complain if no suitable member function matching the arguments is
+    found.  */
  #define LOOKUP_COMPLAIN (1 << 1)
  #define LOOKUP_NORMAL (LOOKUP_PROTECT | LOOKUP_COMPLAIN)
+ /* Even if the function found by lookup is a virtual function, it
+    should be called directly.  */
  #define LOOKUP_NONVIRTUAL (1 << 2)
+ /* Non-converting (i.e., "explicit") constructors are not tried.  */
  #define LOOKUP_ONLYCONVERTING (1 << 3)
+ /* If a temporary is created, it should be created so that it lives
+    as long as the current variable bindings; otherwise it only lives
+    until the end of the complete-expression.  It also forces
+    direct-initialization in cases where other parts of the compiler
+    have already generated a temporary, such as reference
+    initialization and the catch parameter.  */
  #define DIRECT_BIND (1 << 4)
+ /* User-defined conversions are not permitted.  (Built-in conversions
+    are permitted.)  */
  #define LOOKUP_NO_CONVERSION (1 << 5)
+ /* The user has explicitly called a destructor.  (Therefore, we do
+    not need to check that the object is non-NULL before calling the
+    destructor.)  */
  #define LOOKUP_DESTRUCTOR (1 << 6)
+ /* Do not permit references to bind to temporaries.  */
  #define LOOKUP_NO_TEMP_BIND (1 << 7)
+ /* Do not accept objects, and possibly namespaces.  */
  #define LOOKUP_PREFER_TYPES (1 << 8)
+ /* Do not accept objects, and possibly types.   */
  #define LOOKUP_PREFER_NAMESPACES (1 << 9)
+ /* Accept types or namespaces.  */
  #define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES)
+ /* We are checking that a constructor can be called -- but we do not
+    actually plan to call it.  */
  #define LOOKUP_CONSTRUCTOR_CALLABLE (1 << 10)
+ /* Return friend decarations and un-declared builtin functions.
+    (Normally, these entities are registered in the symbol table, but
+    not found by lookup.)  */
+ #define LOOKUP_HIDDEN (LOOKUP_CONSTRUCTOR_CALLABLE << 1)
  
  #define LOOKUP_NAMESPACES_ONLY(F)  \
    (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
*************** enum overload_flags { NO_SPECIAL = 0, DT
*** 3378,3384 ****
  #define WANT_ENUM	4 /* enumerated types */
  #define WANT_POINTER	8 /* pointer types */
  #define WANT_NULL      16 /* null pointer constant */
! #define WANT_ARITH	(WANT_INT | WANT_FLOAT)
  
  /* Used with comptypes, and related functions, to guide type
     comparison.  */
--- 3436,3443 ----
  #define WANT_ENUM	4 /* enumerated types */
  #define WANT_POINTER	8 /* pointer types */
  #define WANT_NULL      16 /* null pointer constant */
! #define WANT_VECTOR    32 /* vector types */
! #define WANT_ARITH	(WANT_INT | WANT_FLOAT | WANT_VECTOR)
  
  /* Used with comptypes, and related functions, to guide type
     comparison.  */
*************** extern void initialize_artificial_var		(
*** 3870,3877 ****
  extern tree check_var_type			(tree, tree);
  extern tree reshape_init (tree, tree);
  
- extern bool have_extern_spec;
- 
  /* in decl2.c */
  extern bool check_java_method			(tree);
  extern cp_cv_quals grok_method_quals		(tree, tree, cp_cv_quals);
--- 3929,3934 ----
*************** extern int template_class_depth			(tree)
*** 4042,4048 ****
  extern int is_specialization_of			(tree, tree);
  extern bool is_specialization_of_friend		(tree, tree);
  extern int comp_template_args			(tree, tree);
! extern void maybe_process_partial_specialization (tree);
  extern tree most_specialized_instantiation	(tree);
  extern void print_candidates			(tree);
  extern void instantiate_pending_templates	(int);
--- 4099,4105 ----
  extern int is_specialization_of			(tree, tree);
  extern bool is_specialization_of_friend		(tree, tree);
  extern int comp_template_args			(tree, tree);
! extern tree maybe_process_partial_specialization (tree);
  extern tree most_specialized_instantiation	(tree);
  extern void print_candidates			(tree);
  extern void instantiate_pending_templates	(int);
*************** extern tree build_non_dependent_args		(t
*** 4070,4075 ****
--- 4127,4133 ----
  extern bool reregister_specialization		(tree, tree, tree);
  extern tree fold_non_dependent_expr		(tree);
  extern tree fold_decl_constant_value		(tree);
+ extern bool explicit_class_specialization_p     (tree);
  
  /* in repo.c */
  extern void init_repo				(void);
*************** extern void finish_try_block			(tree);
*** 4174,4182 ****
  extern tree begin_eh_spec_block			(void);
  extern void finish_eh_spec_block		(tree, tree);
  extern void finish_handler_sequence		(tree);
! extern tree begin_function_try_block		(void);
  extern void finish_function_try_block		(tree);
! extern void finish_function_handler_sequence    (tree);
  extern void finish_cleanup_try_block		(tree);
  extern tree begin_handler			(void);
  extern void finish_handler_parms		(tree, tree);
--- 4232,4240 ----
  extern tree begin_eh_spec_block			(void);
  extern void finish_eh_spec_block		(tree, tree);
  extern void finish_handler_sequence		(tree);
! extern tree begin_function_try_block		(tree *);
  extern void finish_function_try_block		(tree);
! extern void finish_function_handler_sequence    (tree, tree);
  extern void finish_cleanup_try_block		(tree);
  extern tree begin_handler			(void);
  extern void finish_handler_parms		(tree, tree);
*************** extern tree finish_id_expression		(tree,
*** 4223,4228 ****
--- 4281,4287 ----
  						 bool, bool, bool, bool,
  						 const char **);
  extern tree finish_typeof			(tree);
+ extern tree finish_offsetof			(tree);
  extern void finish_decl_cleanup			(tree, tree);
  extern void finish_eh_cleanup			(tree);
  extern void expand_body				(tree);
diff -Nrcpad gcc-4.1.1/gcc/cp/cvt.c gcc-4.1.2/gcc/cp/cvt.c
*** gcc-4.1.1/gcc/cp/cvt.c	Wed Apr 19 17:19:35 2006
--- gcc-4.1.2/gcc/cp/cvt.c	Tue Nov 21 10:53:03 2006
*************** convert_to_void (tree expr, const char *
*** 863,876 ****
  	int is_volatile = TYPE_VOLATILE (type);
  	int is_complete = COMPLETE_TYPE_P (complete_type (type));
  
  	if (is_volatile && !is_complete)
  	  warning (0, "object of incomplete type %qT will not be accessed in %s",
  		   type, implicit ? implicit : "void context");
! 	else if (is_reference && is_volatile)
  	  warning (0, "object of type %qT will not be accessed in %s",
  		   TREE_TYPE (TREE_OPERAND (expr, 0)),
  		   implicit ? implicit : "void context");
! 	if (is_reference || !is_volatile || !is_complete)
  	  expr = TREE_OPERAND (expr, 0);
  
  	break;
--- 863,879 ----
  	int is_volatile = TYPE_VOLATILE (type);
  	int is_complete = COMPLETE_TYPE_P (complete_type (type));
  
+ 	/* Can't load the value if we don't know the type.  */
  	if (is_volatile && !is_complete)
  	  warning (0, "object of incomplete type %qT will not be accessed in %s",
  		   type, implicit ? implicit : "void context");
! 	/* Don't load the value if this is an implicit dereference, or if
! 	   the type needs to be handled by ctors/dtors.  */
! 	else if (is_volatile && (is_reference || TREE_ADDRESSABLE (type)))
  	  warning (0, "object of type %qT will not be accessed in %s",
  		   TREE_TYPE (TREE_OPERAND (expr, 0)),
  		   implicit ? implicit : "void context");
! 	if (is_reference || !is_volatile || !is_complete || TREE_ADDRESSABLE (type))
  	  expr = TREE_OPERAND (expr, 0);
  
  	break;
*************** convert_to_void (tree expr, const char *
*** 904,912 ****
  	expr = void_zero_node;
        }
      else if (implicit && probe == expr && is_overloaded_fn (probe))
!       /* Only warn when there is no &.  */
!       warning (0, "%s is a reference, not call, to function %qE",
! 		  implicit, expr);
    }
  
    if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
--- 907,919 ----
  	expr = void_zero_node;
        }
      else if (implicit && probe == expr && is_overloaded_fn (probe))
!       {
! 	/* Only warn when there is no &.  */
! 	warning (0, "%s is a reference, not call, to function %qE",
! 		 implicit, expr);
! 	if (TREE_CODE (expr) == COMPONENT_REF)
! 	  expr = TREE_OPERAND (expr, 0);
!       }
    }
  
    if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
*************** convert_to_void (tree expr, const char *
*** 956,961 ****
--- 963,970 ----
  	}
        expr = build1 (CONVERT_EXPR, void_type_node, expr);
      }
+   if (! TREE_SIDE_EFFECTS (expr))
+     expr = void_zero_node;
    return expr;
  }
  
*************** build_expr_type_conversion (int desires,
*** 1074,1080 ****
  	  return expr;
  	/* else fall through...  */
  
-       case VECTOR_TYPE:
        case BOOLEAN_TYPE:
  	return (desires & WANT_INT) ? expr : NULL_TREE;
        case ENUMERAL_TYPE:
--- 1083,1088 ----
*************** build_expr_type_conversion (int desires,
*** 1088,1093 ****
--- 1096,1118 ----
        case ARRAY_TYPE:
  	return (desires & WANT_POINTER) ? decay_conversion (expr)
  					: NULL_TREE;
+ 
+       case VECTOR_TYPE:
+ 	if ((desires & WANT_VECTOR) == 0)
+ 	  return NULL_TREE;
+ 	switch (TREE_CODE (TREE_TYPE (basetype)))
+ 	  {
+ 	  case INTEGER_TYPE:
+ 	  case BOOLEAN_TYPE:
+ 	    return (desires & WANT_INT) ? expr : NULL_TREE;
+ 	  case ENUMERAL_TYPE:
+ 	    return (desires & WANT_ENUM) ? expr : NULL_TREE;
+ 	  case REAL_TYPE:
+ 	    return (desires & WANT_FLOAT) ? expr : NULL_TREE;
+ 	  default:
+ 	    return NULL_TREE;
+ 	  }
+ 
        default:
  	return NULL_TREE;
        }
*************** build_expr_type_conversion (int desires,
*** 1122,1127 ****
--- 1147,1169 ----
  	case POINTER_TYPE:
  	  win = (desires & WANT_POINTER); break;
  
+ 	case VECTOR_TYPE:
+ 	  if ((desires & WANT_VECTOR) == 0)
+ 	    break;
+ 	  switch (TREE_CODE (TREE_TYPE (candidate)))
+ 	    {
+ 	    case BOOLEAN_TYPE:
+ 	    case INTEGER_TYPE:
+ 	      win = (desires & WANT_INT); break;
+ 	    case ENUMERAL_TYPE:
+ 	      win = (desires & WANT_ENUM); break;
+ 	    case REAL_TYPE:
+ 	      win = (desires & WANT_FLOAT); break;
+ 	    default:
+ 	      break;
+ 	    }
+ 	  break;
+ 
  	default:
  	  break;
  	}
diff -Nrcpad gcc-4.1.1/gcc/cp/decl.c gcc-4.1.2/gcc/cp/decl.c
*** gcc-4.1.1/gcc/cp/decl.c	Thu May 11 14:45:56 2006
--- gcc-4.1.2/gcc/cp/decl.c	Fri Feb  9 02:52:53 2007
*************** enum deprecated_states {
*** 227,236 ****
  
  static enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
  
- /* True if a declaration with an `extern' linkage specifier is being
-    processed.  */
- bool have_extern_spec;
- 
  
  /* A TREE_LIST of VAR_DECLs.  The TREE_PURPOSE is a RECORD_TYPE or
     UNION_TYPE; the TREE_VALUE is a VAR_DECL with that type.  At the
--- 227,232 ----
*************** decls_match (tree newdecl, tree olddecl)
*** 941,947 ****
        /* Need to check scope for variable declaration (VAR_DECL).
  	 For typedef (TYPE_DECL), scope is ignored.  */
        if (TREE_CODE (newdecl) == VAR_DECL
! 	  && CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl))
  	return 0;
  
        if (TREE_TYPE (newdecl) == error_mark_node)
--- 937,949 ----
        /* Need to check scope for variable declaration (VAR_DECL).
  	 For typedef (TYPE_DECL), scope is ignored.  */
        if (TREE_CODE (newdecl) == VAR_DECL
! 	  && CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)
! 	  /* [dcl.link]
! 	     Two declarations for an object with C language linkage
! 	     with the same name (ignoring the namespace that qualify
! 	     it) that appear in different namespace scopes refer to
! 	     the same object.  */
! 	  && !(DECL_EXTERN_C_P (olddecl) && DECL_EXTERN_C_P (newdecl)))
  	return 0;
  
        if (TREE_TYPE (newdecl) == error_mark_node)
*************** duplicate_decls (tree newdecl, tree oldd
*** 1396,1409 ****
  	  warning (0, "prototype for %q+#D", newdecl);
  	  warning (0, "%Jfollows non-prototype definition here", olddecl);
  	}
!       else if (TREE_CODE (olddecl) == FUNCTION_DECL
  	       && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl))
  	{
! 	  /* extern "C" int foo ();
! 	     int foo () { bar (); }
! 	     is OK.  */
  	  if (current_lang_depth () == 0)
! 	    SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl));
  	  else
  	    {
  	      error ("previous declaration of %q+#D with %qL linkage",
--- 1398,1439 ----
  	  warning (0, "prototype for %q+#D", newdecl);
  	  warning (0, "%Jfollows non-prototype definition here", olddecl);
  	}
!       else if ((TREE_CODE (olddecl) == FUNCTION_DECL
! 		|| TREE_CODE (olddecl) == VAR_DECL)
  	       && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl))
  	{
! 	  /* [dcl.link]
! 	     If two declarations of the same function or object
! 	     specify different linkage-specifications ..., the program
! 	     is ill-formed.... Except for functions with C++ linkage,
! 	     a function declaration without a linkage specification
! 	     shall not precede the first linkage specification for
! 	     that function.  A function can be declared without a
! 	     linkage specification after an explicit linkage
! 	     specification has been seen; the linkage explicitly
! 	     specified in the earlier declaration is not affected by
! 	     such a function declaration.
! 
! 	     DR 563 raises the question why the restrictions on
! 	     functions should not also apply to objects.  Older
! 	     versions of G++ silently ignore the linkage-specification
! 	     for this example:
! 
! 	       namespace N { 
!                  extern int i;
!    	         extern "C" int i;
!                }
! 
!              which is clearly wrong.  Therefore, we now treat objects
! 	     like functions.  */
  	  if (current_lang_depth () == 0)
! 	    {
! 	      /* There is no explicit linkage-specification, so we use
! 		 the linkage from the previous declaration.  */
! 	      if (!DECL_LANG_SPECIFIC (newdecl))
! 		retrofit_lang_decl (newdecl);
! 	      SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl));
! 	    }
  	  else
  	    {
  	      error ("previous declaration of %q+#D with %qL linkage",
*************** duplicate_decls (tree newdecl, tree oldd
*** 1591,1596 ****
--- 1621,1629 ----
  	check_redeclaration_exception_specification (newdecl, olddecl);
        TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype;
  
+       if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ 	check_default_args (newdecl);
+ 
        /* Lay the type out, unless already done.  */
        if (! same_type_p (newtype, oldtype)
  	  && TREE_TYPE (newdecl) != error_mark_node
*************** define_label (location_t location, tree 
*** 2385,2391 ****
      pedwarn ("label named wchar_t");
  
    if (DECL_INITIAL (decl) != NULL_TREE)
!     error ("duplicate label %qD", decl);
    else
      {
        /* Mark label as having been defined.  */
--- 2418,2427 ----
      pedwarn ("label named wchar_t");
  
    if (DECL_INITIAL (decl) != NULL_TREE)
!     {
!       error ("duplicate label %qD", decl);
!       POP_TIMEVAR_AND_RETURN(TV_NAME_LOOKUP, error_mark_node);
!     }
    else
      {
        /* Mark label as having been defined.  */
*************** make_typename_type (tree context, tree n
*** 2610,2615 ****
--- 2646,2653 ----
  		    tsubst_flags_t complain)
  {
    tree fullname;
+   tree t;
+   bool want_template;
  
    if (name == error_mark_node
        || context == NULL_TREE
*************** make_typename_type (tree context, tree n
*** 2638,2643 ****
--- 2676,2686 ----
        name = TREE_OPERAND (name, 0);
        if (TREE_CODE (name) == TEMPLATE_DECL)
  	name = TREE_OPERAND (fullname, 0) = DECL_NAME (name);
+       else if (TREE_CODE (name) == OVERLOAD)
+ 	{
+ 	  error ("%qD is not a type", name);
+ 	  return error_mark_node;
+ 	}
      }
    if (TREE_CODE (name) == TEMPLATE_DECL)
      {
*************** make_typename_type (tree context, tree n
*** 2647,2719 ****
    gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
    gcc_assert (TYPE_P (context));
  
!   if (!dependent_type_p (context)
!       || currently_open_class (context))
!     {
!       if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR)
! 	{
! 	  tree tmpl = NULL_TREE;
! 	  if (IS_AGGR_TYPE (context))
! 	    tmpl = lookup_field (context, name, 0, false);
! 	  if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
! 	    {
! 	      if (complain & tf_error)
! 		error ("no class template named %q#T in %q#T",
! 		       name, context);
! 	      return error_mark_node;
! 	    }
! 
! 	  if (complain & tf_error)
! 	    perform_or_defer_access_check (TYPE_BINFO (context), tmpl);
! 
! 	  return lookup_template_class (tmpl,
! 					TREE_OPERAND (fullname, 1),
! 					NULL_TREE, context,
! 					/*entering_scope=*/0,
! 					tf_error | tf_warning | tf_user);
! 	}
!       else
! 	{
! 	  tree t;
! 
! 	  if (!IS_AGGR_TYPE (context))
! 	    {
! 	      if (complain & tf_error)
! 		error ("no type named %q#T in %q#T", name, context);
! 	      return error_mark_node;
! 	    }
! 
! 	  t = lookup_field (context, name, 0, true);
! 	  if (t)
! 	    {
! 	      if (TREE_CODE (t) != TYPE_DECL)
! 		{
! 		  if (complain & tf_error)
! 		    error ("no type named %q#T in %q#T", name, context);
! 		  return error_mark_node;
! 		}
! 
! 	      if (complain & tf_error)
! 		perform_or_defer_access_check (TYPE_BINFO (context), t);
! 
! 	      if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
! 		t = TREE_TYPE (t);
  
! 	      return t;
! 	    }
! 	}
      }
! 
!   /* If the CONTEXT is not a template type, then either the field is
!      there now or its never going to be.  */
!   if (!dependent_type_p (context))
      {
        if (complain & tf_error)
! 	error ("no type named %q#T in %q#T", name, context);
        return error_mark_node;
      }
  
!   return build_typename_type (context, name, fullname, tag_type);
  }
  
  /* Resolve `CONTEXT::template NAME'.  Returns a TEMPLATE_DECL if the name
--- 2690,2749 ----
    gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
    gcc_assert (TYPE_P (context));
  
!   /* When the CONTEXT is a dependent type,  NAME could refer to a
!      dependent base class of CONTEXT.  So we cannot peek inside it,
!      even if CONTEXT is a currently open scope.  */
!   if (dependent_type_p (context))
!     return build_typename_type (context, name, fullname, tag_type);
  
!   if (!IS_AGGR_TYPE (context))
!     {
!       if (complain & tf_error)
! 	error ("%q#T is not a class", context);
!       return error_mark_node;
      }
!   
!   want_template = TREE_CODE (fullname) == TEMPLATE_ID_EXPR;
!   
!   /* We should only set WANT_TYPE when we're a nested typename type.
!      Then we can give better diagnostics if we find a non-type.  */
!   t = lookup_field (context, name, 0, /*want_type=*/true);
!   if (!t)
      {
        if (complain & tf_error)
! 	error (want_template ? "no class template named %q#T in %q#T"
! 	       : "no type named %q#T in %q#T", name, context);
        return error_mark_node;
      }
+   
+   if (want_template && !DECL_CLASS_TEMPLATE_P (t))
+     {
+       if (complain & tf_error)
+ 	error ("%<typename %T::%D%> names %q#T, which is not a class template",
+ 	       context, name, t);
+       return error_mark_node;
+     }
+   if (!want_template && TREE_CODE (t) != TYPE_DECL)
+     {
+       if (complain & tf_error)
+ 	error ("%<typename %T::%D%> names %q#T, which is not a type",
+ 	       context, name, t);
+       return error_mark_node;
+     }
+   
+   if (complain & tf_error)
+     perform_or_defer_access_check (TYPE_BINFO (context), t);
  
!   if (want_template)
!     return lookup_template_class (t, TREE_OPERAND (fullname, 1),
! 				  NULL_TREE, context,
! 				  /*entering_scope=*/0,
! 				  tf_error | tf_warning | tf_user);
!   
!   if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
!     t = TREE_TYPE (t);
!   
!   return t;
  }
  
  /* Resolve `CONTEXT::template NAME'.  Returns a TEMPLATE_DECL if the name
*************** start_decl (const cp_declarator *declara
*** 3654,3666 ****
  
    *pushed_scope_p = NULL_TREE;
  
-   /* This should only be done once on the top most decl.  */
-   if (have_extern_spec)
-     {
-       declspecs->storage_class = sc_extern;
-       have_extern_spec = false;
-     }
- 
    /* An object declared as __attribute__((deprecated)) suppresses
       warnings of uses of other deprecated items.  */
    if (lookup_attribute ("deprecated", attributes))
--- 3684,3689 ----
*************** start_decl (const cp_declarator *declara
*** 3698,3705 ****
        {
        case TYPE_DECL:
  	error ("typedef %qD is initialized (use __typeof__ instead)", decl);
! 	initialized = 0;
! 	break;
  
        case FUNCTION_DECL:
  	error ("function %q#D is initialized like a variable", decl);
--- 3721,3727 ----
        {
        case TYPE_DECL:
  	error ("typedef %qD is initialized (use __typeof__ instead)", decl);
! 	return error_mark_node;
  
        case FUNCTION_DECL:
  	error ("function %q#D is initialized like a variable", decl);
*************** grok_reference_init (tree decl, tree typ
*** 3973,3978 ****
--- 3995,4022 ----
    return NULL_TREE;
  }
  
+ /* Designated initializers in arrays are not supported in GNU C++.
+    The parser cannot detect this error since it does not know whether
+    a given brace-enclosed initializer is for a class type or for an
+    array.  This function checks that CE does not use a designated
+    initializer.  If it does, an error is issued.  Returns true if CE
+    is valid, i.e., does not have a designated initializer.  */
+ 
+ static bool
+ check_array_designated_initializer (const constructor_elt *ce)
+ {
+   /* Designated initializers for array elements arenot supported.  */
+   if (ce->index)
+     {
+       if (TREE_CODE (ce->index) == IDENTIFIER_NODE)
+ 	error ("name %qD used in a GNU-style designated "
+ 	       "initializer for an array", ce->index);
+       return false;
+     }
+ 
+   return true;
+ }
+ 
  /* When parsing `int a[] = {1, 2};' we don't know the size of the
     array until we finish parsing the initializer.  If that's the
     situation we're in, update DECL accordingly.  */
*************** maybe_deduce_size_from_array_init (tree 
*** 3990,4015 ****
  	 But let's leave it here to ease the eventual merge.  */
        int do_default = !DECL_EXTERNAL (decl);
        tree initializer = init ? init : DECL_INITIAL (decl);
!       int failure = cp_complete_array_type (&TREE_TYPE (decl), initializer,
! 					    do_default);
! 
!       if (failure == 1)
! 	error ("initializer fails to determine size of %qD", decl);
  
!       if (failure == 2)
  	{
! 	  if (do_default)
! 	    error ("array size missing in %qD", decl);
! 	  /* If a `static' var's size isn't known, make it extern as
! 	     well as static, so it does not get allocated.  If it's not
! 	     `static', then don't mark it extern; finish_incomplete_decl
! 	     will give it a default size and it will get allocated.  */
! 	  else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
! 	    DECL_EXTERNAL (decl) = 1;
  	}
  
!       if (failure == 3)
! 	error ("zero-size array %qD", decl);
  
        cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl);
  
--- 4034,4086 ----
  	 But let's leave it here to ease the eventual merge.  */
        int do_default = !DECL_EXTERNAL (decl);
        tree initializer = init ? init : DECL_INITIAL (decl);
!       int failure = 0;
  
!       /* Check that there are no designated initializers in INIT, as
! 	 those are not supported in GNU C++, and as the middle-end
! 	 will crash if presented with a non-numeric designated
! 	 initializer.  */
!       if (initializer && TREE_CODE (initializer) == CONSTRUCTOR)
  	{
! 	  VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initializer);
! 	  constructor_elt *ce;
! 	  HOST_WIDE_INT i;
! 	  for (i = 0; 
! 	       VEC_iterate (constructor_elt, v, i, ce);
! 	       ++i)
! 	    if (!check_array_designated_initializer (ce))
! 	      failure = 1;
  	}
  
!       if (!failure)
! 	{
! 	  failure = cp_complete_array_type (&TREE_TYPE (decl), initializer,
! 					    do_default);
! 	  if (failure == 1)
! 	    {
! 	      error ("initializer fails to determine size of %qD", decl);
! 	      TREE_TYPE (decl) = error_mark_node;
! 	    }
! 	  else if (failure == 2)
! 	    {
! 	      if (do_default)
! 		{
! 		  error ("array size missing in %qD", decl);
! 		  TREE_TYPE (decl) = error_mark_node;
! 		}
! 	      /* If a `static' var's size isn't known, make it extern as
! 		 well as static, so it does not get allocated.  If it's not
! 		 `static', then don't mark it extern; finish_incomplete_decl
! 		 will give it a default size and it will get allocated.  */
! 	      else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
! 		DECL_EXTERNAL (decl) = 1;
! 	    }
! 	  else if (failure == 3)
! 	    {
! 	      error ("zero-size array %qD", decl);
! 	      TREE_TYPE (decl) = error_mark_node;
! 	    }
! 	}
  
        cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl);
  
*************** maybe_deduce_size_from_array_init (tree 
*** 4023,4029 ****
  static void
  layout_var_decl (tree decl)
  {
!   tree type = TREE_TYPE (decl);
  
    /* If we haven't already layed out this declaration, do so now.
       Note that we must not call complete type for an external object
--- 4094,4104 ----
  static void
  layout_var_decl (tree decl)
  {
!   tree type;
! 
!   type = TREE_TYPE (decl);
!   if (type == error_mark_node)
!     return;
  
    /* If we haven't already layed out this declaration, do so now.
       Note that we must not call complete type for an external object
*************** layout_var_decl (tree decl)
*** 4069,4080 ****
        else
  	error ("storage size of %qD isn't constant", decl);
      }
- 
-   if (TREE_STATIC (decl)
-       && !DECL_ARTIFICIAL (decl)
-       && current_function_decl
-       && DECL_CONTEXT (decl) == current_function_decl)
-     push_local_name (decl);
  }
  
  /* If a local static variable is declared in an inline function, or if
--- 4144,4149 ----
*************** reshape_init_array_1 (tree elt_type, tre
*** 4222,4240 ****
      {
        tree elt_init;
  
!       if (d->cur->index)
! 	{
! 	  /* Handle array designated initializers (GNU extension).  */
! 	  if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE)
! 	    {
! 	      error ("name %qD used in a GNU-style designated "
! 		     "initializer for an array", d->cur->index);
! 	    }
! 	  else
! 	    gcc_unreachable ();
! 	}
! 
        elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false);
        CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), NULL_TREE, elt_init);
      }
  
--- 4291,4300 ----
      {
        tree elt_init;
  
!       check_array_designated_initializer (d->cur);
        elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false);
+       if (elt_init == error_mark_node)
+ 	return error_mark_node;
        CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), NULL_TREE, elt_init);
      }
  
*************** reshape_init_class (tree type, reshape_i
*** 4335,4342 ****
  	  field = lookup_field_1 (type, d->cur->index, /*want_type=*/false);
  
  	  if (!field || TREE_CODE (field) != FIELD_DECL)
! 	    error ("%qT has no non-static data member named %qD", type,
! 		  d->cur->index);
  	}
  
        /* If we processed all the member of the class, we are done.  */
--- 4395,4405 ----
  	  field = lookup_field_1 (type, d->cur->index, /*want_type=*/false);
  
  	  if (!field || TREE_CODE (field) != FIELD_DECL)
! 	    {
! 	      error ("%qT has no non-static data member named %qD", type,
! 		    d->cur->index);
! 	      return error_mark_node;
! 	    }
  	}
  
        /* If we processed all the member of the class, we are done.  */
*************** reshape_init (tree type, tree init)
*** 4513,4518 ****
--- 4576,4583 ----
    d.end = d.cur + VEC_length (constructor_elt, v);
  
    new_init = reshape_init_r (type, &d, true);
+   if (new_init == error_mark_node)
+     return error_mark_node;
  
    /* Make sure all the element of the constructor were used. Otherwise,
       issue an error about exceeding initializers.  */
*************** check_initializer (tree decl, tree init,
*** 4552,4572 ****
    if (type == error_mark_node)
      /* We will have already complained.  */
      init = NULL_TREE;
!   else if (init && COMPLETE_TYPE_P (type)
! 	   && !TREE_CONSTANT (TYPE_SIZE (type)))
      {
!       error ("variable-sized object %qD may not be initialized", decl);
!       init = NULL_TREE;
      }
!   else if (TREE_CODE (type) == ARRAY_TYPE
! 	   && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
      {
!       error ("elements of array %q#D have incomplete type", decl);
!       init = NULL_TREE;
      }
!   else if (TREE_CODE (type) != ARRAY_TYPE && !COMPLETE_TYPE_P (type))
      {
!       error ("%qD has incomplete type", decl);
        TREE_TYPE (decl) = error_mark_node;
        init = NULL_TREE;
      }
--- 4617,4660 ----
    if (type == error_mark_node)
      /* We will have already complained.  */
      init = NULL_TREE;
! 
!   if (TREE_CODE (type) == ARRAY_TYPE)
      {
!       tree element_type = TREE_TYPE (type);
! 
!       /* The array type itself need not be complete, because the
! 	 initializer may tell us how many elements are in the array.
! 	 But, the elements of the array must be complete.  */
!       if (!COMPLETE_TYPE_P (complete_type (element_type)))
! 	{
! 	  error ("elements of array %q#D have incomplete type", decl);
! 	  return NULL_TREE;
! 	}
!       /* It is not valid to initialize an a VLA.  */
!       if (init
! 	  && ((COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type)))
! 	      || !TREE_CONSTANT (TYPE_SIZE (element_type))))
! 	{
! 	  error ("variable-sized object %qD may not be initialized", decl);
! 	  return NULL_TREE;
! 	}
      }
!   else if (!COMPLETE_TYPE_P (type))
      {
!       error ("%qD has incomplete type", decl);
!       TREE_TYPE (decl) = error_mark_node;
!       return NULL_TREE;
      }
!   else
!     /* There is no way to make a variable-sized class type in GNU C++.  */
!     gcc_assert (TREE_CONSTANT (TYPE_SIZE (type)));
! 
!   if (!CP_AGGREGATE_TYPE_P (type)
!       && init && TREE_CODE (init) == CONSTRUCTOR
!       && BRACE_ENCLOSED_INITIALIZER_P (init)
!       && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)) != 1)
      {
!       error ("scalar object %qD requires one element in initializer", decl);
        TREE_TYPE (decl) = error_mark_node;
        init = NULL_TREE;
      }
*************** check_initializer (tree decl, tree init,
*** 4603,4608 ****
--- 4691,4698 ----
  	 array size from the initializer.  */
        maybe_deduce_size_from_array_init (decl, init);
        type = TREE_TYPE (decl);
+       if (type == error_mark_node)
+ 	return NULL_TREE;
  
        if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))
  	{
*************** make_rtl_for_nonlocal_decl (tree decl, t
*** 4747,4753 ****
      {
        /* Fool with the linkage of static consts according to #pragma
  	 interface.  */
!       struct c_fileinfo *finfo = get_fileinfo (lbasename (filename));
        if (!finfo->interface_unknown && !TREE_PUBLIC (decl))
  	{
  	  TREE_PUBLIC (decl) = 1;
--- 4837,4843 ----
      {
        /* Fool with the linkage of static consts according to #pragma
  	 interface.  */
!       struct c_fileinfo *finfo = get_fileinfo (filename);
        if (!finfo->interface_unknown && !TREE_PUBLIC (decl))
  	{
  	  TREE_PUBLIC (decl) = 1;
*************** initialize_local_var (tree decl, tree in
*** 4835,4840 ****
--- 4925,4931 ----
  void
  initialize_artificial_var (tree decl, tree init)
  {
+   gcc_assert (DECL_ARTIFICIAL (decl));
    if (TREE_CODE (init) == TREE_LIST)
      init = build_constructor_from_list (NULL_TREE, init);
    gcc_assert (TREE_CODE (init) == CONSTRUCTOR);
*************** cp_finish_decl (tree decl, tree init, bo
*** 4866,4871 ****
--- 4957,4963 ----
    const char *asmspec = NULL;
    int was_readonly = 0;
    bool var_definition_p = false;
+   int saved_processing_template_decl;
  
    if (decl == error_mark_node)
      return;
*************** cp_finish_decl (tree decl, tree init, bo
*** 4877,4932 ****
      }
  
    gcc_assert (TREE_CODE (decl) != RESULT_DECL);
  
    /* Assume no cleanup is required.  */
    cleanup = NULL_TREE;
  
    /* If a name was specified, get the string.  */
    if (global_scope_p (current_binding_level))
      asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
!   if (asmspec_tree)
      asmspec = TREE_STRING_POINTER (asmspec_tree);
  
-   if (init && TREE_CODE (init) == NAMESPACE_DECL)
-     {
-       error ("cannot initialize %qD to namespace %qD", decl, init);
-       init = NULL_TREE;
-     }
- 
    if (current_class_type
        && CP_DECL_CONTEXT (decl) == current_class_type
        && TYPE_BEING_DEFINED (current_class_type)
        && (DECL_INITIAL (decl) || init))
      DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
  
-   type = TREE_TYPE (decl);
- 
-   if (type == error_mark_node)
-     goto finish_end;
- 
    if (processing_template_decl)
      {
        /* Add this declaration to the statement-tree.  */
        if (at_function_scope_p ())
  	add_decl_expr (decl);
  
!       if (init && DECL_INITIAL (decl))
  	{
! 	  DECL_INITIAL (decl) = init;
! 	  if (init_const_expr_p)
! 	    {
! 	      DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
! 	      if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
! 		TREE_CONSTANT (decl) = 1;
! 	    }
  	}
  
!       if (TREE_CODE (decl) == VAR_DECL
! 	  && !DECL_PRETTY_FUNCTION_P (decl)
! 	  && !dependent_type_p (TREE_TYPE (decl)))
! 	maybe_deduce_size_from_array_init (decl, init);
! 
!       goto finish_end;
      }
  
    /* Parameters are handled by store_parm_decls, not cp_finish_decl.  */
--- 4969,5038 ----
      }
  
    gcc_assert (TREE_CODE (decl) != RESULT_DECL);
+   /* Parameters are handled by store_parm_decls, not cp_finish_decl.  */
+   gcc_assert (TREE_CODE (decl) != PARM_DECL);
+ 
+   type = TREE_TYPE (decl);
+   if (type == error_mark_node)
+     return;
  
    /* Assume no cleanup is required.  */
    cleanup = NULL_TREE;
+   saved_processing_template_decl = processing_template_decl;
  
    /* If a name was specified, get the string.  */
    if (global_scope_p (current_binding_level))
      asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
!   if (asmspec_tree && asmspec_tree != error_mark_node)
      asmspec = TREE_STRING_POINTER (asmspec_tree);
  
    if (current_class_type
        && CP_DECL_CONTEXT (decl) == current_class_type
        && TYPE_BEING_DEFINED (current_class_type)
        && (DECL_INITIAL (decl) || init))
      DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
  
    if (processing_template_decl)
      {
+       bool type_dependent_p;
+ 
        /* Add this declaration to the statement-tree.  */
        if (at_function_scope_p ())
  	add_decl_expr (decl);
  
!       type_dependent_p = dependent_type_p (type);
! 
!       if (init && init_const_expr_p)
  	{
! 	  DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
! 	  if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
! 	    TREE_CONSTANT (decl) = 1;
! 	}
!       
!       if (!init
! 	  || !DECL_CLASS_SCOPE_P (decl)
! 	  || !DECL_INTEGRAL_CONSTANT_VAR_P (decl)
! 	  || type_dependent_p
! 	  || value_dependent_expression_p (init)
! 	     /* Check also if initializer is a value dependent
! 		{ integral_constant_expression }.  */
! 	  || (TREE_CODE (init) == CONSTRUCTOR
! 	      && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)) == 1
! 	      && value_dependent_expression_p
! 		   (VEC_index (constructor_elt,
! 			       CONSTRUCTOR_ELTS (init), 0)->value)))
! 	{
! 	  if (init && DECL_INITIAL (decl))
! 	    DECL_INITIAL (decl) = init;
! 	  if (TREE_CODE (decl) == VAR_DECL
! 	      && !DECL_PRETTY_FUNCTION_P (decl)
! 	      && !type_dependent_p)
! 	    maybe_deduce_size_from_array_init (decl, init);
! 	  goto finish_end;
  	}
  
!       init = fold_non_dependent_expr (init);
!       processing_template_decl = 0;
      }
  
    /* Parameters are handled by store_parm_decls, not cp_finish_decl.  */
*************** cp_finish_decl (tree decl, tree init, bo
*** 4971,4976 ****
--- 5077,5093 ----
        if (DECL_THREAD_LOCAL_P (decl) && !pod_type_p (TREE_TYPE (decl)))
  	error ("%qD cannot be thread-local because it has non-POD type %qT",
  	       decl, TREE_TYPE (decl));
+       /* If this is a local variable that will need a mangled name,
+ 	 register it now.  We must do this before processing the
+ 	 initializer for the variable, since the initialization might
+ 	 require a guard variable, and since the mangled name of the
+ 	 guard variable will depend on the mangled name of this
+ 	 variable.  */
+       if (!processing_template_decl
+ 	  && DECL_FUNCTION_SCOPE_P (decl)
+ 	  && TREE_STATIC (decl)
+ 	  && !DECL_ARTIFICIAL (decl))
+ 	push_local_name (decl);
        /* Convert the initializer to the type of DECL, if we have not
  	 already initialized DECL.  */
        if (!DECL_INITIALIZED_P (decl)
*************** cp_finish_decl (tree decl, tree init, bo
*** 5060,5075 ****
    if (at_function_scope_p ())
      add_decl_expr (decl);
  
!   if (TREE_CODE (decl) == VAR_DECL)
!     layout_var_decl (decl);
! 
!   /* Output the assembler code and/or RTL code for variables and functions,
!      unless the type is an undefined structure or union.
!      If not, it will get done when the type is completed.  */
!   if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
      {
        if (TREE_CODE (decl) == VAR_DECL)
! 	maybe_commonize_var (decl);
  
        make_rtl_for_nonlocal_decl (decl, init, asmspec);
  
--- 5177,5193 ----
    if (at_function_scope_p ())
      add_decl_expr (decl);
  
!   /* Let the middle end know about variables and functions -- but not
!      static data members in uninstantiated class templates.  */
!   if (!saved_processing_template_decl
!       && (TREE_CODE (decl) == VAR_DECL 
! 	  || TREE_CODE (decl) == FUNCTION_DECL))
      {
        if (TREE_CODE (decl) == VAR_DECL)
! 	{
! 	  layout_var_decl (decl);
! 	  maybe_commonize_var (decl);
! 	}
  
        make_rtl_for_nonlocal_decl (decl, init, asmspec);
  
*************** cp_finish_decl (tree decl, tree init, bo
*** 5127,5132 ****
--- 5245,5251 ----
      push_cleanup (decl, cleanup, false);
  
   finish_end:
+   processing_template_decl = saved_processing_template_decl;
  
    if (was_readonly)
      TREE_READONLY (decl) = 1;
*************** grokfndecl (tree ctype,
*** 5829,5844 ****
  	error ("cannot declare %<::main%> to be inline");
        if (!publicp)
  	error ("cannot declare %<::main%> to be static");
-       if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)),
- 			integer_type_node))
- 	{
- 	  tree oldtypeargs = TYPE_ARG_TYPES (TREE_TYPE (decl));
- 	  tree newtype;
- 	  error ("%<::main%> must return %<int%>");
- 	  newtype =  build_function_type (integer_type_node,
- 			  		  oldtypeargs);
- 	  TREE_TYPE (decl) = newtype;
- 	}
        inlinep = 0;
        publicp = 1;
      }
--- 5948,5953 ----
*************** grokfndecl (tree ctype,
*** 5942,5947 ****
--- 6051,6068 ----
        *attrlist = NULL_TREE;
      }
  
+   /* Check main's type after attributes have been applied.  */
+   if (ctype == NULL_TREE && DECL_MAIN_P (decl)
+       && !same_type_p (TREE_TYPE (TREE_TYPE (decl)),
+ 		       integer_type_node))
+     {
+       tree oldtypeargs = TYPE_ARG_TYPES (TREE_TYPE (decl));
+       tree newtype;
+       error ("%<::main%> must return %<int%>");
+       newtype = build_function_type (integer_type_node, oldtypeargs);
+       TREE_TYPE (decl) = newtype;
+     }
+ 
    if (ctype != NULL_TREE
        && (! TYPE_FOR_JAVA (ctype) || check_java_method (decl))
        && check)
*************** grokdeclarator (const cp_declarator *dec
*** 6726,6732 ****
  	      break;
  	    if (qualifying_scope)
  	      {
! 		if (TYPE_P (qualifying_scope))
  		  {
  		    ctype = qualifying_scope;
  		    if (innermost_code != cdk_function
--- 6847,6873 ----
  	      break;
  	    if (qualifying_scope)
  	      {
! 		if (at_function_scope_p ())
! 		  {
! 		    /* [dcl.meaning] 
! 
! 		       A declarator-id shall not be qualified except
! 		       for ... 
! 
! 		       None of the cases are permitted in block
! 		       scope.  */
! 		    if (qualifying_scope == global_namespace)
! 		      error ("invalid use of qualified-name %<::%D%>",
! 			     decl);
! 		    else if (TYPE_P (qualifying_scope))
! 		      error ("invalid use of qualified-name %<%T::%D%>",
! 			     qualifying_scope, decl);
! 		    else 
! 		      error ("invalid use of qualified-name %<%D::%D%>",
! 			     qualifying_scope, decl);
! 		    return error_mark_node;
! 		  }
! 		else if (TYPE_P (qualifying_scope))
  		  {
  		    ctype = qualifying_scope;
  		    if (innermost_code != cdk_function
*************** grokdeclarator (const cp_declarator *dec
*** 6771,6778 ****
  		  tree fns = TREE_OPERAND (decl, 0);
  
  		  dname = fns;
- 		  if (TREE_CODE (dname) == COMPONENT_REF)
- 		    dname = TREE_OPERAND (dname, 1);
  		  if (TREE_CODE (dname) != IDENTIFIER_NODE)
  		    {
  		      gcc_assert (is_overloaded_fn (dname));
--- 6912,6917 ----
*************** grokdeclarator (const cp_declarator *dec
*** 7123,7129 ****
    if (decl_context == PARM)
      {
        if (declspecs->specs[(int)ds_typedef])
! 	error ("typedef declaration invalid in parameter declaration");
        else if (storage_class == sc_static
  	       || storage_class == sc_extern
  	       || thread_p)
--- 7262,7271 ----
    if (decl_context == PARM)
      {
        if (declspecs->specs[(int)ds_typedef])
! 	{
! 	  error ("typedef declaration invalid in parameter declaration");
! 	  return error_mark_node;
! 	}
        else if (storage_class == sc_static
  	       || storage_class == sc_extern
  	       || thread_p)
*************** grokdeclarator (const cp_declarator *dec
*** 7987,7993 ****
  	  {
  	    /* Something like struct S { int N::j; };  */
  	    error ("invalid use of %<::%>");
! 	    decl = NULL_TREE;
  	  }
  	else if (TREE_CODE (type) == FUNCTION_TYPE)
  	  {
--- 8129,8135 ----
  	  {
  	    /* Something like struct S { int N::j; };  */
  	    error ("invalid use of %<::%>");
! 	    return error_mark_node;
  	  }
  	else if (TREE_CODE (type) == FUNCTION_TYPE)
  	  {
*************** lookup_and_check_tag (enum tag_types tag
*** 9290,9296 ****
        /* If that fails, the name will be placed in the smallest
  	 non-class, non-function-prototype scope according to 3.3.1/5.
  	 We may already have a hidden name declared as friend in this
! 	 scope.  So lookup again but not ignoring hidden name.
  	 If we find one, that name will be made visible rather than
  	 creating a new tag.  */
        if (!decl)
--- 9432,9438 ----
        /* If that fails, the name will be placed in the smallest
  	 non-class, non-function-prototype scope according to 3.3.1/5.
  	 We may already have a hidden name declared as friend in this
! 	 scope.  So lookup again but not ignoring hidden names.
  	 If we find one, that name will be made visible rather than
  	 creating a new tag.  */
        if (!decl)
*************** xref_tag (enum tag_types tag_code, tree 
*** 9467,9473 ****
  	       && CLASSTYPE_IS_TEMPLATE (t))
  	{
  	  error ("redeclaration of %qT as a non-template", t);
! 	  t = error_mark_node;
  	}
  
        /* Make injected friend class visible.  */
--- 9609,9616 ----
  	       && CLASSTYPE_IS_TEMPLATE (t))
  	{
  	  error ("redeclaration of %qT as a non-template", t);
! 	  error ("previous declaration %q+D", t);
! 	  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
  	}
  
        /* Make injected friend class visible.  */
*************** start_preparsed_function (tree decl1, tr
*** 10110,10116 ****
    struct cp_binding_level *bl;
    tree current_function_parms;
    struct c_fileinfo *finfo
!     = get_fileinfo (lbasename (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1))));
    bool honor_interface;
  
    /* Sanity check.  */
--- 10253,10259 ----
    struct cp_binding_level *bl;
    tree current_function_parms;
    struct c_fileinfo *finfo
!     = get_fileinfo (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)));
    bool honor_interface;
  
    /* Sanity check.  */
*************** start_preparsed_function (tree decl1, tr
*** 10209,10216 ****
       you declare a function, these types can be incomplete, but they
       must be complete when you define the function.  */
    check_function_type (decl1, current_function_parms);
-   /* Make sure no default arg is missing.  */
-   check_default_args (decl1);
  
    /* Build the return declaration for the function.  */
    restype = TREE_TYPE (fntype);
--- 10352,10357 ----
*************** start_function (cp_decl_specifier_seq *d
*** 10448,10460 ****
  {
    tree decl1;
  
-   if (have_extern_spec)
-     {
-       declspecs->storage_class = sc_extern;
-       /* This should only be done once on the outermost decl.  */
-       have_extern_spec = false;
-     }
- 
    decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
    /* If the declarator is not suitable for a function definition,
       cause a syntax error.  */
--- 10589,10594 ----
*************** finish_function (int flags)
*** 10875,10881 ****
    /* If this function can't throw any exceptions, remember that.  */
    if (!processing_template_decl
        && !cp_function_chain->can_throw
!       && !flag_non_call_exceptions)
      TREE_NOTHROW (fndecl) = 1;
  
    /* This must come after expand_function_end because cleanups might
--- 11009,11016 ----
    /* If this function can't throw any exceptions, remember that.  */
    if (!processing_template_decl
        && !cp_function_chain->can_throw
!       && !flag_non_call_exceptions
!       && !DECL_REPLACEABLE_P (fndecl))
      TREE_NOTHROW (fndecl) = 1;
  
    /* This must come after expand_function_end because cleanups might
*************** finish_function (int flags)
*** 10978,10983 ****
--- 11113,11119 ----
        f->x_vtt_parm = NULL;
        f->x_return_value = NULL;
        f->bindings = NULL;
+       f->extern_decl_map = NULL;
  
        /* Handle attribute((warn_unused_result)).  Relies on gimple input.  */
        c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
*************** revert_static_member_fn (tree decl)
*** 11280,11286 ****
    tmp = build_exception_variant (tmp,
  				 TYPE_RAISES_EXCEPTIONS (function));
    TREE_TYPE (decl) = tmp;
!   if (DECL_ARGUMENTS (decl))
      DECL_ARGUMENTS (decl) = TREE_CHAIN (DECL_ARGUMENTS (decl));
    DECL_STATIC_FUNCTION_P (decl) = 1;
  }
--- 11416,11426 ----
    tmp = build_exception_variant (tmp,
  				 TYPE_RAISES_EXCEPTIONS (function));
    TREE_TYPE (decl) = tmp;
!   if (DECL_ARGUMENTS (decl)
!       /* revert_static_member_fn might be called before grokclassfn
!          had time to add the "this" argument.  */
!       && DECL_ARTIFICIAL (DECL_ARGUMENTS (decl))
!       && DECL_NAME (DECL_ARGUMENTS (decl)) == this_identifier)
      DECL_ARGUMENTS (decl) = TREE_CHAIN (DECL_ARGUMENTS (decl));
    DECL_STATIC_FUNCTION_P (decl) = 1;
  }
diff -Nrcpad gcc-4.1.1/gcc/cp/decl2.c gcc-4.1.2/gcc/cp/decl2.c
*** gcc-4.1.1/gcc/cp/decl2.c	Sat Feb 18 08:37:34 2006
--- gcc-4.1.2/gcc/cp/decl2.c	Wed Dec  6 21:04:52 2006
*************** grok_method_quals (tree ctype, tree func
*** 119,124 ****
--- 119,130 ----
    type_quals = quals & ~TYPE_QUAL_RESTRICT;
    this_quals = quals & TYPE_QUAL_RESTRICT;
  
+   if (fntype == error_mark_node || ctype == error_mark_node)
+     {
+       TREE_TYPE (function) = error_mark_node;
+       return this_quals;
+     }
+ 
    ctype = cp_build_qualified_type (ctype, type_quals);
    fntype = build_method_type_directly (ctype, TREE_TYPE (fntype),
  				       (TREE_CODE (fntype) == METHOD_TYPE
*************** check_member_template (tree tmpl)
*** 470,482 ****
        || (TREE_CODE (decl) == TYPE_DECL
  	  && IS_AGGR_TYPE (TREE_TYPE (decl))))
      {
!       if (current_function_decl)
! 	/* 14.5.2.2 [temp.mem]
! 
! 	   A local class shall not have member templates.  */
! 	error ("invalid declaration of member template %q#D in local class",
! 	       decl);
! 
        if (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl))
  	{
  	  /* 14.5.2.3 [temp.mem]
--- 476,483 ----
        || (TREE_CODE (decl) == TYPE_DECL
  	  && IS_AGGR_TYPE (TREE_TYPE (decl))))
      {
!       /* The parser rejects template declarations in local classes.  */
!       gcc_assert (!current_function_decl);
        if (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl))
  	{
  	  /* 14.5.2.3 [temp.mem]
*************** check_classfn (tree ctype, tree function
*** 581,587 ****
  {
    int ix;
    bool is_template;
! 
    if (DECL_USE_TEMPLATE (function)
        && !(TREE_CODE (function) == TEMPLATE_DECL
  	   && DECL_TEMPLATE_SPECIALIZATION (function))
--- 582,589 ----
  {
    int ix;
    bool is_template;
!   tree pushed_scope;
!   
    if (DECL_USE_TEMPLATE (function)
        && !(TREE_CODE (function) == TEMPLATE_DECL
  	   && DECL_TEMPLATE_SPECIALIZATION (function))
*************** check_classfn (tree ctype, tree function
*** 611,626 ****
    /* OK, is this a definition of a member template?  */
    is_template = (template_parms != NULL_TREE);
  
    ix = class_method_index_for_fn (complete_type (ctype), function);
    if (ix >= 0)
      {
        VEC(tree,gc) *methods = CLASSTYPE_METHOD_VEC (ctype);
        tree fndecls, fndecl = 0;
        bool is_conv_op;
-       tree pushed_scope;
        const char *format = NULL;
  
-       pushed_scope = push_scope (ctype);
        for (fndecls = VEC_index (tree, methods, ix);
  	   fndecls; fndecls = OVL_NEXT (fndecls))
  	{
--- 613,630 ----
    /* OK, is this a definition of a member template?  */
    is_template = (template_parms != NULL_TREE);
  
+   /* We must enter the scope here, because conversion operators are
+      named by target type, and type equivalence relies on typenames
+      resolving within the scope of CTYPE.  */
+   pushed_scope = push_scope (ctype);
    ix = class_method_index_for_fn (complete_type (ctype), function);
    if (ix >= 0)
      {
        VEC(tree,gc) *methods = CLASSTYPE_METHOD_VEC (ctype);
        tree fndecls, fndecl = 0;
        bool is_conv_op;
        const char *format = NULL;
  
        for (fndecls = VEC_index (tree, methods, ix);
  	   fndecls; fndecls = OVL_NEXT (fndecls))
  	{
*************** check_classfn (tree ctype, tree function
*** 659,668 ****
  		      == DECL_TI_TEMPLATE (fndecl))))
  	    break;
  	}
-       if (pushed_scope)
- 	pop_scope (pushed_scope);
        if (fndecls)
! 	return OVL_CURRENT (fndecls);
        error ("prototype for %q#D does not match any in class %qT",
  	     function, ctype);
        is_conv_op = DECL_CONV_FN_P (fndecl);
--- 663,675 ----
  		      == DECL_TI_TEMPLATE (fndecl))))
  	    break;
  	}
        if (fndecls)
! 	{
! 	  if (pushed_scope)
! 	    pop_scope (pushed_scope);
! 	  return OVL_CURRENT (fndecls);
! 	}
!       
        error ("prototype for %q#D does not match any in class %qT",
  	     function, ctype);
        is_conv_op = DECL_CONV_FN_P (fndecl);
*************** check_classfn (tree ctype, tree function
*** 701,708 ****
    else if (!COMPLETE_TYPE_P (ctype))
      cxx_incomplete_type_error (function, ctype);
    else
!     error ("no %q#D member function declared in class %qT",
! 	   function, ctype);
  
    /* If we did not find the method in the class, add it to avoid
       spurious errors (unless the CTYPE is not yet defined, in which
--- 708,717 ----
    else if (!COMPLETE_TYPE_P (ctype))
      cxx_incomplete_type_error (function, ctype);
    else
!     {
!       error ("no %q#D member function declared in class %qT",
! 	     function, ctype);
!     }
  
    /* If we did not find the method in the class, add it to avoid
       spurious errors (unless the CTYPE is not yet defined, in which
*************** check_classfn (tree ctype, tree function
*** 710,715 ****
--- 719,727 ----
       properly within the class.  */
    if (COMPLETE_TYPE_P (ctype))
      add_method (ctype, function, NULL_TREE);
+   
+   if (pushed_scope)
+     pop_scope (pushed_scope);
    return NULL_TREE;
  }
  
*************** grokfield (const cp_declarator *declarat
*** 801,814 ****
    const char *asmspec = 0;
    int flags = LOOKUP_ONLYCONVERTING;
  
-   if (!declspecs->any_specifiers_p
-       && declarator->kind == cdk_id
-       && declarator->u.id.qualifying_scope
-       && TREE_CODE (declarator->u.id.unqualified_name) == IDENTIFIER_NODE)
-     /* Access declaration */
-     return do_class_using_decl (declarator->u.id.qualifying_scope,
- 				declarator->u.id.unqualified_name);
- 
    if (init
        && TREE_CODE (init) == TREE_LIST
        && TREE_VALUE (init) == error_mark_node
--- 813,818 ----
*************** grokfield (const cp_declarator *declarat
*** 872,878 ****
        return void_type_node;
      }
  
!   if (asmspec_tree)
      asmspec = TREE_STRING_POINTER (asmspec_tree);
  
    if (init)
--- 876,882 ----
        return void_type_node;
      }
  
!   if (asmspec_tree && asmspec_tree != error_mark_node)
      asmspec = TREE_STRING_POINTER (asmspec_tree);
  
    if (init)
*************** finish_anon_union (tree anon_union_decl)
*** 1144,1149 ****
--- 1148,1155 ----
      }
  
    main_decl = build_anon_union_vars (type, anon_union_decl);
+   if (main_decl == error_mark_node)
+     return;
    if (main_decl == NULL_TREE)
      {
        warning (0, "anonymous union with no members");
*************** mark_used (tree decl)
*** 3244,3249 ****
--- 3250,3257 ----
      }
  
    TREE_USED (decl) = 1;
+   if (DECL_CLONED_FUNCTION_P (decl))
+     TREE_USED (DECL_CLONED_FUNCTION (decl)) = 1;
    /* If we don't need a value, then we don't need to synthesize DECL.  */ 
    if (skip_evaluation)
      return;
diff -Nrcpad gcc-4.1.1/gcc/cp/error.c gcc-4.1.2/gcc/cp/error.c
*** gcc-4.1.1/gcc/cp/error.c	Tue Nov 22 18:08:17 2005
--- gcc-4.1.2/gcc/cp/error.c	Tue Dec  5 18:04:44 2006
*************** cp_printer (pretty_printer *pp, text_inf
*** 2326,2332 ****
      {
      case 'A': result = args_to_string (next_tree, verbose);	break;
      case 'C': result = code_to_string (next_tcode);		break;
!     case 'D': result = decl_to_string (next_tree, verbose);	break;
      case 'E': result = expr_to_string (next_tree);		break;
      case 'F': result = fndecl_to_string (next_tree, verbose);	break;
      case 'L': result = language_to_string (next_lang);		break;
--- 2326,2347 ----
      {
      case 'A': result = args_to_string (next_tree, verbose);	break;
      case 'C': result = code_to_string (next_tcode);		break;
!     case 'D':
!       {
! 	tree temp = next_tree;
! 	if (DECL_P (temp)
! 	    && DECL_DEBUG_EXPR_IS_FROM (temp) && DECL_DEBUG_EXPR (temp))
! 	  {
! 	    temp = DECL_DEBUG_EXPR (temp);
! 	    if (!DECL_P (temp))
! 	      {
! 		result = expr_to_string (temp);
! 		break;
! 	      }
! 	  }
! 	result = decl_to_string (temp, verbose);
!       }
!       break;
      case 'E': result = expr_to_string (next_tree);		break;
      case 'F': result = fndecl_to_string (next_tree, verbose);	break;
      case 'L': result = language_to_string (next_lang);		break;
diff -Nrcpad gcc-4.1.1/gcc/cp/except.c gcc-4.1.2/gcc/cp/except.c
*** gcc-4.1.1/gcc/cp/except.c	Sat Feb 18 08:37:34 2006
--- gcc-4.1.2/gcc/cp/except.c	Sat Sep  2 06:58:19 2006
*************** build_throw (tree exp)
*** 600,606 ****
  
    if (processing_template_decl)
      {
!       current_function_returns_abnormally = 1;
        return build_min (THROW_EXPR, void_type_node, exp);
      }
  
--- 600,607 ----
  
    if (processing_template_decl)
      {
!       if (cfun)
! 	current_function_returns_abnormally = 1;
        return build_min (THROW_EXPR, void_type_node, exp);
      }
  
diff -Nrcpad gcc-4.1.1/gcc/cp/friend.c gcc-4.1.2/gcc/cp/friend.c
*** gcc-4.1.1/gcc/cp/friend.c	Mon Sep 12 19:54:23 2005
--- gcc-4.1.2/gcc/cp/friend.c	Wed Jul  5 20:40:49 2006
*************** is_friend (tree type, tree supplicant)
*** 78,90 ****
    else
      /* It's a type.  */
      {
!       /* Nested classes are implicitly friends of their enclosing types, as
! 	 per core issue 45 (this is a change from the standard).  */
!       for (context = supplicant;
! 	   context && TYPE_P (context);
! 	   context = TYPE_CONTEXT (context))
! 	if (type == context)
! 	  return 1;
  
        list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
        for (; list ; list = TREE_CHAIN (list))
--- 78,85 ----
    else
      /* It's a type.  */
      {
!       if (same_type_p (supplicant, type))
! 	return 1;
  
        list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
        for (; list ; list = TREE_CHAIN (list))
*************** is_friend (tree type, tree supplicant)
*** 98,110 ****
  	}
      }
  
!   if (declp && DECL_FUNCTION_MEMBER_P (supplicant))
!     context = DECL_CONTEXT (supplicant);
!   else if (! declp)
!     /* Local classes have the same access as the enclosing function.  */
!     context = decl_function_context (TYPE_MAIN_DECL (supplicant));
    else
!     context = NULL_TREE;
  
    /* A namespace is not friend to anybody.  */
    if (context && TREE_CODE (context) == NAMESPACE_DECL)
--- 93,116 ----
  	}
      }
  
!   if (declp)
!     {
!       if (DECL_FUNCTION_MEMBER_P (supplicant))
! 	context = DECL_CONTEXT (supplicant);
!       else
! 	context = NULL_TREE;
!     }
    else
!     {
!       if (TYPE_CONTEXT (supplicant)
! 	  && TYPE_P (TYPE_CONTEXT (supplicant)))
! 	/* Nested classes get the same access as their enclosing types, as
! 	   per DR 45 (this is a change from the standard).  */
! 	context = TYPE_CONTEXT (supplicant);
!       else
! 	/* Local classes have the same access as the enclosing function.  */
! 	context = decl_function_context (TYPE_MAIN_DECL (supplicant));
!     }
  
    /* A namespace is not friend to anybody.  */
    if (context && TREE_CODE (context) == NAMESPACE_DECL)
diff -Nrcpad gcc-4.1.1/gcc/cp/init.c gcc-4.1.2/gcc/cp/init.c
*** gcc-4.1.1/gcc/cp/init.c	Sat Feb 18 08:37:34 2006
--- gcc-4.1.2/gcc/cp/init.c	Tue Nov 14 05:11:32 2006
*************** build_zero_init (tree type, tree nelts, 
*** 179,185 ****
         items with static storage duration that are not otherwise
         initialized are initialized to zero.  */
      ;
!   else if (SCALAR_TYPE_P (type))
      init = convert (type, integer_zero_node);
    else if (CLASS_TYPE_P (type))
      {
--- 179,186 ----
         items with static storage duration that are not otherwise
         initialized are initialized to zero.  */
      ;
!   else if (SCALAR_TYPE_P (type)
! 	   || TREE_CODE (type) == COMPLEX_TYPE)
      init = convert (type, integer_zero_node);
    else if (CLASS_TYPE_P (type))
      {
*************** build_zero_init (tree type, tree nelts, 
*** 223,228 ****
--- 224,234 ----
  				 nelts, integer_one_node);
        else
  	max_index = array_type_nelts (type);
+ 
+       /* If we have an error_mark here, we should just return error mark
+ 	 as we don't know the size of the array yet.  */
+       if (max_index == error_mark_node)
+ 	return error_mark_node;
        gcc_assert (TREE_CODE (max_index) == INTEGER_CST);
  
        /* A zero-sized array, which is accepted as an extension, will
*************** build_zero_init (tree type, tree nelts, 
*** 249,254 ****
--- 255,262 ----
        /* Build a constructor to contain the initializations.  */
        init = build_constructor (type, v);
      }
+   else if (TREE_CODE (type) == VECTOR_TYPE)
+     init = fold_convert (type, integer_zero_node);
    else
      gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
  
*************** build_offset_ref (tree type, tree name, 
*** 1545,1551 ****
  	    }
  	  error ("invalid use of non-static member function %qD",
  		 TREE_OPERAND (member, 1));
! 	  return member;
  	}
        else if (TREE_CODE (member) == FIELD_DECL)
  	{
--- 1553,1559 ----
  	    }
  	  error ("invalid use of non-static member function %qD",
  		 TREE_OPERAND (member, 1));
! 	  return error_mark_node;
  	}
        else if (TREE_CODE (member) == FIELD_DECL)
  	{
*************** constant_value_1 (tree decl, bool integr
*** 1601,1608 ****
  	  mark_used (decl);
  	  init = DECL_INITIAL (decl);
  	}
        if (init == error_mark_node)
! 	return error_mark_node;
        if (!init
  	  || !TREE_TYPE (init)
  	  || (integral_p
--- 1609,1619 ----
  	  mark_used (decl);
  	  init = DECL_INITIAL (decl);
  	}
+       /* If INIT is ERROR_MARK_NODE, that may mean that we are
+ 	 presently processing the initializer, so we conservatively
+ 	 treat this situation as meaning that DECL is uninitialized.  */
        if (init == error_mark_node)
! 	break;
        if (!init
  	  || !TREE_TYPE (init)
  	  || (integral_p
*************** build_new (tree placement, tree type, tr
*** 1669,1675 ****
  {
    tree rval;
  
!   if (type == error_mark_node)
      return error_mark_node;
  
    if (processing_template_decl)
--- 1680,1686 ----
  {
    tree rval;
  
!   if (placement == error_mark_node || type == error_mark_node)
      return error_mark_node;
  
    if (processing_template_decl)
*************** build_new_1 (tree exp)
*** 1847,1856 ****
  	 function context.  Methinks that's not it's purvey.  So we'll do
  	 our own VLA layout later.  */
        vla_p = true;
-       full_type = build_cplus_array_type (type, NULL_TREE);
        index = convert (sizetype, nelts);
        index = size_binop (MINUS_EXPR, index, size_one_node);
!       TYPE_DOMAIN (full_type) = build_index_type (index);
      }
    else
      {
--- 1858,1871 ----
  	 function context.  Methinks that's not it's purvey.  So we'll do
  	 our own VLA layout later.  */
        vla_p = true;
        index = convert (sizetype, nelts);
        index = size_binop (MINUS_EXPR, index, size_one_node);
!       index = build_index_type (index);
!       full_type = build_cplus_array_type (type, NULL_TREE);
!       /* We need a copy of the type as build_array_type will return a shared copy
!          of the incomplete array type.  */
!       full_type = build_distinct_type_copy (full_type);
!       TYPE_DOMAIN (full_type) = index;
      }
    else
      {
diff -Nrcpad gcc-4.1.1/gcc/cp/lex.c gcc-4.1.2/gcc/cp/lex.c
*** gcc-4.1.1/gcc/cp/lex.c	Sat Jun 25 00:59:41 2005
--- gcc-4.1.2/gcc/cp/lex.c	Thu Sep  7 22:27:01 2006
*************** handle_pragma_interface (cpp_reader* dfi
*** 504,510 ****
    else
      filename = ggc_strdup (TREE_STRING_POINTER (fname));
  
!   finfo = get_fileinfo (filename);
  
    if (impl_file_chain == 0)
      {
--- 504,510 ----
    else
      filename = ggc_strdup (TREE_STRING_POINTER (fname));
  
!   finfo = get_fileinfo (input_filename);
  
    if (impl_file_chain == 0)
      {
*************** cxx_make_type (enum tree_code code)
*** 810,816 ****
    /* Set up some flags that give proper default behavior.  */
    if (IS_AGGR_TYPE_CODE (code))
      {
!       struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename));
        SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
        CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
      }
--- 810,816 ----
    /* Set up some flags that give proper default behavior.  */
    if (IS_AGGR_TYPE_CODE (code))
      {
!       struct c_fileinfo *finfo = get_fileinfo (input_filename);
        SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
        CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
      }
diff -Nrcpad gcc-4.1.1/gcc/cp/mangle.c gcc-4.1.2/gcc/cp/mangle.c
*** gcc-4.1.1/gcc/cp/mangle.c	Sun Oct 16 19:38:57 2005
--- gcc-4.1.2/gcc/cp/mangle.c	Tue Jul 11 17:25:01 2006
*************** mangle_conv_op_name_for_type (const tree
*** 2797,2802 ****
--- 2797,2805 ----
    void **slot;
    tree identifier;
  
+   if (type == error_mark_node)
+     return error_mark_node;
+ 
    if (conv_type_names == NULL)
      conv_type_names = htab_create_ggc (31, &hash_type, &compare_type, NULL);
  
diff -Nrcpad gcc-4.1.1/gcc/cp/method.c gcc-4.1.2/gcc/cp/method.c
*** gcc-4.1.1/gcc/cp/method.c	Wed Nov 16 20:22:00 2005
--- gcc-4.1.2/gcc/cp/method.c	Fri Sep  8 16:52:40 2006
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 418,423 ****
--- 418,424 ----
        TREE_CHAIN (x) = t;
        DECL_CONTEXT (x) = thunk_fndecl;
        SET_DECL_RTL (x, NULL_RTX);
+       DECL_HAS_VALUE_EXPR_P (x) = 0;
        t = x;
      }
    a = nreverse (t);
*************** locate_copy (tree type, void *client_)
*** 945,950 ****
--- 946,955 ----
        if (!parms)
  	continue;
        src_type = non_reference (TREE_VALUE (parms));
+ 
+       if (src_type == error_mark_node)
+         return NULL_TREE;
+ 
        if (!same_type_ignoring_top_level_qualifiers_p (src_type, type))
  	continue;
        if (!sufficient_parms_p (TREE_CHAIN (parms)))
diff -Nrcpad gcc-4.1.1/gcc/cp/name-lookup.c gcc-4.1.2/gcc/cp/name-lookup.c
*** gcc-4.1.1/gcc/cp/name-lookup.c	Sat Feb 18 08:37:34 2006
--- gcc-4.1.2/gcc/cp/name-lookup.c	Thu Sep  7 22:27:01 2006
*************** pushdecl_maybe_friend (tree x, bool is_f
*** 602,610 ****
      {
        int different_binding_level = 0;
  
-       if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))
-        check_default_args (x);
- 
        if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
  	name = TREE_OPERAND (name, 0);
  
--- 602,607 ----
*************** pushdecl_maybe_friend (tree x, bool is_f
*** 669,682 ****
  	      if (decls_match (x, t))
  		/* The standard only says that the local extern
  		   inherits linkage from the previous decl; in
! 		   particular, default args are not shared.  We must
! 		   also tell cgraph to treat these decls as the same,
! 		   or we may neglect to emit an "unused" static - we
! 		   do this by making the DECL_UIDs equal, which should
! 		   be viewed as a kludge.  FIXME.  */
  		{
  		  TREE_PUBLIC (x) = TREE_PUBLIC (t);
! 		  DECL_UID (x) = DECL_UID (t);
  		}
  	    }
  	  else if (TREE_CODE (t) == PARM_DECL)
--- 666,693 ----
  	      if (decls_match (x, t))
  		/* The standard only says that the local extern
  		   inherits linkage from the previous decl; in
! 		   particular, default args are not shared.  Add
! 		   the decl into a hash table to make sure only
! 		   the previous decl in this case is seen by the
! 		   middle end.  */
  		{
+ 		  struct cxx_int_tree_map *h;
+ 		  void **loc;
+ 
  		  TREE_PUBLIC (x) = TREE_PUBLIC (t);
! 
! 		  if (cp_function_chain->extern_decl_map == NULL)
! 		    cp_function_chain->extern_decl_map
! 		      = htab_create_ggc (20, cxx_int_tree_map_hash,
! 					 cxx_int_tree_map_eq, NULL);
! 
! 		  h = GGC_NEW (struct cxx_int_tree_map);
! 		  h->uid = DECL_UID (x);
! 		  h->to = t;
! 		  loc = htab_find_slot_with_hash
! 			  (cp_function_chain->extern_decl_map, h,
! 			   h->uid, INSERT);
! 		  *(struct cxx_int_tree_map **) loc = h;
  		}
  	    }
  	  else if (TREE_CODE (t) == PARM_DECL)
*************** pushdecl_maybe_friend (tree x, bool is_f
*** 733,738 ****
--- 744,752 ----
  	    }
  	}
  
+       if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))
+ 	check_default_args (x);
+ 
        check_template_shadow (x);
  
        /* If this is a function conjured up by the backend, massage it
*************** push_class_level_binding (tree name, tre
*** 2584,2589 ****
--- 2598,2606 ----
    if (!class_binding_level)
      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
  
+   if (name == error_mark_node)
+     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
+ 
    /* Check for invalid member names.  */
    gcc_assert (TYPE_BEING_DEFINED (current_class_type));
    /* We could have been passed a tree list if this is an ambiguous
*************** do_class_using_decl (tree scope, tree na
*** 2738,2743 ****
--- 2755,2763 ----
    tree base_binfo;
    int i;
  
+   if (name == error_mark_node)
+     return NULL_TREE;
+ 
    if (!scope || !TYPE_P (scope))
      {
        error ("using-declaration for non-member at class scope");
*************** do_class_using_decl (tree scope, tree na
*** 2790,2807 ****
       class type.  However, if all of the base classes are
       non-dependent, then we can avoid delaying the check until
       instantiation.  */
!   if (!scope_dependent_p && !bases_dependent_p)
      {
        base_kind b_kind;
-       tree binfo;
        binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
        if (b_kind < bk_proper_base)
  	{
! 	  error_not_base_type (scope, current_class_type);
! 	  return NULL_TREE;
  	}
! 
!       if (!name_dependent_p)
  	{
  	  decl = lookup_member (binfo, name, 0, false);
  	  if (!decl)
--- 2810,2828 ----
       class type.  However, if all of the base classes are
       non-dependent, then we can avoid delaying the check until
       instantiation.  */
!   if (!scope_dependent_p)
      {
        base_kind b_kind;
        binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
        if (b_kind < bk_proper_base)
  	{
! 	  if (!bases_dependent_p)
! 	    {
! 	      error_not_base_type (scope, current_class_type);
! 	      return NULL_TREE;
! 	    }
  	}
!       else if (!name_dependent_p)
  	{
  	  decl = lookup_member (binfo, name, 0, false);
  	  if (!decl)
*************** unqualified_namespace_lookup (tree name,
*** 3671,3680 ****
  
        if (b)
  	{
! 	  if (b->value && hidden_name_p (b->value))
! 	    /* Ignore anticipated built-in functions and friends.  */
! 	    ;
! 	  else
  	    binding.value = b->value;
  	  binding.type = b->type;
  	}
--- 3692,3699 ----
  
        if (b)
  	{
! 	  if (b->value
! 	      && ((flags & LOOKUP_HIDDEN) || !hidden_name_p (b->value)))
  	    binding.value = b->value;
  	  binding.type = b->type;
  	}
*************** tree
*** 3722,3727 ****
--- 3741,3747 ----
  lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
  {
    int flags = 0;
+   tree t = NULL_TREE;
  
    if (TREE_CODE (scope) == NAMESPACE_DECL)
      {
*************** lookup_qualified_name (tree scope, tree 
*** 3731,3747 ****
        if (is_type_p)
  	flags |= LOOKUP_PREFER_TYPES;
        if (qualified_lookup_using_namespace (name, scope, &binding, flags))
! 	return select_decl (&binding, flags);
      }
    else if (is_aggr_type (scope, complain))
!     {
!       tree t;
!       t = lookup_member (scope, name, 2, is_type_p);
!       if (t)
! 	return t;
!     }
  
!   return error_mark_node;
  }
  
  /* Subroutine of unqualified_namespace_lookup:
--- 3751,3764 ----
        if (is_type_p)
  	flags |= LOOKUP_PREFER_TYPES;
        if (qualified_lookup_using_namespace (name, scope, &binding, flags))
! 	t = select_decl (&binding, flags);
      }
    else if (is_aggr_type (scope, complain))
!     t = lookup_member (scope, name, 2, is_type_p);
  
!   if (!t)
!     return error_mark_node;
!   return t;
  }
  
  /* Subroutine of unqualified_namespace_lookup:
*************** lookup_name_real (tree name, int prefer_
*** 3979,3996 ****
  	  continue;
  
  	/* If this is the kind of thing we're looking for, we're done.  */
! 	if (qualify_lookup (iter->value, flags)
! 	    && !hidden_name_p (iter->value))
  	  binding = iter->value;
  	else if ((flags & LOOKUP_PREFER_TYPES)
! 		 && qualify_lookup (iter->type, flags)
! 		 && !hidden_name_p (iter->type))
  	  binding = iter->type;
  	else
  	  binding = NULL_TREE;
  
  	if (binding)
  	  {
  	    val = binding;
  	    break;
  	  }
--- 3996,4013 ----
  	  continue;
  
  	/* If this is the kind of thing we're looking for, we're done.  */
! 	if (qualify_lookup (iter->value, flags))
  	  binding = iter->value;
  	else if ((flags & LOOKUP_PREFER_TYPES)
! 		 && qualify_lookup (iter->type, flags))
  	  binding = iter->type;
  	else
  	  binding = NULL_TREE;
  
  	if (binding)
  	  {
+ 	    /* Only namespace-scope bindings can be hidden.  */
+ 	    gcc_assert (!hidden_name_p (binding));
  	    val = binding;
  	    break;
  	  }
*************** pushtag (tree name, tree type, tag_scope
*** 4875,4881 ****
  	    pushdecl_class_level (decl);
  	}
        else if (b->kind != sk_template_parms)
! 	decl = pushdecl_with_scope (decl, b, /*is_friend=*/false);
  
        TYPE_CONTEXT (type) = DECL_CONTEXT (decl);
  
--- 4892,4902 ----
  	    pushdecl_class_level (decl);
  	}
        else if (b->kind != sk_template_parms)
! 	{
! 	  decl = pushdecl_with_scope (decl, b, /*is_friend=*/false);
! 	  if (decl == error_mark_node)
! 	    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
! 	}
  
        TYPE_CONTEXT (type) = DECL_CONTEXT (decl);
  
diff -Nrcpad gcc-4.1.1/gcc/cp/parser.c gcc-4.1.2/gcc/cp/parser.c
*** gcc-4.1.1/gcc/cp/parser.c	Tue May 16 14:54:55 2006
--- gcc-4.1.2/gcc/cp/parser.c	Fri Jan  5 16:53:27 2007
*************** cp_lexer_next_token_is_keyword (cp_lexer
*** 501,506 ****
--- 501,549 ----
    return token->keyword == keyword;
  }
  
+ static bool
+ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
+ {
+   cp_token *token;
+ 
+   token = cp_lexer_peek_token (lexer);
+   switch (token->keyword) 
+     {
+       /* Storage classes.  */
+     case RID_AUTO:
+     case RID_REGISTER:
+     case RID_STATIC:
+     case RID_EXTERN:
+     case RID_MUTABLE:
+     case RID_THREAD:
+       /* Elaborated type specifiers.  */
+     case RID_ENUM:
+     case RID_CLASS:
+     case RID_STRUCT:
+     case RID_UNION:
+     case RID_TYPENAME:
+       /* Simple type specifiers.  */
+     case RID_CHAR:
+     case RID_WCHAR:
+     case RID_BOOL:
+     case RID_SHORT:
+     case RID_INT:
+     case RID_LONG:
+     case RID_SIGNED:
+     case RID_UNSIGNED:
+     case RID_FLOAT:
+     case RID_DOUBLE:
+     case RID_VOID:
+       /* GNU extensions.  */ 
+     case RID_ATTRIBUTE:
+     case RID_TYPEOF:
+       return true;
+ 
+     default:
+       return false;
+     }
+ }
+ 
  /* Return a pointer to the Nth token in the token stream.  If N is 1,
     then this is precisely equivalent to cp_lexer_peek_token (except
     that it is not inline).  One would like to disallow that case, but
*************** make_parameter_declarator (cp_decl_speci
*** 982,987 ****
--- 1025,1048 ----
    return parameter;
  }
  
+ /* Returns true iff DECLARATOR  is a declaration for a function.  */
+ 
+ static bool
+ function_declarator_p (const cp_declarator *declarator)
+ {
+   while (declarator)
+     {
+       if (declarator->kind == cdk_function
+ 	  && declarator->declarator->kind == cdk_id)
+ 	return true;
+       if (declarator->kind == cdk_id
+ 	  || declarator->kind == cdk_error)
+ 	return false;
+       declarator = declarator->declarator;
+     }
+   return false;
+ }
+  
  /* The parser.  */
  
  /* Overview
*************** typedef struct cp_parser GTY(())
*** 1337,1342 ****
--- 1398,1407 ----
       character set.  */
    bool translate_strings_p;
  
+   /* TRUE if we are presently parsing the body of a function, but not
+      a local class.  */
+   bool in_function_body;
+ 
    /* If non-NULL, then we are parsing a construct where new type
       definitions are not permitted.  The string stored here will be
       issued as an error message if a type is defined.  */
*************** static tree cp_parser_builtin_offsetof
*** 1464,1471 ****
  
  static void cp_parser_statement
    (cp_parser *, tree);
! static tree cp_parser_labeled_statement
!   (cp_parser *, tree);
  static tree cp_parser_expression_statement
    (cp_parser *, tree);
  static tree cp_parser_compound_statement
--- 1529,1536 ----
  
  static void cp_parser_statement
    (cp_parser *, tree);
! static void cp_parser_label_for_labeled_statement
!   (cp_parser *);
  static tree cp_parser_expression_statement
    (cp_parser *, tree);
  static tree cp_parser_compound_statement
*************** static tree cp_parser_qualified_namespac
*** 1531,1538 ****
    (cp_parser *);
  static void cp_parser_namespace_alias_definition
    (cp_parser *);
! static void cp_parser_using_declaration
!   (cp_parser *);
  static void cp_parser_using_directive
    (cp_parser *);
  static void cp_parser_asm_definition
--- 1596,1603 ----
    (cp_parser *);
  static void cp_parser_namespace_alias_definition
    (cp_parser *);
! static bool cp_parser_using_declaration
!   (cp_parser *, bool);
  static void cp_parser_using_directive
    (cp_parser *);
  static void cp_parser_asm_definition
*************** static tree cp_parser_class_name
*** 1583,1589 ****
  static tree cp_parser_class_specifier
    (cp_parser *);
  static tree cp_parser_class_head
!   (cp_parser *, bool *, tree *);
  static enum tag_types cp_parser_class_key
    (cp_parser *);
  static void cp_parser_member_specification_opt
--- 1648,1654 ----
  static tree cp_parser_class_specifier
    (cp_parser *);
  static tree cp_parser_class_head
!   (cp_parser *, bool *, tree *, tree *);
  static enum tag_types cp_parser_class_key
    (cp_parser *);
  static void cp_parser_member_specification_opt
*************** static tree cp_parser_sizeof_operand
*** 1759,1765 ****
  static bool cp_parser_declares_only_class_p
    (cp_parser *);
  static void cp_parser_set_storage_class
!   (cp_decl_specifier_seq *, cp_storage_class);
  static void cp_parser_set_decl_spec_type
    (cp_decl_specifier_seq *, tree, bool);
  static bool cp_parser_friend_p
--- 1824,1830 ----
  static bool cp_parser_declares_only_class_p
    (cp_parser *);
  static void cp_parser_set_storage_class
!   (cp_parser *, cp_decl_specifier_seq *, enum rid);
  static void cp_parser_set_decl_spec_type
    (cp_decl_specifier_seq *, tree, bool);
  static bool cp_parser_friend_p
*************** static void cp_parser_name_lookup_error
*** 1806,1812 ****
    (cp_parser *, tree, tree, const char *);
  static bool cp_parser_simulate_error
    (cp_parser *);
! static void cp_parser_check_type_definition
    (cp_parser *);
  static void cp_parser_check_for_definition_in_return_type
    (cp_declarator *, tree);
--- 1871,1877 ----
    (cp_parser *, tree, tree, const char *);
  static bool cp_parser_simulate_error
    (cp_parser *);
! static bool cp_parser_check_type_definition
    (cp_parser *);
  static void cp_parser_check_for_definition_in_return_type
    (cp_declarator *, tree);
*************** cp_parser_simulate_error (cp_parser* par
*** 1958,1975 ****
    return false;
  }
  
  /* This function is called when a type is defined.  If type
     definitions are forbidden at this point, an error message is
     issued.  */
  
! static void
  cp_parser_check_type_definition (cp_parser* parser)
  {
    /* If types are forbidden here, issue a message.  */
    if (parser->type_definition_forbidden_message)
!     /* Use `%s' to print the string in case there are any escape
!        characters in the message.  */
!     error ("%s", parser->type_definition_forbidden_message);
  }
  
  /* This function is called when the DECLARATOR is processed.  The TYPE
--- 2023,2087 ----
    return false;
  }
  
+ /* Check for repeated decl-specifiers.  */
+ 
+ static void
+ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs)
+ {
+   cp_decl_spec ds;
+ 
+   for (ds = ds_first; ds != ds_last; ++ds)
+     {
+       unsigned count = decl_specs->specs[(int)ds];
+       if (count < 2)
+ 	continue;
+       /* The "long" specifier is a special case because of "long long".  */
+       if (ds == ds_long)
+ 	{
+ 	  if (count > 2)
+ 	    error ("%<long long long%> is too long for GCC");
+ 	  else if (pedantic && !in_system_header && warn_long_long)
+ 	    pedwarn ("ISO C++ does not support %<long long%>");
+ 	}
+       else if (count > 1)
+ 	{
+ 	  static const char *const decl_spec_names[] = {
+ 	    "signed",
+ 	    "unsigned",
+ 	    "short",
+ 	    "long",
+ 	    "const",
+ 	    "volatile",
+ 	    "restrict",
+ 	    "inline",
+ 	    "virtual",
+ 	    "explicit",
+ 	    "friend",
+ 	    "typedef",
+ 	    "__complex",
+ 	    "__thread"
+ 	  };
+ 	  error ("duplicate %qs", decl_spec_names[(int)ds]);
+ 	}
+     }
+ }
+ 
  /* This function is called when a type is defined.  If type
     definitions are forbidden at this point, an error message is
     issued.  */
  
! static bool
  cp_parser_check_type_definition (cp_parser* parser)
  {
    /* If types are forbidden here, issue a message.  */
    if (parser->type_definition_forbidden_message)
!     {
!       /* Use `%s' to print the string in case there are any escape
! 	 characters in the message.  */
!       error ("%s", parser->type_definition_forbidden_message);
!       return false;
!     }
!   return true;
  }
  
  /* This function is called when the DECLARATOR is processed.  The TYPE
*************** cp_parser_diagnose_invalid_type_name (cp
*** 2070,2077 ****
    /* If the lookup found a template-name, it means that the user forgot
    to specify an argument list. Emit a useful error message.  */
    if (TREE_CODE (decl) == TEMPLATE_DECL)
!     error ("invalid use of template-name %qE without an argument list",
!       decl);
    else if (!parser->scope)
      {
        /* Issue an error message.  */
--- 2182,2193 ----
    /* If the lookup found a template-name, it means that the user forgot
    to specify an argument list. Emit a useful error message.  */
    if (TREE_CODE (decl) == TEMPLATE_DECL)
!     error ("invalid use of template-name %qE without an argument list", decl);
!   else if (TREE_CODE (id) == BIT_NOT_EXPR)
!     error ("invalid use of destructor %qD as a type", id);
!   else if (TREE_CODE (decl) == TYPE_DECL)
!     /* Something like 'unsigned A a;'  */
!     error ("invalid combination of multiple type-specifiers");
    else if (!parser->scope)
      {
        /* Issue an error message.  */
*************** cp_parser_parse_and_diagnose_invalid_typ
*** 2164,2171 ****
        cp_parser_abort_tentative_parse (parser);
        return false;
      }
!   if (!cp_parser_parse_definitely (parser)
!       || TREE_CODE (id) != IDENTIFIER_NODE)
      return false;
  
    /* Emit a diagnostic for the invalid type.  */
--- 2280,2286 ----
        cp_parser_abort_tentative_parse (parser);
        return false;
      }
!   if (!cp_parser_parse_definitely (parser) || TREE_CODE (id) == TYPE_DECL)
      return false;
  
    /* Emit a diagnostic for the invalid type.  */
*************** cp_parser_new (void)
*** 2498,2503 ****
--- 2613,2621 ----
    /* String literals should be translated to the execution character set.  */
    parser->translate_strings_p = true;
  
+   /* We are not parsing a function body.  */
+   parser->in_function_body = false;
+ 
    /* The unparsed function queue is empty.  */
    parser->unparsed_functions_queues = build_tree_list (NULL_TREE, NULL_TREE);
  
*************** cp_parser_primary_expression (cp_parser 
*** 2853,2859 ****
  		 int i = ({ int j = 3; j + 1; });
  
  	       at class or namespace scope.  */
! 	    if (!at_function_scope_p ())
  	      error ("statement-expressions are allowed only inside functions");
  	    /* Start the statement-expression.  */
  	    expr = begin_stmt_expr ();
--- 2971,2977 ----
  		 int i = ({ int j = 3; j + 1; });
  
  	       at class or namespace scope.  */
! 	    if (!parser->in_function_body)
  	      error ("statement-expressions are allowed only inside functions");
  	    /* Start the statement-expression.  */
  	    expr = begin_stmt_expr ();
*************** cp_parser_unqualified_id (cp_parser* par
*** 3339,3351 ****
  	object_scope = parser->object_scope;
  	qualifying_scope = parser->qualifying_scope;
  
  	/* If the name is of the form "X::~X" it's OK.  */
! 	if (scope && TYPE_P (scope)
! 	    && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
  	    && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
  		== CPP_OPEN_PAREN)
! 	    && (cp_lexer_peek_token (parser->lexer)->value
! 		== TYPE_IDENTIFIER (scope)))
  	  {
  	    cp_lexer_consume_token (parser->lexer);
  	    return build_nt (BIT_NOT_EXPR, scope);
--- 3457,3487 ----
  	object_scope = parser->object_scope;
  	qualifying_scope = parser->qualifying_scope;
  
+ 	/* Check for invalid scopes.  */
+ 	if (scope == error_mark_node)
+ 	  {
+ 	    if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ 	      cp_lexer_consume_token (parser->lexer);
+ 	    return error_mark_node;
+ 	  }
+ 	if (scope && TREE_CODE (scope) == NAMESPACE_DECL)
+ 	  {
+ 	    if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
+ 	      error ("scope %qT before %<~%> is not a class-name", scope);
+ 	    cp_parser_simulate_error (parser);
+ 	    if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ 	      cp_lexer_consume_token (parser->lexer);
+ 	    return error_mark_node;
+ 	  }
+ 	gcc_assert (!scope || TYPE_P (scope));
+ 
  	/* If the name is of the form "X::~X" it's OK.  */
! 	token = cp_lexer_peek_token (parser->lexer);
! 	if (scope
! 	    && token->type == CPP_NAME
  	    && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
  		== CPP_OPEN_PAREN)
! 	    && constructor_name_p (token->value, scope))
  	  {
  	    cp_lexer_consume_token (parser->lexer);
  	    return build_nt (BIT_NOT_EXPR, scope);
*************** cp_parser_unqualified_id (cp_parser* par
*** 3423,3429 ****
  	   destructor is the same as the name of the qualifying
  	   class.  That allows us to keep parsing after running
  	   into ill-formed destructor names.  */
! 	if (type_decl == error_mark_node && scope && TYPE_P (scope))
  	  return build_nt (BIT_NOT_EXPR, scope);
  	else if (type_decl == error_mark_node)
  	  return error_mark_node;
--- 3559,3565 ----
  	   destructor is the same as the name of the qualifying
  	   class.  That allows us to keep parsing after running
  	   into ill-formed destructor names.  */
! 	if (type_decl == error_mark_node && scope)
  	  return build_nt (BIT_NOT_EXPR, scope);
  	else if (type_decl == error_mark_node)
  	  return error_mark_node;
*************** cp_parser_unqualified_id (cp_parser* par
*** 3434,3439 ****
--- 3570,3576 ----
  	    if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
  	      error ("declaration of %<~%T%> as member of %qT",
  		     type_decl, scope);
+ 	    cp_parser_simulate_error (parser);
  	    return error_mark_node;
  	  }
  
*************** cp_parser_nested_name_specifier_opt (cp_
*** 3514,3533 ****
    cp_token_position start = 0;
    cp_token *token;
  
-   /* If the next token corresponds to a nested name specifier, there
-      is no need to reparse it.  However, if CHECK_DEPENDENCY_P is
-      false, it may have been true before, in which case something
-      like `A<X>::B<Y>::C' may have resulted in a nested-name-specifier
-      of `A<X>::', where it should now be `A<X>::B<Y>::'.  So, when
-      CHECK_DEPENDENCY_P is false, we have to fall through into the
-      main loop.  */
-   if (check_dependency_p
-       && cp_lexer_next_token_is (parser->lexer, CPP_NESTED_NAME_SPECIFIER))
-     {
-       cp_parser_pre_parsed_nested_name_specifier (parser);
-       return parser->scope;
-     }
- 
    /* Remember where the nested-name-specifier starts.  */
    if (cp_parser_uncommitted_to_tentative_parse_p (parser))
      {
--- 3651,3656 ----
*************** cp_parser_nested_name_specifier_opt (cp_
*** 3552,3557 ****
--- 3675,3691 ----
  	{
  	  /* Grab the nested-name-specifier and continue the loop.  */
  	  cp_parser_pre_parsed_nested_name_specifier (parser);
+ 	  /* If we originally encountered this nested-name-specifier
+ 	     with IS_DECLARATION set to false, we will not have
+ 	     resolved TYPENAME_TYPEs, so we must do so here.  */
+ 	  if (is_declaration
+ 	      && TREE_CODE (parser->scope) == TYPENAME_TYPE)
+ 	    {
+ 	      new_scope = resolve_typename_type (parser->scope,
+ 						 /*only_current_p=*/false);
+ 	      if (new_scope != error_mark_node)
+ 		parser->scope = new_scope;
+ 	    }
  	  success = true;
  	  continue;
  	}
*************** cp_parser_nested_name_specifier_opt (cp_
*** 3627,3632 ****
--- 3761,3768 ----
  	     class-or-namespace-name.  */
  	  parser->scope = old_scope;
  	  parser->qualifying_scope = saved_qualifying_scope;
+ 	  if (cp_parser_uncommitted_to_tentative_parse_p (parser))
+ 	    break;
  	  /* If the next token is an identifier, and the one after
  	     that is a `::', then any valid interpretation would have
  	     found a class-or-namespace-name.  */
*************** cp_parser_postfix_dot_deref_expression (
*** 4511,4517 ****
  	    }
  	  if (scope && name && BASELINK_P (name))
  	    adjust_result_of_qualified_name_lookup
! 	      (name, BINFO_TYPE (BASELINK_BINFO (name)), scope);
  	  postfix_expression
  	    = finish_class_member_access_expr (postfix_expression, name,
  					       template_p);
--- 4647,4653 ----
  	    }
  	  if (scope && name && BASELINK_P (name))
  	    adjust_result_of_qualified_name_lookup
! 	      (name, BINFO_TYPE (BASELINK_ACCESS_BINFO (name)), scope);
  	  postfix_expression
  	    = finish_class_member_access_expr (postfix_expression, name,
  					       template_p);
*************** cp_parser_builtin_offsetof (cp_parser *p
*** 5999,6005 ****
    if (processing_template_decl)
      expr = build1 (OFFSETOF_EXPR, size_type_node, expr);
    else
!     expr = fold_offsetof (expr);
  
   failure:
    parser->integral_constant_expression_p = save_ice_p;
--- 6135,6141 ----
    if (processing_template_decl)
      expr = build1 (OFFSETOF_EXPR, size_type_node, expr);
    else
!     expr = finish_offsetof (expr);
  
   failure:
    parser->integral_constant_expression_p = save_ice_p;
*************** cp_parser_statement (cp_parser* parser, 
*** 6029,6034 ****
--- 6165,6171 ----
    cp_token *token;
    location_t statement_location;
  
+  restart:
    /* There is no statement yet.  */
    statement = NULL_TREE;
    /* Peek at the next token.  */
*************** cp_parser_statement (cp_parser* parser, 
*** 6045,6053 ****
  	{
  	case RID_CASE:
  	case RID_DEFAULT:
! 	  statement = cp_parser_labeled_statement (parser,
! 						   in_statement_expr);
! 	  break;
  
  	case RID_IF:
  	case RID_SWITCH:
--- 6182,6192 ----
  	{
  	case RID_CASE:
  	case RID_DEFAULT:
! 	  /* Looks like a labeled-statement with a case label.
! 	     Parse the label, and then use tail recursion to parse
! 	     the statement.  */
! 	  cp_parser_label_for_labeled_statement (parser);
! 	  goto restart;
  
  	case RID_IF:
  	case RID_SWITCH:
*************** cp_parser_statement (cp_parser* parser, 
*** 6092,6098 ****
  	 labeled-statement.  */
        token = cp_lexer_peek_nth_token (parser->lexer, 2);
        if (token->type == CPP_COLON)
! 	statement = cp_parser_labeled_statement (parser, in_statement_expr);
      }
    /* Anything that starts with a `{' must be a compound-statement.  */
    else if (token->type == CPP_OPEN_BRACE)
--- 6231,6243 ----
  	 labeled-statement.  */
        token = cp_lexer_peek_nth_token (parser->lexer, 2);
        if (token->type == CPP_COLON)
! 	{
! 	  /* Looks like a labeled-statement with an ordinary label.
! 	     Parse the label, and then use tail recursion to parse
! 	     the statement.  */
! 	  cp_parser_label_for_labeled_statement (parser);
! 	  goto restart;
! 	}
      }
    /* Anything that starts with a `{' must be a compound-statement.  */
    else if (token->type == CPP_OPEN_BRACE)
*************** cp_parser_statement (cp_parser* parser, 
*** 6134,6159 ****
      SET_EXPR_LOCATION (statement, statement_location);
  }
  
! /* Parse a labeled-statement.
  
!    labeled-statement:
!      identifier : statement
!      case constant-expression : statement
!      default : statement
  
     GNU Extension:
  
!    labeled-statement:
!      case constant-expression ... constant-expression : statement
! 
!    Returns the new CASE_LABEL_EXPR, for a `case' or `default' label.
!    For an ordinary label, returns a LABEL_EXPR.  */
! 
! static tree
! cp_parser_labeled_statement (cp_parser* parser, tree in_statement_expr)
  {
    cp_token *token;
-   tree statement = error_mark_node;
  
    /* The next token should be an identifier.  */
    token = cp_lexer_peek_token (parser->lexer);
--- 6279,6301 ----
      SET_EXPR_LOCATION (statement, statement_location);
  }
  
! /* Parse the label for a labeled-statement, i.e.
  
!    identifier :
!    case constant-expression :
!    default :
  
     GNU Extension:
+    case constant-expression ... constant-expression : statement
  
!    When a label is parsed without errors, the label is added to the
!    parse tree by the finish_* functions, so this function doesn't
!    have to return the label.  */
!   
! static void
! cp_parser_label_for_labeled_statement (cp_parser* parser)
  {
    cp_token *token;
  
    /* The next token should be an identifier.  */
    token = cp_lexer_peek_token (parser->lexer);
*************** cp_parser_labeled_statement (cp_parser* 
*** 6161,6167 ****
        && token->type != CPP_KEYWORD)
      {
        cp_parser_error (parser, "expected labeled-statement");
!       return error_mark_node;
      }
  
    switch (token->keyword)
--- 6303,6309 ----
        && token->type != CPP_KEYWORD)
      {
        cp_parser_error (parser, "expected labeled-statement");
!       return;
      }
  
    switch (token->keyword)
*************** cp_parser_labeled_statement (cp_parser* 
*** 6196,6202 ****
  	if (!parser->in_switch_statement_p)
  	  error ("case label %qE not within a switch statement", expr);
  	else
! 	  statement = finish_case_label (expr, expr_hi);
        }
        break;
  
--- 6338,6344 ----
  	if (!parser->in_switch_statement_p)
  	  error ("case label %qE not within a switch statement", expr);
  	else
! 	  finish_case_label (expr, expr_hi);
        }
        break;
  
*************** cp_parser_labeled_statement (cp_parser* 
*** 6206,6227 ****
        if (!parser->in_switch_statement_p)
  	error ("case label not within a switch statement");
        else
! 	statement = finish_case_label (NULL_TREE, NULL_TREE);
        break;
  
      default:
        /* Anything else must be an ordinary label.  */
!       statement = finish_label_stmt (cp_parser_identifier (parser));
        break;
      }
  
    /* Require the `:' token.  */
    cp_parser_require (parser, CPP_COLON, "`:'");
-   /* Parse the labeled statement.  */
-   cp_parser_statement (parser, in_statement_expr);
- 
-   /* Return the label, in the case of a `case' or `default' label.  */
-   return statement;
  }
  
  /* Parse an expression-statement.
--- 6348,6364 ----
        if (!parser->in_switch_statement_p)
  	error ("case label not within a switch statement");
        else
! 	finish_case_label (NULL_TREE, NULL_TREE);
        break;
  
      default:
        /* Anything else must be an ordinary label.  */
!       finish_label_stmt (cp_parser_identifier (parser));
        break;
      }
  
    /* Require the `:' token.  */
    cp_parser_require (parser, CPP_COLON, "`:'");
  }
  
  /* Parse an expression-statement.
*************** cp_parser_block_declaration (cp_parser *
*** 7069,7075 ****
  	cp_parser_using_directive (parser);
        /* Otherwise, it's a using-declaration.  */
        else
! 	cp_parser_using_declaration (parser);
      }
    /* If the next keyword is `__label__' we have a label declaration.  */
    else if (token1->keyword == RID_LABEL)
--- 7206,7213 ----
  	cp_parser_using_directive (parser);
        /* Otherwise, it's a using-declaration.  */
        else
! 	cp_parser_using_declaration (parser,
! 				     /*access_declaration_p=*/false);
      }
    /* If the next keyword is `__label__' we have a label declaration.  */
    else if (token1->keyword == RID_LABEL)
*************** cp_parser_decl_specifier_seq (cp_parser*
*** 7298,7304 ****
  			      int* declares_class_or_enum)
  {
    bool constructor_possible_p = !parser->in_declarator_p;
-   cp_decl_spec ds;
  
    /* Clear DECL_SPECS.  */
    clear_decl_specs (decl_specs);
--- 7436,7441 ----
*************** cp_parser_decl_specifier_seq (cp_parser*
*** 7371,7409 ****
  	     GNU Extension:
  	       thread  */
  	case RID_AUTO:
- 	  /* Consume the token.  */
- 	  cp_lexer_consume_token (parser->lexer);
- 	  cp_parser_set_storage_class (decl_specs, sc_auto);
- 	  break;
  	case RID_REGISTER:
- 	  /* Consume the token.  */
- 	  cp_lexer_consume_token (parser->lexer);
- 	  cp_parser_set_storage_class (decl_specs, sc_register);
- 	  break;
  	case RID_STATIC:
- 	  /* Consume the token.  */
- 	  cp_lexer_consume_token (parser->lexer);
- 	  if (decl_specs->specs[(int) ds_thread])
- 	    {
- 	      error ("%<__thread%> before %<static%>");
- 	      decl_specs->specs[(int) ds_thread] = 0;
- 	    }
- 	  cp_parser_set_storage_class (decl_specs, sc_static);
- 	  break;
  	case RID_EXTERN:
- 	  /* Consume the token.  */
- 	  cp_lexer_consume_token (parser->lexer);
- 	  if (decl_specs->specs[(int) ds_thread])
- 	    {
- 	      error ("%<__thread%> before %<extern%>");
- 	      decl_specs->specs[(int) ds_thread] = 0;
- 	    }
- 	  cp_parser_set_storage_class (decl_specs, sc_extern);
- 	  break;
  	case RID_MUTABLE:
  	  /* Consume the token.  */
  	  cp_lexer_consume_token (parser->lexer);
! 	  cp_parser_set_storage_class (decl_specs, sc_mutable);
  	  break;
  	case RID_THREAD:
  	  /* Consume the token.  */
--- 7508,7520 ----
  	     GNU Extension:
  	       thread  */
  	case RID_AUTO:
  	case RID_REGISTER:
  	case RID_STATIC:
  	case RID_EXTERN:
  	case RID_MUTABLE:
  	  /* Consume the token.  */
  	  cp_lexer_consume_token (parser->lexer);
! 	  cp_parser_set_storage_class (parser, decl_specs, token->keyword);
  	  break;
  	case RID_THREAD:
  	  /* Consume the token.  */
*************** cp_parser_decl_specifier_seq (cp_parser*
*** 7499,7539 ****
        flags |= CP_PARSER_FLAGS_OPTIONAL;
      }
  
!   /* Check for repeated decl-specifiers.  */
!   for (ds = ds_first; ds != ds_last; ++ds)
!     {
!       unsigned count = decl_specs->specs[(int)ds];
!       if (count < 2)
! 	continue;
!       /* The "long" specifier is a special case because of "long long".  */
!       if (ds == ds_long)
! 	{
! 	  if (count > 2)
! 	    error ("%<long long long%> is too long for GCC");
! 	  else if (pedantic && !in_system_header && warn_long_long)
! 	    pedwarn ("ISO C++ does not support %<long long%>");
! 	}
!       else if (count > 1)
! 	{
! 	  static const char *const decl_spec_names[] = {
! 	    "signed",
! 	    "unsigned",
! 	    "short",
! 	    "long",
! 	    "const",
! 	    "volatile",
! 	    "restrict",
! 	    "inline",
! 	    "virtual",
! 	    "explicit",
! 	    "friend",
! 	    "typedef",
! 	    "__complex",
! 	    "__thread"
! 	  };
! 	  error ("duplicate %qs", decl_spec_names[(int)ds]);
! 	}
!     }
  
    /* Don't allow a friend specifier with a class definition.  */
    if (decl_specs->specs[(int) ds_friend] != 0
--- 7610,7616 ----
        flags |= CP_PARSER_FLAGS_OPTIONAL;
      }
  
!   cp_parser_check_decl_spec (decl_specs);
  
    /* Don't allow a friend specifier with a class definition.  */
    if (decl_specs->specs[(int) ds_friend] != 0
*************** cp_parser_linkage_specification (cp_pars
*** 7667,7675 ****
        saved_in_unbraced_linkage_specification_p
  	= parser->in_unbraced_linkage_specification_p;
        parser->in_unbraced_linkage_specification_p = true;
-       have_extern_spec = true;
        cp_parser_declaration (parser);
-       have_extern_spec = false;
        parser->in_unbraced_linkage_specification_p
  	= saved_in_unbraced_linkage_specification_p;
      }
--- 7744,7750 ----
*************** cp_parser_template_id (cp_parser *parser
*** 8721,8730 ****
      template_id = build_min_nt (TEMPLATE_ID_EXPR, template, arguments);
    else if (DECL_CLASS_TEMPLATE_P (template)
  	   || DECL_TEMPLATE_TEMPLATE_PARM_P (template))
!     template_id
!       = finish_template_type (template, arguments,
! 			      cp_lexer_next_token_is (parser->lexer,
! 						      CPP_SCOPE));
    else
      {
        /* If it's not a class-template or a template-template, it should be
--- 8796,8814 ----
      template_id = build_min_nt (TEMPLATE_ID_EXPR, template, arguments);
    else if (DECL_CLASS_TEMPLATE_P (template)
  	   || DECL_TEMPLATE_TEMPLATE_PARM_P (template))
!     {
!       bool entering_scope;
!       /* In "template <typename T> ... A<T>::", A<T> is the abstract A
! 	 template (rather than some instantiation thereof) only if
! 	 is not nested within some other construct.  For example, in
! 	 "template <typename T> void f(T) { A<T>::", A<T> is just an
! 	 instantiation of A.  */
!       entering_scope = (template_parm_scope_p ()
! 			&& cp_lexer_next_token_is (parser->lexer,
! 						   CPP_SCOPE));
!       template_id
! 	= finish_template_type (template, arguments, entering_scope);
!     }
    else
      {
        /* If it's not a class-template or a template-template, it should be
*************** cp_parser_enum_specifier (cp_parser* par
*** 10219,10234 ****
      identifier = make_anon_name ();
  
    /* Issue an error message if type-definitions are forbidden here.  */
!   cp_parser_check_type_definition (parser);
! 
!   /* Create the new type.  We do this before consuming the opening brace
!      so the enum will be recorded as being on the line of its tag (or the
!      'enum' keyword, if there is no tag).  */
!   type = start_enum (identifier);
! 
    /* Consume the opening brace.  */
    cp_lexer_consume_token (parser->lexer);
  
    /* If the next token is not '}', then there are some enumerators.  */
    if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
      cp_parser_enumerator_list (parser, type);
--- 10303,10325 ----
      identifier = make_anon_name ();
  
    /* Issue an error message if type-definitions are forbidden here.  */
!   if (!cp_parser_check_type_definition (parser))
!     type = error_mark_node;
!   else
!     /* Create the new type.  We do this before consuming the opening
!        brace so the enum will be recorded as being on the line of its
!        tag (or the 'enum' keyword, if there is no tag).  */
!     type = start_enum (identifier);
!   
    /* Consume the opening brace.  */
    cp_lexer_consume_token (parser->lexer);
  
+   if (type == error_mark_node)
+     {
+       cp_parser_skip_to_end_of_block_or_statement (parser);
+       return error_mark_node;
+     }
+ 
    /* If the next token is not '}', then there are some enumerators.  */
    if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
      cp_parser_enumerator_list (parser, type);
*************** cp_parser_qualified_namespace_specifier 
*** 10490,10503 ****
    return cp_parser_namespace_name (parser);
  }
  
! /* Parse a using-declaration.
  
     using-declaration:
       using typename [opt] :: [opt] nested-name-specifier unqualified-id ;
!      using :: unqualified-id ;  */
  
! static void
! cp_parser_using_declaration (cp_parser* parser)
  {
    cp_token *token;
    bool typename_p = false;
--- 10581,10601 ----
    return cp_parser_namespace_name (parser);
  }
  
! /* Parse a using-declaration, or, if ACCESS_DECLARATION_P is true, an
!    access declaration.
  
     using-declaration:
       using typename [opt] :: [opt] nested-name-specifier unqualified-id ;
!      using :: unqualified-id ;  
  
!    access-declaration:
!      qualified-id ;  
! 
!    */
! 
! static bool
! cp_parser_using_declaration (cp_parser* parser, 
! 			     bool access_declaration_p)
  {
    cp_token *token;
    bool typename_p = false;
*************** cp_parser_using_declaration (cp_parser* 
*** 10506,10523 ****
    tree identifier;
    tree qscope;
  
!   /* Look for the `using' keyword.  */
!   cp_parser_require_keyword (parser, RID_USING, "`using'");
! 
!   /* Peek at the next token.  */
!   token = cp_lexer_peek_token (parser->lexer);
!   /* See if it's `typename'.  */
!   if (token->keyword == RID_TYPENAME)
      {
!       /* Remember that we've seen it.  */
!       typename_p = true;
!       /* Consume the `typename' token.  */
!       cp_lexer_consume_token (parser->lexer);
      }
  
    /* Look for the optional global scope qualification.  */
--- 10604,10626 ----
    tree identifier;
    tree qscope;
  
!   if (access_declaration_p)
!     cp_parser_parse_tentatively (parser);
!   else
      {
!       /* Look for the `using' keyword.  */
!       cp_parser_require_keyword (parser, RID_USING, "`using'");
!       
!       /* Peek at the next token.  */
!       token = cp_lexer_peek_token (parser->lexer);
!       /* See if it's `typename'.  */
!       if (token->keyword == RID_TYPENAME)
! 	{
! 	  /* Remember that we've seen it.  */
! 	  typename_p = true;
! 	  /* Consume the `typename' token.  */
! 	  cp_lexer_consume_token (parser->lexer);
! 	}
      }
  
    /* Look for the optional global scope qualification.  */
*************** cp_parser_using_declaration (cp_parser* 
*** 10544,10555 ****
--- 10647,10672 ----
    if (!qscope)
      qscope = global_namespace;
  
+   if (access_declaration_p && cp_parser_error_occurred (parser))
+     /* Something has already gone wrong; there's no need to parse
+        further.  Since an error has occurred, the return value of
+        cp_parser_parse_definitely will be false, as required.  */
+     return cp_parser_parse_definitely (parser);
+ 
    /* Parse the unqualified-id.  */
    identifier = cp_parser_unqualified_id (parser,
  					 /*template_keyword_p=*/false,
  					 /*check_dependency_p=*/true,
  					 /*declarator_p=*/true);
  
+   if (access_declaration_p)
+     {
+       if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ 	cp_parser_simulate_error (parser);
+       if (!cp_parser_parse_definitely (parser))
+ 	return false;
+     }
+ 
    /* The function we call to handle a using-declaration is different
       depending on what scope we are in.  */
    if (qscope == error_mark_node || identifier == error_mark_node)
*************** cp_parser_using_declaration (cp_parser* 
*** 10583,10588 ****
--- 10700,10707 ----
  
    /* Look for the final `;'.  */
    cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+   
+   return true;
  }
  
  /* Parse a using-directive.
*************** cp_parser_asm_definition (cp_parser* par
*** 10675,10681 ****
       too.  Doing that means that we have to treat the `::' operator as
       two `:' tokens.  */
    if (cp_parser_allow_gnu_extensions_p (parser)
!       && at_function_scope_p ()
        && (cp_lexer_next_token_is (parser->lexer, CPP_COLON)
  	  || cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)))
      {
--- 10794,10800 ----
       too.  Doing that means that we have to treat the `::' operator as
       two `:' tokens.  */
    if (cp_parser_allow_gnu_extensions_p (parser)
!       && parser->in_function_body
        && (cp_lexer_next_token_is (parser->lexer, CPP_COLON)
  	  || cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)))
      {
*************** cp_parser_asm_definition (cp_parser* par
*** 10741,10747 ****
    cp_parser_require (parser, CPP_SEMICOLON, "`;'");
  
    /* Create the ASM_EXPR.  */
!   if (at_function_scope_p ())
      {
        asm_stmt = finish_asm_stmt (volatile_p, string, outputs,
  				  inputs, clobbers);
--- 10860,10866 ----
    cp_parser_require (parser, CPP_SEMICOLON, "`;'");
  
    /* Create the ASM_EXPR.  */
!   if (parser->in_function_body)
      {
        asm_stmt = finish_asm_stmt (volatile_p, string, outputs,
  				  inputs, clobbers);
*************** cp_parser_init_declarator (cp_parser* pa
*** 10855,10860 ****
--- 10974,10983 ----
    if (declarator == cp_error_declarator)
      return error_mark_node;
  
+   /* Check that the number of template-parameter-lists is OK.  */
+   if (!cp_parser_check_declarator_template_parameters (parser, declarator))
+     return error_mark_node;
+ 
    if (declares_class_or_enum & 2)
      cp_parser_check_for_definition_in_return_type (declarator,
  						   decl_specifiers->type);
*************** cp_parser_init_declarator (cp_parser* pa
*** 10974,10993 ****
    /* Check to see whether or not this declaration is a friend.  */
    friend_p = cp_parser_friend_p (decl_specifiers);
  
-   /* Check that the number of template-parameter-lists is OK.  */
-   if (!cp_parser_check_declarator_template_parameters (parser, declarator))
-     return error_mark_node;
- 
    /* Enter the newly declared entry in the symbol table.  If we're
       processing a declaration in a class-specifier, we wait until
       after processing the initializer.  */
    if (!member_p)
      {
        if (parser->in_unbraced_linkage_specification_p)
! 	{
! 	  decl_specifiers->storage_class = sc_extern;
! 	  have_extern_spec = false;
! 	}
        decl = start_decl (declarator, decl_specifiers,
  			 is_initialized, attributes, prefix_attributes,
  			 &pushed_scope);
--- 11097,11109 ----
    /* Check to see whether or not this declaration is a friend.  */
    friend_p = cp_parser_friend_p (decl_specifiers);
  
    /* Enter the newly declared entry in the symbol table.  If we're
       processing a declaration in a class-specifier, we wait until
       after processing the initializer.  */
    if (!member_p)
      {
        if (parser->in_unbraced_linkage_specification_p)
! 	decl_specifiers->storage_class = sc_extern;
        decl = start_decl (declarator, decl_specifiers,
  			 is_initialized, attributes, prefix_attributes,
  			 &pushed_scope);
*************** cp_parser_init_declarator (cp_parser* pa
*** 11030,11039 ****
    is_non_constant_init = true;
    if (is_initialized)
      {
!       if (declarator->kind == cdk_function
! 	  && declarator->declarator->kind == cdk_id
! 	  && initialization_kind == CPP_EQ)
! 	initializer = cp_parser_pure_specifier (parser);
        else
  	initializer = cp_parser_initializer (parser,
  					     &is_parenthesized_init,
--- 11146,11168 ----
    is_non_constant_init = true;
    if (is_initialized)
      {
!       if (function_declarator_p (declarator))
! 	{
! 	   if (initialization_kind == CPP_EQ)
! 	     initializer = cp_parser_pure_specifier (parser);
! 	   else
! 	     {
! 	       /* If the declaration was erroneous, we don't really
! 		  know what the user intended, so just silently
! 		  consume the initializer.  */
! 	       if (decl != error_mark_node)
! 		 error ("initializer provided for function");
! 	       cp_parser_skip_to_closing_parenthesis (parser,
! 						      /*recovering=*/true,
! 						      /*or_comma=*/false,
! 						      /*consume_paren=*/true);
! 	     }
! 	}
        else
  	initializer = cp_parser_initializer (parser,
  					     &is_parenthesized_init,
*************** cp_parser_declarator (cp_parser* parser,
*** 11201,11207 ****
  						member_p);
      }
  
!   if (attributes && declarator != cp_error_declarator)
      declarator->attributes = attributes;
  
    return declarator;
--- 11330,11336 ----
  						member_p);
      }
  
!   if (attributes && declarator && declarator != cp_error_declarator)
      declarator->attributes = attributes;
  
    return declarator;
*************** cp_parser_direct_declarator (cp_parser* 
*** 11425,11431 ****
  	      /* Normally, the array bound must be an integral constant
  		 expression.  However, as an extension, we allow VLAs
  		 in function scopes.  */
! 	      else if (!at_function_scope_p ())
  		{
  		  error ("array bound is not an integer constant");
  		  bounds = error_mark_node;
--- 11554,11560 ----
  	      /* Normally, the array bound must be an integral constant
  		 expression.  However, as an extension, we allow VLAs
  		 in function scopes.  */
! 	      else if (!parser->in_function_body)
  		{
  		  error ("array bound is not an integer constant");
  		  bounds = error_mark_node;
*************** cp_parser_type_specifier_seq (cp_parser*
*** 11929,11935 ****
  	flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
      }
  
!   return;
  }
  
  /* Parse a parameter-declaration-clause.
--- 12058,12064 ----
  	flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
      }
  
!   cp_parser_check_decl_spec (type_specifier_seq);
  }
  
  /* Parse a parameter-declaration-clause.
*************** cp_parser_parameter_declaration_list (cp
*** 12035,12043 ****
--- 12164,12179 ----
  {
    cp_parameter_declarator *parameters = NULL;
    cp_parameter_declarator **tail = &parameters;
+   bool saved_in_unbraced_linkage_specification_p;
  
    /* Assume all will go well.  */
    *is_error = false;
+   /* The special considerations that apply to a function within an
+      unbraced linkage specifications do not apply to the parameters
+      to the function.  */
+   saved_in_unbraced_linkage_specification_p 
+     = parser->in_unbraced_linkage_specification_p;
+   parser->in_unbraced_linkage_specification_p = false;
  
    /* Look for more parameters.  */
    while (true)
*************** cp_parser_parameter_declaration_list (cp
*** 12116,12121 ****
--- 12252,12260 ----
  	}
      }
  
+   parser->in_unbraced_linkage_specification_p
+     = saved_in_unbraced_linkage_specification_p;
+ 
    return parameters;
  }
  
*************** cp_parser_class_specifier (cp_parser* pa
*** 12785,12799 ****
    int has_trailing_semicolon;
    bool nested_name_specifier_p;
    unsigned saved_num_template_parameter_lists;
    tree old_scope = NULL_TREE;
    tree scope = NULL_TREE;
  
    push_deferring_access_checks (dk_no_deferred);
  
    /* Parse the class-head.  */
    type = cp_parser_class_head (parser,
  			       &nested_name_specifier_p,
! 			       &attributes);
    /* If the class-head was a semantic disaster, skip the entire body
       of the class.  */
    if (!type)
--- 12924,12941 ----
    int has_trailing_semicolon;
    bool nested_name_specifier_p;
    unsigned saved_num_template_parameter_lists;
+   bool saved_in_function_body;
    tree old_scope = NULL_TREE;
    tree scope = NULL_TREE;
+   tree bases = NULL_TREE;
  
    push_deferring_access_checks (dk_no_deferred);
  
    /* Parse the class-head.  */
    type = cp_parser_class_head (parser,
  			       &nested_name_specifier_p,
! 			       &attributes,
!                                &bases);
    /* If the class-head was a semantic disaster, skip the entire body
       of the class.  */
    if (!type)
*************** cp_parser_class_specifier (cp_parser* pa
*** 12810,12815 ****
--- 12952,12960 ----
        return error_mark_node;
      }
  
+   /* Process the base classes.  */
+   xref_basetypes (type, bases);
+ 
    /* Issue an error message if type-definitions are forbidden here.  */
    cp_parser_check_type_definition (parser);
    /* Remember that we are defining one more class.  */
*************** cp_parser_class_specifier (cp_parser* pa
*** 12819,12824 ****
--- 12964,12972 ----
    saved_num_template_parameter_lists
      = parser->num_template_parameter_lists;
    parser->num_template_parameter_lists = 0;
+   /* We are not in a function body.  */
+   saved_in_function_body = parser->in_function_body;
+   parser->in_function_body = false;
  
    /* Start the class.  */
    if (nested_name_specifier_p)
*************** cp_parser_class_specifier (cp_parser* pa
*** 12930,12936 ****
    /* Put back any saved access checks.  */
    pop_deferring_access_checks ();
  
!   /* Restore the count of active template-parameter-lists.  */
    parser->num_template_parameter_lists
      = saved_num_template_parameter_lists;
  
--- 13078,13085 ----
    /* Put back any saved access checks.  */
    pop_deferring_access_checks ();
  
!   /* Restore saved state.  */
!   parser->in_function_body = saved_in_function_body;
    parser->num_template_parameter_lists
      = saved_num_template_parameter_lists;
  
*************** cp_parser_class_specifier (cp_parser* pa
*** 12964,12970 ****
  static tree
  cp_parser_class_head (cp_parser* parser,
  		      bool* nested_name_specifier_p,
! 		      tree *attributes_p)
  {
    tree nested_name_specifier;
    enum tag_types class_key;
--- 13113,13120 ----
  static tree
  cp_parser_class_head (cp_parser* parser,
  		      bool* nested_name_specifier_p,
! 		      tree *attributes_p,
!                       tree *bases)
  {
    tree nested_name_specifier;
    enum tag_types class_key;
*************** cp_parser_class_head (cp_parser* parser,
*** 12977,12983 ****
    bool invalid_explicit_specialization_p = false;
    tree pushed_scope = NULL_TREE;
    unsigned num_templates;
-   tree bases;
  
    /* Assume no nested-name-specifier will be present.  */
    *nested_name_specifier_p = false;
--- 13127,13132 ----
*************** cp_parser_class_head (cp_parser* parser,
*** 13192,13198 ****
    if (template_id_p)
      {
        type = TREE_TYPE (id);
!       maybe_process_partial_specialization (type);
        if (nested_name_specifier)
  	pushed_scope = push_scope (nested_name_specifier);
      }
--- 13341,13347 ----
    if (template_id_p)
      {
        type = TREE_TYPE (id);
!       type = maybe_process_partial_specialization (type);
        if (nested_name_specifier)
  	pushed_scope = push_scope (nested_name_specifier);
      }
*************** cp_parser_class_head (cp_parser* parser,
*** 13273,13286 ****
         struct A::C : B {};
  
       is valid.  */
!   bases = NULL_TREE;
  
    /* Get the list of base-classes, if there is one.  */
    if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
!     bases = cp_parser_base_clause (parser);
! 
!   /* Process the base classes.  */
!   xref_basetypes (type, bases);
  
   done:
    /* Leave the scope given by the nested-name-specifier.  We will
--- 13422,13432 ----
         struct A::C : B {};
  
       is valid.  */
!   *bases = NULL_TREE;
  
    /* Get the list of base-classes, if there is one.  */
    if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
!     *bases = cp_parser_base_clause (parser);
  
   done:
    /* Leave the scope given by the nested-name-specifier.  We will
*************** cp_parser_member_declaration (cp_parser*
*** 13443,13450 ****
    if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
      {
        /* Parse the using-declaration.  */
!       cp_parser_using_declaration (parser);
! 
        return;
      }
  
--- 13589,13596 ----
    if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
      {
        /* Parse the using-declaration.  */
!       cp_parser_using_declaration (parser,
! 				   /*access_declaration_p=*/false);
        return;
      }
  
*************** cp_parser_member_declaration (cp_parser*
*** 13464,13469 ****
--- 13610,13618 ----
        return;
      }
  
+   if (cp_parser_using_declaration (parser, /*access_declaration=*/true))
+     return;
+ 
    /* Parse the decl-specifier-seq.  */
    cp_parser_decl_specifier_seq (parser,
  				CP_PARSER_FLAGS_OPTIONAL,
*************** cp_parser_member_declaration (cp_parser*
*** 13677,13684 ****
  		     for a pure-specifier; otherwise, we look for a
  		     constant-initializer.  When we call `grokfield', it will
  		     perform more stringent semantics checks.  */
! 		  if (declarator->kind == cdk_function
! 		      && declarator->declarator->kind == cdk_id)
  		    initializer = cp_parser_pure_specifier (parser);
  		  else
  		    /* Parse the initializer.  */
--- 13826,13832 ----
  		     for a pure-specifier; otherwise, we look for a
  		     constant-initializer.  When we call `grokfield', it will
  		     perform more stringent semantics checks.  */
! 		  if (function_declarator_p (declarator))
  		    initializer = cp_parser_pure_specifier (parser);
  		  else
  		    /* Parse the initializer.  */
*************** cp_parser_try_block (cp_parser* parser)
*** 14137,14142 ****
--- 14285,14291 ----
  static bool
  cp_parser_function_try_block (cp_parser* parser)
  {
+   tree compound_stmt;
    tree try_block;
    bool ctor_initializer_p;
  
*************** cp_parser_function_try_block (cp_parser*
*** 14144,14150 ****
    if (!cp_parser_require_keyword (parser, RID_TRY, "`try'"))
      return false;
    /* Let the rest of the front-end know where we are.  */
!   try_block = begin_function_try_block ();
    /* Parse the function-body.  */
    ctor_initializer_p
      = cp_parser_ctor_initializer_opt_and_function_body (parser);
--- 14293,14299 ----
    if (!cp_parser_require_keyword (parser, RID_TRY, "`try'"))
      return false;
    /* Let the rest of the front-end know where we are.  */
!   try_block = begin_function_try_block (&compound_stmt);
    /* Parse the function-body.  */
    ctor_initializer_p
      = cp_parser_ctor_initializer_opt_and_function_body (parser);
*************** cp_parser_function_try_block (cp_parser*
*** 14153,14159 ****
    /* Parse the handlers.  */
    cp_parser_handler_seq (parser);
    /* We're done with the handlers.  */
!   finish_function_handler_sequence (try_block);
  
    return ctor_initializer_p;
  }
--- 14302,14308 ----
    /* Parse the handlers.  */
    cp_parser_handler_seq (parser);
    /* We're done with the handlers.  */
!   finish_function_handler_sequence (try_block, compound_stmt);
  
    return ctor_initializer_p;
  }
*************** cp_parser_attribute_list (cp_parser* par
*** 14517,14522 ****
--- 14666,14673 ----
        if (token->type == CPP_NAME
  	  || token->type == CPP_KEYWORD)
  	{
+ 	  tree arguments = NULL_TREE;
+ 
  	  /* Consume the token.  */
  	  token = cp_lexer_consume_token (parser->lexer);
  
*************** cp_parser_attribute_list (cp_parser* par
*** 14530,14547 ****
  	  /* If it's an `(', then parse the attribute arguments.  */
  	  if (token->type == CPP_OPEN_PAREN)
  	    {
! 	      tree arguments;
! 
! 	      arguments = (cp_parser_parenthesized_expression_list
! 			   (parser, true, /*cast_p=*/false,
! 			    /*non_constant_p=*/NULL));
! 	      /* Save the identifier and arguments away.  */
  	      TREE_VALUE (attribute) = arguments;
  	    }
  
! 	  /* Add this attribute to the list.  */
! 	  TREE_CHAIN (attribute) = attribute_list;
! 	  attribute_list = attribute;
  
  	  token = cp_lexer_peek_token (parser->lexer);
  	}
--- 14681,14699 ----
  	  /* If it's an `(', then parse the attribute arguments.  */
  	  if (token->type == CPP_OPEN_PAREN)
  	    {
! 	      arguments = cp_parser_parenthesized_expression_list
! 			  (parser, true, /*cast_p=*/false,
! 			   /*non_constant_p=*/NULL);
! 	      /* Save the arguments away.  */
  	      TREE_VALUE (attribute) = arguments;
  	    }
  
! 	  if (arguments != error_mark_node)
! 	    {
! 	      /* Add this attribute to the list.  */
! 	      TREE_CHAIN (attribute) = attribute_list;
! 	      attribute_list = attribute;
! 	    }
  
  	  token = cp_lexer_peek_token (parser->lexer);
  	}
*************** cp_parser_check_declarator_template_para
*** 14959,14968 ****
  
  		 is correct; there shouldn't be a `template <>' for
  		 the definition of `S<int>::f'.  */
! 	      if (CLASSTYPE_TEMPLATE_INFO (scope)
! 		  && (CLASSTYPE_TEMPLATE_INSTANTIATION (scope)
! 		      || uses_template_parms (CLASSTYPE_TI_ARGS (scope)))
! 		  && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope)))
  		++num_templates;
  
  	      scope = TYPE_CONTEXT (scope);
--- 15111,15124 ----
  
  		 is correct; there shouldn't be a `template <>' for
  		 the definition of `S<int>::f'.  */
! 	      if (!CLASSTYPE_TEMPLATE_INFO (scope))
! 		/* If SCOPE does not have template information of any
! 		   kind, then it is not a template, nor is it nested
! 		   within a template.  */
! 		break;
! 	      if (explicit_class_specialization_p (scope))
! 		break;
! 	      if (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope)))
  		++num_templates;
  
  	      scope = TYPE_CONTEXT (scope);
*************** cp_parser_constructor_declarator_p (cp_p
*** 15079,15085 ****
    /* The common case is that this is not a constructor declarator, so
       try to avoid doing lots of work if at all possible.  It's not
       valid declare a constructor at function scope.  */
!   if (at_function_scope_p ())
      return false;
    /* And only certain tokens can begin a constructor declarator.  */
    next_token = cp_lexer_peek_token (parser->lexer);
--- 15235,15241 ----
    /* The common case is that this is not a constructor declarator, so
       try to avoid doing lots of work if at all possible.  It's not
       valid declare a constructor at function scope.  */
!   if (parser->in_function_body)
      return false;
    /* And only certain tokens can begin a constructor declarator.  */
    next_token = cp_lexer_peek_token (parser->lexer);
*************** cp_parser_constructor_declarator_p (cp_p
*** 15156,15163 ****
  	  /* A parameter declaration begins with a decl-specifier,
  	     which is either the "attribute" keyword, a storage class
  	     specifier, or (usually) a type-specifier.  */
! 	  && !cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE)
! 	  && !cp_parser_storage_class_specifier_opt (parser))
  	{
  	  tree type;
  	  tree pushed_scope = NULL_TREE;
--- 15312,15318 ----
  	  /* A parameter declaration begins with a decl-specifier,
  	     which is either the "attribute" keyword, a storage class
  	     specifier, or (usually) a type-specifier.  */
! 	  && !cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer))
  	{
  	  tree type;
  	  tree pushed_scope = NULL_TREE;
*************** cp_parser_function_definition_after_decl
*** 15271,15278 ****
--- 15426,15436 ----
    tree fn;
    bool ctor_initializer_p = false;
    bool saved_in_unbraced_linkage_specification_p;
+   bool saved_in_function_body;
    unsigned saved_num_template_parameter_lists;
  
+   saved_in_function_body = parser->in_function_body;
+   parser->in_function_body = true;
    /* If the next token is `return', then the code may be trying to
       make use of the "named return value" extension that G++ used to
       support.  */
*************** cp_parser_function_definition_after_decl
*** 15320,15325 ****
--- 15478,15484 ----
      = saved_in_unbraced_linkage_specification_p;
    parser->num_template_parameter_lists
      = saved_num_template_parameter_lists;
+   parser->in_function_body = saved_in_function_body;
  
    return fn;
  }
*************** cp_parser_template_declaration_after_exp
*** 15344,15349 ****
--- 15503,15517 ----
    /* And the `<'.  */
    if (!cp_parser_require (parser, CPP_LESS, "`<'"))
      return;
+   if (at_class_scope_p () && current_function_decl)
+     {
+       /* 14.5.2.2 [temp.mem]
+ 
+          A local class shall not have member templates.  */
+       error ("invalid declaration of member template in local class");
+       cp_parser_skip_to_end_of_block_or_statement (parser);
+       return;
+     }
    /* [temp]
     
       A template ... shall not have C linkage.  */
*************** cp_parser_declares_only_class_p (cp_pars
*** 16032,16047 ****
  	  || cp_lexer_next_token_is (parser->lexer, CPP_COMMA));
  }
  
! /* Update the DECL_SPECS to reflect the STORAGE_CLASS.  */
  
  static void
! cp_parser_set_storage_class (cp_decl_specifier_seq *decl_specs,
! 			     cp_storage_class storage_class)
  {
!   if (decl_specs->storage_class != sc_none)
!     decl_specs->multiple_storage_classes_p = true;
!   else
!     decl_specs->storage_class = storage_class;
  }
  
  /* Update the DECL_SPECS to reflect the TYPE_SPEC.  If USER_DEFINED_P
--- 16200,16255 ----
  	  || cp_lexer_next_token_is (parser->lexer, CPP_COMMA));
  }
  
! /* Update the DECL_SPECS to reflect the storage class indicated by
!    KEYWORD.  */
  
  static void
! cp_parser_set_storage_class (cp_parser *parser,
! 			     cp_decl_specifier_seq *decl_specs,
! 			     enum rid keyword)
  {
!   cp_storage_class storage_class;
! 
!   if (parser->in_unbraced_linkage_specification_p)
!     {
!       error ("invalid use of %qD in linkage specification",
! 	     ridpointers[keyword]);
!       return;
!     }
!   else if (decl_specs->storage_class != sc_none)
!     {
!       decl_specs->multiple_storage_classes_p = true;
!       return;
!     }
! 
!   if ((keyword == RID_EXTERN || keyword == RID_STATIC)
!       && decl_specs->specs[(int) ds_thread])
!     {
!       error ("%<__thread%> before %qD", ridpointers[keyword]);
!       decl_specs->specs[(int) ds_thread] = 0;
!     }
! 
!   switch (keyword) 
!     {
!     case RID_AUTO:
!       storage_class = sc_auto;
!       break;
!     case RID_REGISTER:
!       storage_class = sc_register;
!       break;
!     case RID_STATIC:
!       storage_class = sc_static;
!       break;
!     case RID_EXTERN:
!       storage_class = sc_extern;
!       break;
!     case RID_MUTABLE:
!       storage_class = sc_mutable;
!       break;
!     default:
!       gcc_unreachable ();
!     }
!   decl_specs->storage_class = storage_class;
  }
  
  /* Update the DECL_SPECS to reflect the TYPE_SPEC.  If USER_DEFINED_P
diff -Nrcpad gcc-4.1.1/gcc/cp/pt.c gcc-4.1.2/gcc/cp/pt.c
*** gcc-4.1.1/gcc/cp/pt.c	Mon May 15 09:38:11 2006
--- gcc-4.1.2/gcc/cp/pt.c	Sun Dec 10 23:48:13 2006
*************** static tree get_template_base (tree, tre
*** 150,156 ****
  static tree try_class_unification (tree, tree, tree, tree);
  static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
  					   tree, tree);
- static tree determine_specialization (tree, tree, tree *, int, int);
  static int template_args_equal (tree, tree);
  static void tsubst_default_arguments (tree);
  static tree for_each_template_parm_r (tree *, int *, void *);
--- 150,155 ----
*************** check_explicit_instantiation_namespace (
*** 691,703 ****
  /* The TYPE is being declared.  If it is a template type, that means it
     is a partial specialization.  Do appropriate error-checking.  */
  
! void
  maybe_process_partial_specialization (tree type)
  {
    tree context;
  
    if (type == error_mark_node)
!     return;
  
    context = TYPE_CONTEXT (type);
  
--- 690,709 ----
  /* The TYPE is being declared.  If it is a template type, that means it
     is a partial specialization.  Do appropriate error-checking.  */
  
! tree
  maybe_process_partial_specialization (tree type)
  {
    tree context;
  
    if (type == error_mark_node)
!     return error_mark_node;
! 
!   if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
!     {
!       error ("name of class shadows template template parameter %qD",
! 	     TYPE_NAME (type));
!       return error_mark_node;
!     }
  
    context = TYPE_CONTEXT (type);
  
*************** maybe_process_partial_specialization (tr
*** 782,788 ****
  	}
      }
    else if (processing_specialization)
!     error ("explicit specialization of non-template %qT", type);
  }
  
  /* Returns nonzero if we can optimize the retrieval of specializations
--- 788,799 ----
  	}
      }
    else if (processing_specialization)
!     {
!       error ("explicit specialization of non-template %qT", type);
!       return error_mark_node;
!     }
! 
!   return type;
  }
  
  /* Returns nonzero if we can optimize the retrieval of specializations
*************** register_specialization (tree spec, tree
*** 1178,1184 ****
  	    {
  	      error ("specialization of %qD after instantiation",
  		     fn);
! 	      return spec;
  	    }
  	  else
  	    {
--- 1189,1195 ----
  	    {
  	      error ("specialization of %qD after instantiation",
  		     fn);
! 	      return error_mark_node;
  	    }
  	  else
  	    {
*************** register_local_specialization (tree spec
*** 1310,1315 ****
--- 1321,1337 ----
    *slot = build_tree_list (spec, tmpl);
  }
  
+ /* TYPE is a class type.  Returns true if TYPE is an explicitly
+    specialized class.  */
+ 
+ bool
+ explicit_class_specialization_p (tree type)
+ {
+   if (!CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
+     return false;
+   return !uses_template_parms (CLASSTYPE_TI_ARGS (type));
+ }
+ 
  /* Print the list of candidate FNS in an error message.  */
  
  void
*************** print_candidates (tree fns)
*** 1342,1347 ****
--- 1364,1374 ----
     template classes that appeared in the name of the function. See
     check_explicit_specialization for a more accurate description.
  
+    TSK indicates what kind of template declaration (if any) is being
+    declared.  TSK_TEMPLATE indicates that the declaration given by
+    DECL, though a FUNCTION_DECL, has template parameters, and is
+    therefore a template function.
+ 
     The template args (those explicitly specified and those deduced)
     are output in a newly created vector *TARGS_OUT.
  
*************** determine_specialization (tree template_
*** 1353,1359 ****
  			  tree decl,
  			  tree* targs_out,
  			  int need_member_template,
! 			  int template_count)
  {
    tree fns;
    tree targs;
--- 1380,1387 ----
  			  tree decl,
  			  tree* targs_out,
  			  int need_member_template,
! 			  int template_count,
! 			  tmpl_spec_kind tsk)
  {
    tree fns;
    tree targs;
*************** determine_specialization (tree template_
*** 1466,1471 ****
--- 1494,1511 ----
  				      (current_template_parms))))
  	    continue;
  
+ 	  /* Function templates cannot be specializations; there are
+ 	     no partial specializations of functions.  Therefore, if
+ 	     the type of DECL does not match FN, there is no
+ 	     match.  */
+ 	  if (tsk == tsk_template)
+ 	    {
+ 	      if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
+ 			     decl_arg_types))
+ 		candidates = tree_cons (NULL_TREE, fn, candidates);
+ 	      continue;
+ 	    }
+ 
  	  /* See whether this function might be a specialization of this
  	     template.  */
  	  targs = get_bindings (fn, decl, explicit_targs, /*check_ret=*/true);
*************** determine_specialization (tree template_
*** 1592,1601 ****
    /* We have one, and exactly one, match.  */
    if (candidates)
      {
        /* It was a specialization of an ordinary member function in a
  	 template class.  */
!       *targs_out = copy_node (DECL_TI_ARGS (TREE_VALUE (candidates)));
!       return DECL_TI_TEMPLATE (TREE_VALUE (candidates));
      }
  
    /* It was a specialization of a template.  */
--- 1632,1645 ----
    /* We have one, and exactly one, match.  */
    if (candidates)
      {
+       tree fn = TREE_VALUE (candidates);
+       /* DECL is a re-declaration of a template function.  */
+       if (TREE_CODE (fn) == TEMPLATE_DECL)
+ 	return fn;
        /* It was a specialization of an ordinary member function in a
  	 template class.  */
!       *targs_out = copy_node (DECL_TI_ARGS (fn));
!       return DECL_TI_TEMPLATE (fn);
      }
  
    /* It was a specialization of a template.  */
*************** check_explicit_specialization (tree decl
*** 2049,2055 ****
        tmpl = determine_specialization (declarator, decl,
  				       &targs,
  				       member_specialization,
! 				       template_count);
  
        if (!tmpl || tmpl == error_mark_node)
  	/* We couldn't figure out what this declaration was
--- 2093,2100 ----
        tmpl = determine_specialization (declarator, decl,
  				       &targs,
  				       member_specialization,
! 				       template_count,
! 				       tsk);
  
        if (!tmpl || tmpl == error_mark_node)
  	/* We couldn't figure out what this declaration was
*************** check_explicit_specialization (tree decl
*** 2095,2102 ****
  	    revert_static_member_fn (decl);
  
  	  /* If this is a specialization of a member template of a
! 	     template class.  In we want to return the TEMPLATE_DECL,
! 	     not the specialization of it.  */
  	  if (tsk == tsk_template)
  	    {
  	      SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
--- 2140,2147 ----
  	    revert_static_member_fn (decl);
  
  	  /* If this is a specialization of a member template of a
! 	     template class, we want to return the TEMPLATE_DECL, not
! 	     the specialization of it.  */
  	  if (tsk == tsk_template)
  	    {
  	      SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
*************** comp_template_parms (tree parms1, tree p
*** 2195,2202 ****
  
        for (i = 0; i < TREE_VEC_LENGTH (t2); ++i)
  	{
! 	  tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
! 	  tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
  
  	  if (TREE_CODE (parm1) != TREE_CODE (parm2))
  	    return 0;
--- 2240,2247 ----
  
        for (i = 0; i < TREE_VEC_LENGTH (t2); ++i)
  	{
!           tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
!           tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
  
  	  if (TREE_CODE (parm1) != TREE_CODE (parm2))
  	    return 0;
*************** check_default_tmpl_args (tree decl, tree
*** 2826,2831 ****
--- 2871,2877 ----
        for (i = 0; i < ntparms; ++i)
  	{
  	  tree parm = TREE_VEC_ELT (inner_parms, i);
+ 
  	  if (TREE_PURPOSE (parm))
  	    seen_def_arg_p = 1;
  	  else if (seen_def_arg_p)
*************** check_default_tmpl_args (tree decl, tree
*** 2890,2907 ****
  
        ntparms = TREE_VEC_LENGTH (inner_parms);
        for (i = 0; i < ntparms; ++i)
! 	if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)))
! 	  {
! 	    if (msg)
! 	      {
! 		error (msg, decl);
! 		msg = 0;
! 	      }
  
! 	    /* Clear out the default argument so that we are not
! 	       confused later.  */
! 	    TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE;
! 	  }
  
        /* At this point, if we're still interested in issuing messages,
  	 they must apply to classes surrounding the object declared.  */
--- 2936,2955 ----
  
        ntparms = TREE_VEC_LENGTH (inner_parms);
        for (i = 0; i < ntparms; ++i)
!         {
! 	  if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)))
! 	    {
! 	      if (msg)
! 	        {
! 		  error (msg, decl);
! 		  msg = 0;
! 	        }
  
! 	      /* Clear out the default argument so that we are not
! 	         confused later.  */
! 	      TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE;
! 	    }
!         }
  
        /* At this point, if we're still interested in issuing messages,
  	 they must apply to classes surrounding the object declared.  */
*************** push_template_decl_real (tree decl, bool
*** 2981,2987 ****
      DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
  
    /* See if this is a primary template.  */
!   primary = template_parm_scope_p ();
  
    if (primary)
      {
--- 3029,3041 ----
      DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
  
    /* See if this is a primary template.  */
!   if (is_friend && ctx)
!     /* A friend template that specifies a class context, i.e.
!          template <typename T> friend void A<T>::f();
!        is not primary.  */
!     primary = 0;
!   else
!     primary = template_parm_scope_p ();
  
    if (primary)
      {
*************** push_template_decl_real (tree decl, bool
*** 3013,3019 ****
  		 template. ... Template allocation functions shall
  		 have two or more parameters.  */
  	      error ("invalid template declaration of %qD", decl);
! 	      return decl;
  	    }
  	}
        else if (DECL_IMPLICIT_TYPEDEF_P (decl)
--- 3067,3073 ----
  		 template. ... Template allocation functions shall
  		 have two or more parameters.  */
  	      error ("invalid template declaration of %qD", decl);
! 	      return error_mark_node;
  	    }
  	}
        else if (DECL_IMPLICIT_TYPEDEF_P (decl)
*************** redeclare_class_template (tree type, tre
*** 3331,3336 ****
--- 3385,3393 ----
  tree
  fold_non_dependent_expr (tree expr)
  {
+   if (expr == NULL_TREE)
+     return NULL_TREE;
+ 
    /* If we're in a template, but EXPR isn't value dependent, simplify
       it.  We're supposed to treat:
  
*************** convert_template_argument (tree parm,
*** 3827,3837 ****
  			   tree in_decl)
  {
    tree val;
-   tree inner_args;
    int is_type, requires_type, is_tmpl_type, requires_tmpl_type;
  
-   inner_args = INNERMOST_TEMPLATE_ARGS (args);
- 
    if (TREE_CODE (arg) == TREE_LIST
        && TREE_CODE (TREE_VALUE (arg)) == OFFSET_REF)
      {
--- 3884,3891 ----
*************** convert_template_argument (tree parm,
*** 3923,3929 ****
  
  	      if (coerce_template_template_parms (parmparm, argparm,
  						  complain, in_decl,
! 						  inner_args))
  		{
  		  val = arg;
  
--- 3977,3983 ----
  
  	      if (coerce_template_template_parms (parmparm, argparm,
  						  complain, in_decl,
! 						  args))
  		{
  		  val = arg;
  
*************** coerce_template_parms (tree parms,
*** 4010,4015 ****
--- 4064,4070 ----
    tree inner_args;
    tree new_args;
    tree new_inner_args;
+   bool saved_skip_evaluation;
  
    inner_args = INNERMOST_TEMPLATE_ARGS (args);
    nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
*************** coerce_template_parms (tree parms,
*** 4032,4037 ****
--- 4087,4096 ----
        return error_mark_node;
      }
  
+   /* We need to evaluate the template arguments, even though this
+      template-id may be nested within a "sizeof".  */
+   saved_skip_evaluation = skip_evaluation;
+   skip_evaluation = false;
    new_inner_args = make_tree_vec (nparms);
    new_args = add_outermost_template_args (args, new_inner_args);
    for (i = 0; i < nparms; i++)
*************** coerce_template_parms (tree parms,
*** 4067,4072 ****
--- 4126,4132 ----
  	lost++;
        TREE_VEC_ELT (new_inner_args, i) = arg;
      }
+   skip_evaluation = saved_skip_evaluation;
  
    if (lost)
      return error_mark_node;
*************** tsubst_friend_function (tree decl, tree 
*** 5165,5171 ****
        tmpl = determine_specialization (template_id, new_friend,
  				       &new_args,
  				       /*need_member_template=*/0,
! 				       TREE_VEC_LENGTH (args));
        return instantiate_template (tmpl, new_args, tf_error);
      }
  
--- 5225,5232 ----
        tmpl = determine_specialization (template_id, new_friend,
  				       &new_args,
  				       /*need_member_template=*/0,
! 				       TREE_VEC_LENGTH (args),
! 				       tsk_none);
        return instantiate_template (tmpl, new_args, tf_error);
      }
  
*************** tsubst_friend_function (tree decl, tree 
*** 5229,5234 ****
--- 5290,5299 ----
        else
  	new_friend_result_template_info = NULL_TREE;
  
+       /* Make the init_value nonzero so pushdecl knows this is a defn.  */
+       if (new_friend_is_defn)
+ 	DECL_INITIAL (new_friend) = error_mark_node;
+ 
        /* Inside pushdecl_namespace_level, we will push into the
  	 current namespace. However, the friend function should go
  	 into the namespace of the template.  */
*************** tsubst_friend_class (tree friend_tmpl, t
*** 5389,5396 ****
  	push_nested_class (tsubst (context, args, tf_none, NULL_TREE));
      }
  
!   /* First, we look for a class template.  */
!   tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0);
  
    /* But, if we don't find one, it might be because we're in a
       situation like this:
--- 5454,5474 ----
  	push_nested_class (tsubst (context, args, tf_none, NULL_TREE));
      }
  
!   /* Look for a class template declaration.  We look for hidden names
!      because two friend declarations of the same template are the
!      same.  For example, in:
! 
!        struct A { 
!          template <typename> friend class F;
!        };
!        template <typename> struct B { 
!          template <typename> friend class F;
!        };
! 
!      both F templates are the same.  */
!   tmpl = lookup_name_real (DECL_NAME (friend_tmpl), 0, 0,
! 			   /*block_p=*/true, 0, 
! 			   LOOKUP_COMPLAIN | LOOKUP_HIDDEN);
  
    /* But, if we don't find one, it might be because we're in a
       situation like this:
*************** tsubst_decl (tree t, tree args, tsubst_f
*** 6648,6654 ****
  	tree tmpl = NULL_TREE;
  	tree ctx;
  	tree type = NULL_TREE;
! 	int local_p;
  
  	if (TREE_CODE (t) == TYPE_DECL)
  	  {
--- 6726,6732 ----
  	tree tmpl = NULL_TREE;
  	tree ctx;
  	tree type = NULL_TREE;
! 	bool local_p;
  
  	if (TREE_CODE (t) == TYPE_DECL)
  	  {
*************** tsubst_decl (tree t, tree args, tsubst_f
*** 6666,6705 ****
  	      }
  	  }
  
! 	/* Assume this is a non-local variable.  */
! 	local_p = 0;
  
! 	if (TYPE_P (CP_DECL_CONTEXT (t)))
! 	  ctx = tsubst_aggr_type (DECL_CONTEXT (t), args,
! 				  complain,
! 				  in_decl, /*entering_scope=*/1);
! 	else if (DECL_NAMESPACE_SCOPE_P (t))
! 	  ctx = DECL_CONTEXT (t);
  	else
  	  {
  	    /* Subsequent calls to pushdecl will fill this in.  */
  	    ctx = NULL_TREE;
! 	    local_p = 1;
! 	  }
! 
! 	/* Check to see if we already have this specialization.  */
! 	if (!local_p)
! 	  {
! 	    tmpl = DECL_TI_TEMPLATE (t);
! 	    gen_tmpl = most_general_template (tmpl);
! 	    argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl);
! 	    spec = retrieve_specialization (gen_tmpl, argvec,
! 					    /*class_specializations_p=*/false);
  	  }
! 	else
! 	  spec = retrieve_local_specialization (t);
! 
  	if (spec)
  	  {
  	    r = spec;
  	    break;
  	  }
  
  	r = copy_decl (t);
  	if (TREE_CODE (r) == VAR_DECL)
  	  {
--- 6744,6807 ----
  	      }
  	  }
  
! 	/* Check to see if we already have the specialization we
! 	   need.  */
! 	spec = NULL_TREE;
! 	if (DECL_CLASS_SCOPE_P (t) || DECL_NAMESPACE_SCOPE_P (t))
! 	  {
! 	    /* T is a static data member or namespace-scope entity.
! 	       We have to substitute into namespace-scope variables
! 	       (even though such entities are never templates) because
! 	       of cases like:
! 	       
! 	         template <class T> void f() { extern T t; }
  
! 	       where the entity referenced is not known until
! 	       instantiation time.  */
! 	    local_p = false;
! 	    ctx = DECL_CONTEXT (t);
! 	    if (DECL_CLASS_SCOPE_P (t))
! 	      {
! 		ctx = tsubst_aggr_type (ctx, args,
! 					complain,
! 					in_decl, /*entering_scope=*/1);
! 		/* If CTX is unchanged, then T is in fact the
! 		   specialization we want.  That situation occurs when
! 		   referencing a static data member within in its own
! 		   class.  We can use pointer equality, rather than
! 		   same_type_p, because DECL_CONTEXT is always
! 		   canonical.  */
! 		if (ctx == DECL_CONTEXT (t))
! 		  spec = t;
! 	      }
! 
! 	    if (!spec)
! 	      {
! 		tmpl = DECL_TI_TEMPLATE (t);
! 		gen_tmpl = most_general_template (tmpl);
! 		argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl);
! 		spec = (retrieve_specialization 
! 			(gen_tmpl, argvec,
! 			 /*class_specializations_p=*/false));
! 	      }
! 	  }
  	else
  	  {
+ 	    /* A local variable.  */
+ 	    local_p = true;
  	    /* Subsequent calls to pushdecl will fill this in.  */
  	    ctx = NULL_TREE;
! 	    spec = retrieve_local_specialization (t);
  	  }
! 	/* If we already have the specialization we need, there is
! 	   nothing more to do.  */ 
  	if (spec)
  	  {
  	    r = spec;
  	    break;
  	  }
  
+ 	/* Create a new node for the specialization we need.  */
  	r = copy_decl (t);
  	if (TREE_CODE (r) == VAR_DECL)
  	  {
*************** tsubst_decl (tree t, tree args, tsubst_f
*** 6711,6716 ****
--- 6813,6839 ----
  	    type = tsubst (TREE_TYPE (t), args, complain, in_decl);
  	    if (type == error_mark_node)
  	      return error_mark_node;
+ 	    if (TREE_CODE (type) == FUNCTION_TYPE)
+ 	      {
+ 		/* It may seem that this case cannot occur, since:
+ 
+ 		     typedef void f();
+ 		     void g() { f x; }
+ 
+ 		   declares a function, not a variable.  However:
+       
+ 		     typedef void f();
+ 		     template <typename T> void g() { T t; }
+ 		     template void g<f>();
+ 
+ 		   is an attempt to declare a variable with function
+ 		   type.  */
+ 		error ("variable %qD has function type",
+ 		       /* R is not yet sufficiently initialized, so we
+ 			  just use its name.  */
+ 		       DECL_NAME (r));
+ 		return error_mark_node;
+ 	      }
  	    type = complete_type (type);
  	    DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
  	      = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t);
*************** tsubst (tree t, tree args, tsubst_flags_
*** 7065,7070 ****
--- 7188,7202 ----
  	max = tsubst_template_arg (omax, args, complain, in_decl);
  	max = fold_decl_constant_value (max);
  
+ 	if (TREE_CODE (max) != INTEGER_CST 
+ 	    && TREE_CODE (max) != TEMPLATE_PARM_INDEX
+ 	    && !at_function_scope_p ())
+ 	  {
+ 	    if (complain & tf_error)
+ 	      error ("array bound is not an integer constant");
+ 	    return error_mark_node;
+ 	  }
+ 
  	/* [temp.deduct]
  
  	   Type deduction may fail for any of the following
*************** tsubst (tree t, tree args, tsubst_flags_
*** 7077,7083 ****
  	     indicated by the state of complain), so that
  	     another substitution can be found.  */
  	  return error_mark_node;
- 
  	else if (TREE_CODE (max) == INTEGER_CST
  		 && INT_CST_LT (max, integer_zero_node))
  	  {
--- 7209,7214 ----
*************** tsubst (tree t, tree args, tsubst_flags_
*** 7126,7135 ****
  	  {
  	    if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
  	      {
  		gcc_assert (TYPE_P (arg));
  		return cp_build_qualified_type_real
! 		  (arg, cp_type_quals (arg) | cp_type_quals (t),
! 		   complain | tf_ignore_bad_quals);
  	      }
  	    else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
  	      {
--- 7257,7276 ----
  	  {
  	    if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
  	      {
+ 		int quals;
  		gcc_assert (TYPE_P (arg));
+ 
+ 		/* cv-quals from the template are discarded when
+ 		   substituting in a function or reference type.  */
+ 		if (TREE_CODE (arg) == FUNCTION_TYPE
+ 		    || TREE_CODE (arg) == METHOD_TYPE
+ 		    || TREE_CODE (arg) == REFERENCE_TYPE)
+ 		  quals = cp_type_quals (arg);
+ 		else
+ 		  quals = cp_type_quals (arg) | cp_type_quals (t);
+ 		  
  		return cp_build_qualified_type_real
! 		  (arg, quals, complain | tf_ignore_bad_quals);
  	      }
  	    else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
  	      {
*************** tsubst_baselink (tree baselink, tree obj
*** 7584,7589 ****
--- 7725,7731 ----
      tree name;
      tree qualifying_scope;
      tree fns;
+     tree optype;
      tree template_args = 0;
      bool template_id_p = false;
  
*************** tsubst_baselink (tree baselink, tree obj
*** 7597,7602 ****
--- 7739,7745 ----
         ambiguous now.  Therefore, we perform the lookup again.  */
      qualifying_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (baselink));
      fns = BASELINK_FUNCTIONS (baselink);
+     optype = BASELINK_OPTYPE (baselink);
      if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
        {
  	template_id_p = true;
*************** tsubst_baselink (tree baselink, tree obj
*** 7624,7629 ****
--- 7767,7775 ----
  	= build_nt (TEMPLATE_ID_EXPR,
  		    BASELINK_FUNCTIONS (baselink),
  		    template_args);
+     /* Update the conversion operator type.  */
+     BASELINK_OPTYPE (baselink) 
+       = tsubst (optype, args, complain, in_decl);
  
      if (!object_type)
        object_type = current_class_type;
*************** tsubst_qualified_id (tree qualified_id, 
*** 7740,7746 ****
  	       /*template_arg_p=*/false));
      }
  
!   if (TREE_CODE (expr) != SCOPE_REF)
      expr = convert_from_reference (expr);
  
    return expr;
--- 7886,7896 ----
  	       /*template_arg_p=*/false));
      }
  
!   /* Expressions do not generally have reference type.  */
!   if (TREE_CODE (expr) != SCOPE_REF
!       /* However, if we're about to form a pointer-to-member, we just
! 	 want the referenced member referenced.  */
!       && TREE_CODE (expr) != OFFSET_REF)
      expr = convert_from_reference (expr);
  
    return expr;
*************** tsubst_expr (tree t, tree args, tsubst_f
*** 8395,8402 ****
  	}
        else
  	{
  	  if (FN_TRY_BLOCK_P (t))
! 	    stmt = begin_function_try_block ();
  	  else
  	    stmt = begin_try_block ();
  
--- 8545,8554 ----
  	}
        else
  	{
+ 	  tree compound_stmt = NULL_TREE;
+ 
  	  if (FN_TRY_BLOCK_P (t))
! 	    stmt = begin_function_try_block (&compound_stmt);
  	  else
  	    stmt = begin_try_block ();
  
*************** tsubst_expr (tree t, tree args, tsubst_f
*** 8409,8415 ****
  
  	  tsubst_expr (TRY_HANDLERS (t), args, complain, in_decl);
  	  if (FN_TRY_BLOCK_P (t))
! 	    finish_function_handler_sequence (stmt);
  	  else
  	    finish_handler_sequence (stmt);
  	}
--- 8561,8567 ----
  
  	  tsubst_expr (TRY_HANDLERS (t), args, complain, in_decl);
  	  if (FN_TRY_BLOCK_P (t))
! 	    finish_function_handler_sequence (stmt, compound_stmt);
  	  else
  	    finish_handler_sequence (stmt);
  	}
*************** tsubst_copy_and_build (tree t,
*** 9013,9019 ****
  					  in_decl));
  
      case OFFSETOF_EXPR:
!       return fold_offsetof (RECUR (TREE_OPERAND (t, 0)));
  
      case STMT_EXPR:
        {
--- 9165,9171 ----
  					  in_decl));
  
      case OFFSETOF_EXPR:
!       return finish_offsetof (RECUR (TREE_OPERAND (t, 0)));
  
      case STMT_EXPR:
        {
*************** unify (tree tparms, tree targs, tree par
*** 10045,10051 ****
  	  /* ARG must be constructed from a template class or a template
  	     template parameter.  */
  	  if (TREE_CODE (arg) != BOUND_TEMPLATE_TEMPLATE_PARM
! 	      && (TREE_CODE (arg) != RECORD_TYPE || !CLASSTYPE_TEMPLATE_INFO (arg)))
  	    return 1;
  
  	  {
--- 10197,10203 ----
  	  /* ARG must be constructed from a template class or a template
  	     template parameter.  */
  	  if (TREE_CODE (arg) != BOUND_TEMPLATE_TEMPLATE_PARM
! 	      && !CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P (arg))
  	    return 1;
  
  	  {
*************** unify (tree tparms, tree targs, tree par
*** 10136,10141 ****
--- 10288,10295 ----
  
      case TEMPLATE_PARM_INDEX:
        tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0));
+       if (tparm == error_mark_node)
+ 	return 1;
  
        if (TEMPLATE_PARM_LEVEL (parm)
  	  != template_decl_level (tparm))
*************** unify (tree tparms, tree targs, tree par
*** 10243,10263 ****
  	{
  	  tree parm_max;
  	  tree arg_max;
! 
! 	  parm_max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm));
! 	  arg_max = TYPE_MAX_VALUE (TYPE_DOMAIN (arg));
  
  	  /* Our representation of array types uses "N - 1" as the
  	     TYPE_MAX_VALUE for an array with "N" elements, if "N" is
! 	     not an integer constant.  */
! 	  if (TREE_CODE (parm_max) == MINUS_EXPR)
  	    {
! 	      arg_max = fold_build2 (PLUS_EXPR,
! 				     integer_type_node,
! 				     arg_max,
! 				     TREE_OPERAND (parm_max, 1));
  	      parm_max = TREE_OPERAND (parm_max, 0);
  	    }
  
  	  if (unify (tparms, targs, parm_max, arg_max, UNIFY_ALLOW_INTEGER))
  	    return 1;
--- 10397,10452 ----
  	{
  	  tree parm_max;
  	  tree arg_max;
! 	  bool parm_cst;
! 	  bool arg_cst;
  
  	  /* Our representation of array types uses "N - 1" as the
  	     TYPE_MAX_VALUE for an array with "N" elements, if "N" is
! 	     not an integer constant.  We cannot unify arbitrarily
! 	     complex expressions, so we eliminate the MINUS_EXPRs
! 	     here.  */
! 	  parm_max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm));
! 	  parm_cst = TREE_CODE (parm_max) == INTEGER_CST;
! 	  if (!parm_cst)
  	    {
! 	      gcc_assert (TREE_CODE (parm_max) == MINUS_EXPR);
  	      parm_max = TREE_OPERAND (parm_max, 0);
  	    }
+ 	  arg_max = TYPE_MAX_VALUE (TYPE_DOMAIN (arg));
+ 	  arg_cst = TREE_CODE (arg_max) == INTEGER_CST;
+ 	  if (!arg_cst)
+ 	    {
+ 	      /* The ARG_MAX may not be a simple MINUS_EXPR, if we are
+ 		 trying to unify the type of a variable with the type
+ 		 of a template parameter.  For example:
+ 
+                    template <unsigned int N>
+ 		   void f (char (&) [N]);
+ 		   int g(); 
+ 		   void h(int i) {
+                      char a[g(i)];
+ 		     f(a); 
+                    }
+ 
+                 Here, the type of the ARG will be "int [g(i)]", and
+                 may be a SAVE_EXPR, etc.  */
+ 	      if (TREE_CODE (arg_max) != MINUS_EXPR)
+ 		return 1;
+ 	      arg_max = TREE_OPERAND (arg_max, 0);
+ 	    }
+ 
+ 	  /* If only one of the bounds used a MINUS_EXPR, compensate
+ 	     by adding one to the other bound.  */
+ 	  if (parm_cst && !arg_cst)
+ 	    parm_max = fold_build2 (PLUS_EXPR,
+ 				    integer_type_node,
+ 				    parm_max,
+ 				    integer_one_node);
+ 	  else if (arg_cst && !parm_cst)
+ 	    arg_max = fold_build2 (PLUS_EXPR,
+ 				   integer_type_node,
+ 				   arg_max,
+ 				   integer_one_node);
  
  	  if (unify (tparms, targs, parm_max, arg_max, UNIFY_ALLOW_INTEGER))
  	    return 1;
*************** value_dependent_expression_p (tree expre
*** 12432,12463 ****
  	      || value_dependent_expression_p (TREE_OPERAND (expression, 1)));
  
      case CALL_EXPR:
!       /* A CALL_EXPR is value-dependent if any argument is
! 	 value-dependent.  Why do we have to handle CALL_EXPRs in this
! 	 function at all?  First, some function calls, those for which
! 	 value_dependent_expression_p is true, man appear in constant
! 	 expressions.  Second, there appear to be bugs which result in
! 	 other CALL_EXPRs reaching this point. */
!       {
! 	tree function = TREE_OPERAND (expression, 0);
! 	tree args = TREE_OPERAND (expression, 1);
! 
! 	if (value_dependent_expression_p (function))
! 	  return true;
! 
! 	if (! args)
! 	  return false;
! 
! 	if (TREE_CODE (args) == TREE_LIST)
! 	  {
! 	    for (; args; args = TREE_CHAIN (args))
! 	      if (value_dependent_expression_p (TREE_VALUE (args)))
! 		return true;
! 	    return false;
! 	  }
! 
! 	return value_dependent_expression_p (args);
!       }
  
      default:
        /* A constant expression is value-dependent if any subexpression is
--- 12621,12630 ----
  	      || value_dependent_expression_p (TREE_OPERAND (expression, 1)));
  
      case CALL_EXPR:
!       /* A CALL_EXPR may appear in a constant expression if it is a
! 	 call to a builtin function, e.g., __builtin_constant_p.  All
! 	 such calls are value-dependent.  */
!       return true;
  
      default:
        /* A constant expression is value-dependent if any subexpression is
*************** type_dependent_expression_p (tree expres
*** 12513,12519 ****
      return false;
  
    /* An unresolved name is always dependent.  */
!   if (TREE_CODE (expression) == IDENTIFIER_NODE)
      return true;
  
    /* Some expression forms are never type-dependent.  */
--- 12680,12687 ----
      return false;
  
    /* An unresolved name is always dependent.  */
!   if (TREE_CODE (expression) == IDENTIFIER_NODE
!       || TREE_CODE (expression) == USING_DECL)
      return true;
  
    /* Some expression forms are never type-dependent.  */
diff -Nrcpad gcc-4.1.1/gcc/cp/repo.c gcc-4.1.2/gcc/cp/repo.c
*** gcc-4.1.1/gcc/cp/repo.c	Wed Jan  4 01:04:03 2006
--- gcc-4.1.2/gcc/cp/repo.c	Sat Sep  2 06:56:59 2006
*************** Boston, MA 02110-1301, USA.  */
*** 40,52 ****
  
  static char *extract_string (char **);
  static const char *get_base_filename (const char *);
! static void open_repo_file (const char *);
  static char *afgets (FILE *);
! static void reopen_repo_file_for_write (void);
  
  static GTY(()) tree pending_repo;
  static char *repo_name;
- static FILE *repo_file;
  
  static const char *old_args, *old_dir, *old_main;
  
--- 40,51 ----
  
  static char *extract_string (char **);
  static const char *get_base_filename (const char *);
! static FILE *open_repo_file (const char *);
  static char *afgets (FILE *);
! static FILE *reopen_repo_file_for_write (void);
  
  static GTY(()) tree pending_repo;
  static char *repo_name;
  
  static const char *old_args, *old_dir, *old_main;
  
*************** get_base_filename (const char *filename)
*** 118,131 ****
    return lbasename (filename);
  }
  
! static void
  open_repo_file (const char *filename)
  {
    const char *p;
    const char *s = get_base_filename (filename);
  
    if (s == NULL)
!     return;
  
    p = lbasename (s);
    p = strrchr (p, '.');
--- 117,130 ----
    return lbasename (filename);
  }
  
! static FILE *
  open_repo_file (const char *filename)
  {
    const char *p;
    const char *s = get_base_filename (filename);
  
    if (s == NULL)
!     return NULL;
  
    p = lbasename (s);
    p = strrchr (p, '.');
*************** open_repo_file (const char *filename)
*** 136,142 ****
    memcpy (repo_name, s, p - s);
    memcpy (repo_name + (p - s), ".rpo", 5);
  
!   repo_file = fopen (repo_name, "r");
  }
  
  static char *
--- 135,141 ----
    memcpy (repo_name, s, p - s);
    memcpy (repo_name + (p - s), ".rpo", 5);
  
!   return fopen (repo_name, "r");
  }
  
  static char *
*************** void
*** 155,160 ****
--- 154,160 ----
  init_repo (void)
  {
    char *buf;
+   FILE *repo_file;
  
    if (! flag_use_repository)
      return;
*************** init_repo (void)
*** 167,173 ****
    if (!temporary_obstack_initialized_p)
      gcc_obstack_init (&temporary_obstack);
  
!   open_repo_file (main_input_filename);
  
    if (repo_file == 0)
      return;
--- 167,173 ----
    if (!temporary_obstack_initialized_p)
      gcc_obstack_init (&temporary_obstack);
  
!   repo_file = open_repo_file (main_input_filename);
  
    if (repo_file == 0)
      return;
*************** init_repo (void)
*** 205,220 ****
    fclose (repo_file);
  }
  
! static void
  reopen_repo_file_for_write (void)
  {
!   repo_file = fopen (repo_name, "w");
  
    if (repo_file == 0)
      {
        error ("can't create repository information file %qs", repo_name);
        flag_use_repository = 0;
      }
  }
  
  /* Emit any pending repos.  */
--- 205,222 ----
    fclose (repo_file);
  }
  
! static FILE *
  reopen_repo_file_for_write (void)
  {
!   FILE *repo_file = fopen (repo_name, "w");
  
    if (repo_file == 0)
      {
        error ("can't create repository information file %qs", repo_name);
        flag_use_repository = 0;
      }
+ 
+   return repo_file;
  }
  
  /* Emit any pending repos.  */
*************** finish_repo (void)
*** 224,237 ****
  {
    tree t;
    char *dir, *args;
  
    if (!flag_use_repository)
      return;
  
    if (errorcount || sorrycount)
!     goto out;
  
!   reopen_repo_file_for_write ();
    if (repo_file == 0)
      goto out;
  
--- 226,240 ----
  {
    tree t;
    char *dir, *args;
+   FILE *repo_file;
  
    if (!flag_use_repository)
      return;
  
    if (errorcount || sorrycount)
!     return;
  
!   repo_file = reopen_repo_file_for_write ();
    if (repo_file == 0)
      goto out;
  
diff -Nrcpad gcc-4.1.1/gcc/cp/rtti.c gcc-4.1.2/gcc/cp/rtti.c
*** gcc-4.1.1/gcc/cp/rtti.c	Wed Apr 19 17:19:35 2006
--- gcc-4.1.2/gcc/cp/rtti.c	Mon Oct 23 07:42:02 2006
*************** get_tinfo_decl_dynamic (tree exp)
*** 228,234 ****
    tree type;
    tree t;
  
!   if (exp == error_mark_node)
      return error_mark_node;
  
    /* peel back references, so they match.  */
--- 228,234 ----
    tree type;
    tree t;
  
!   if (error_operand_p (exp))
      return error_mark_node;
  
    /* peel back references, so they match.  */
*************** get_tinfo_decl (tree type)
*** 342,352 ****
    tree name;
    tree d;
  
!   if (COMPLETE_TYPE_P (type)
!       && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
      {
        error ("cannot create type information for type %qT because "
! 	     "its size is variable",
  	     type);
        return error_mark_node;
      }
--- 342,351 ----
    tree name;
    tree d;
  
!   if (variably_modified_type_p (type, /*fn=*/NULL_TREE))
      {
        error ("cannot create type information for type %qT because "
! 	     "it involves types of variable size",
  	     type);
        return error_mark_node;
      }
*************** tinfo_base_init (tinfo_s *ti, tree targe
*** 813,825 ****
      TREE_STATIC (name_decl) = 1;
      DECL_EXTERNAL (name_decl) = 0;
      DECL_TINFO_P (name_decl) = 1;
!     if (involves_incomplete_p (target))
!       {
! 	TREE_PUBLIC (name_decl) = 0;
! 	DECL_INTERFACE_KNOWN (name_decl) = 1;
!       }
!     else
!       set_linkage_according_to_type (target, name_decl);
      import_export_decl (name_decl);
      DECL_INITIAL (name_decl) = name_string;
      mark_used (name_decl);
--- 812,818 ----
      TREE_STATIC (name_decl) = 1;
      DECL_EXTERNAL (name_decl) = 0;
      DECL_TINFO_P (name_decl) = 1;
!     set_linkage_according_to_type (target, name_decl);
      import_export_decl (name_decl);
      DECL_INITIAL (name_decl) = name_string;
      mark_used (name_decl);
diff -Nrcpad gcc-4.1.1/gcc/cp/search.c gcc-4.1.2/gcc/cp/search.c
*** gcc-4.1.1/gcc/cp/search.c	Mon May 15 09:22:44 2006
--- gcc-4.1.2/gcc/cp/search.c	Thu Aug  3 17:09:57 2006
*************** friend_accessible_p (tree scope, tree de
*** 792,799 ****
      if (protected_accessible_p (decl, TREE_VALUE (t), binfo))
        return 1;
  
!   /* Nested classes are implicitly friends of their enclosing types, as
!      per core issue 45 (this is a change from the standard).  */
    if (TYPE_P (scope))
      for (t = TYPE_CONTEXT (scope); t && TYPE_P (t); t = TYPE_CONTEXT (t))
        if (protected_accessible_p (decl, t, binfo))
--- 792,799 ----
      if (protected_accessible_p (decl, TREE_VALUE (t), binfo))
        return 1;
  
!   /* Nested classes have the same access as their enclosing types, as
!      per DR 45 (this is a change from the standard).  */
    if (TYPE_P (scope))
      for (t = TYPE_CONTEXT (scope); t && TYPE_P (t); t = TYPE_CONTEXT (t))
        if (protected_accessible_p (decl, t, binfo))
*************** lookup_member (tree xbasetype, tree name
*** 1209,1215 ****
      }
    else
      {
!       gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)));
        type = xbasetype;
        xbasetype = NULL_TREE;
      }
--- 1209,1216 ----
      }
    else
      {
!       if (!IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)))
! 	return NULL_TREE;
        type = xbasetype;
        xbasetype = NULL_TREE;
      }
*************** adjust_result_of_qualified_name_lookup (
*** 1480,1493 ****
  					tree context_class)
  {
    if (context_class && context_class != error_mark_node
        && CLASS_TYPE_P (qualifying_scope)
        && DERIVED_FROM_P (qualifying_scope, context_class)
        && BASELINK_P (decl))
      {
        tree base;
  
-       gcc_assert (CLASS_TYPE_P (context_class));
- 
        /* Look for the QUALIFYING_SCOPE as a base of the CONTEXT_CLASS.
  	 Because we do not yet know which function will be chosen by
  	 overload resolution, we cannot yet check either accessibility
--- 1481,1493 ----
  					tree context_class)
  {
    if (context_class && context_class != error_mark_node
+       && CLASS_TYPE_P (context_class)
        && CLASS_TYPE_P (qualifying_scope)
        && DERIVED_FROM_P (qualifying_scope, context_class)
        && BASELINK_P (decl))
      {
        tree base;
  
        /* Look for the QUALIFYING_SCOPE as a base of the CONTEXT_CLASS.
  	 Because we do not yet know which function will be chosen by
  	 overload resolution, we cannot yet check either accessibility
diff -Nrcpad gcc-4.1.1/gcc/cp/semantics.c gcc-4.1.2/gcc/cp/semantics.c
*** gcc-4.1.1/gcc/cp/semantics.c	Wed May 17 08:44:36 2006
--- gcc-4.1.2/gcc/cp/semantics.c	Sun Jan 28 18:18:54 2007
*************** begin_try_block (void)
*** 975,986 ****
    return r;
  }
  
! /* Likewise, for a function-try-block.  */
  
  tree
! begin_function_try_block (void)
  {
!   tree r = begin_try_block ();
    FN_TRY_BLOCK_P (r) = 1;
    return r;
  }
--- 975,992 ----
    return r;
  }
  
! /* Likewise, for a function-try-block.  The block returned in
!    *COMPOUND_STMT is an artificial outer scope, containing the
!    function-try-block.  */
  
  tree
! begin_function_try_block (tree *compound_stmt)
  {
!   tree r;
!   /* This outer scope does not exist in the C++ standard, but we need
!      a place to put __FUNCTION__ and similar variables.  */
!   *compound_stmt = begin_compound_stmt (0);
!   r = begin_try_block ();
    FN_TRY_BLOCK_P (r) = 1;
    return r;
  }
*************** finish_handler_sequence (tree try_block)
*** 1034,1046 ****
    check_handlers (TRY_HANDLERS (try_block));
  }
  
! /* Likewise, for a function-try-block.  */
  
  void
! finish_function_handler_sequence (tree try_block)
  {
    in_function_try_handler = 0;
    finish_handler_sequence (try_block);
  }
  
  /* Begin a handler.  Returns a HANDLER if appropriate.  */
--- 1040,1055 ----
    check_handlers (TRY_HANDLERS (try_block));
  }
  
! /* Finish the handler-seq for a function-try-block, given by
!    TRY_BLOCK.  COMPOUND_STMT is the outer block created by
!    begin_function_try_block.  */
  
  void
! finish_function_handler_sequence (tree try_block, tree compound_stmt)
  {
    in_function_try_handler = 0;
    finish_handler_sequence (try_block);
+   finish_compound_stmt (compound_stmt);
  }
  
  /* Begin a handler.  Returns a HANDLER if appropriate.  */
*************** tree
*** 1285,1290 ****
--- 1294,1303 ----
  finish_label_stmt (tree name)
  {
    tree decl = define_label (input_location, name);
+ 
+   if (decl == error_mark_node)
+     return error_mark_node;
+ 
    return add_stmt (build_stmt (LABEL_EXPR, decl));
  }
  
*************** check_accessibility_of_qualified_id (tre
*** 1494,1502 ****
         its bases.  */
      qualifying_type = currently_open_derived_class (scope);
  
!   if (qualifying_type && IS_AGGR_TYPE_CODE (TREE_CODE (qualifying_type)))
!     /* It is possible for qualifying type to be a TEMPLATE_TYPE_PARM
!        or similar in a default argument value.  */
      perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl);
  }
  
--- 1507,1517 ----
         its bases.  */
      qualifying_type = currently_open_derived_class (scope);
  
!   if (qualifying_type 
!       /* It is possible for qualifying type to be a TEMPLATE_TYPE_PARM
! 	 or similar in a default argument value.  */
!       && CLASS_TYPE_P (qualifying_type)
!       && !dependent_type_p (qualifying_type))
      perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl);
  }
  
*************** finish_pseudo_destructor_expr (tree obje
*** 1957,1962 ****
--- 1972,1984 ----
  	  error ("invalid qualifying scope in pseudo-destructor name");
  	  return error_mark_node;
  	}
+       if (scope && TYPE_P (scope) && !check_dtor_name (scope, destructor))
+ 	{
+ 	  error ("qualified type %qT does not match destructor name ~%qT",
+ 		 scope, destructor);
+ 	  return error_mark_node;
+ 	}
+ 
  
        /* [expr.pseudo] says both:
  
*************** finish_compound_literal (tree type, VEC(
*** 2013,2018 ****
--- 2035,2046 ----
  {
    tree compound_literal;
  
+   if (!TYPE_OBJ_P (type))
+     {
+       error ("compound literal of non-object type %qT", type);
+       return error_mark_node;
+     }
+ 
    /* Build a CONSTRUCTOR for the INITIALIZER_LIST.  */
    compound_literal = build_constructor (NULL_TREE, initializer_list);
    if (processing_template_decl)
*************** check_template_template_default_arg (tre
*** 2114,2132 ****
        && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
      {
        if (TREE_CODE (argument) == TYPE_DECL)
! 	{
! 	  tree t = TREE_TYPE (argument);
! 
! 	  /* Try to emit a slightly smarter error message if we detect
! 	     that the user is using a template instantiation.  */
! 	  if (CLASSTYPE_TEMPLATE_INFO (t)
! 	      && CLASSTYPE_TEMPLATE_INSTANTIATION (t))
! 	    error ("invalid use of type %qT as a default value for a "
! 		   "template template-parameter", t);
! 	  else
! 	    error ("invalid use of %qD as a default value for a template "
! 		   "template-parameter", argument);
! 	}
        else
  	error ("invalid default argument for a template template parameter");
        return error_mark_node;
--- 2142,2149 ----
        && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
      {
        if (TREE_CODE (argument) == TYPE_DECL)
! 	error ("invalid use of type %qT as a default value for a template "
! 	       "template-parameter", TREE_TYPE (argument));
        else
  	error ("invalid default argument for a template template parameter");
        return error_mark_node;
*************** begin_class_definition (tree t)
*** 2192,2198 ****
       before.  */
    if (! TYPE_ANONYMOUS_P (t))
      {
!       struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename));
        CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
        SET_CLASSTYPE_INTERFACE_UNKNOWN_X
  	(t, finfo->interface_unknown);
--- 2209,2215 ----
       before.  */
    if (! TYPE_ANONYMOUS_P (t))
      {
!       struct c_fileinfo *finfo = get_fileinfo (input_filename);
        CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
        SET_CLASSTYPE_INTERFACE_UNKNOWN_X
  	(t, finfo->interface_unknown);
*************** note_decl_for_pch (tree decl)
*** 2309,2316 ****
  
    /* There's a good chance that we'll have to mangle names at some
       point, even if only for emission in debugging information.  */
!   if (TREE_CODE (decl) == VAR_DECL
!       || TREE_CODE (decl) == FUNCTION_DECL)
      mangle_decl (decl);
  }
  
--- 2326,2334 ----
  
    /* There's a good chance that we'll have to mangle names at some
       point, even if only for emission in debugging information.  */
!   if ((TREE_CODE (decl) == VAR_DECL
!        || TREE_CODE (decl) == FUNCTION_DECL)
!       && !processing_template_decl)
      mangle_decl (decl);
  }
  
*************** finish_typeof (tree expr)
*** 2858,2863 ****
--- 2876,2905 ----
    return type;
  }
  
+ /* Perform C++-specific checks for __builtin_offsetof before calling
+    fold_offsetof.  */
+ 
+ tree
+ finish_offsetof (tree expr)
+ {
+   if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
+     {
+       error ("cannot apply %<offsetof%> to destructor %<~%T%>",
+ 	      TREE_OPERAND (expr, 2));
+       return error_mark_node;
+     }
+   if (TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE
+       || TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE
+       || TREE_CODE (TREE_TYPE (expr)) == UNKNOWN_TYPE)
+     {
+       if (TREE_CODE (expr) == COMPONENT_REF)
+ 	expr = TREE_OPERAND (expr, 1);
+       error ("cannot apply %<offsetof%> to member function %qD", expr);
+       return error_mark_node;
+     }
+   return fold_offsetof (expr);
+ }
+ 
  /* Called from expand_body via walk_tree.  Replace all AGGR_INIT_EXPRs
     with equivalent CALL_EXPRs.  */
  
diff -Nrcpad gcc-4.1.1/gcc/cp/tree.c gcc-4.1.2/gcc/cp/tree.c
*** gcc-4.1.1/gcc/cp/tree.c	Wed Jan 11 18:09:17 2006
--- gcc-4.1.2/gcc/cp/tree.c	Fri Feb  9 02:52:53 2007
*************** int
*** 827,833 ****
  is_overloaded_fn (tree x)
  {
    /* A baselink is also considered an overloaded function.  */
!   if (TREE_CODE (x) == OFFSET_REF)
      x = TREE_OPERAND (x, 1);
    if (BASELINK_P (x))
      x = BASELINK_FUNCTIONS (x);
--- 827,834 ----
  is_overloaded_fn (tree x)
  {
    /* A baselink is also considered an overloaded function.  */
!   if (TREE_CODE (x) == OFFSET_REF
!       || TREE_CODE (x) == COMPONENT_REF)
      x = TREE_OPERAND (x, 1);
    if (BASELINK_P (x))
      x = BASELINK_FUNCTIONS (x);
*************** get_first_fn (tree from)
*** 856,861 ****
--- 857,864 ----
  {
    gcc_assert (is_overloaded_fn (from));
    /* A baselink is also considered an overloaded function.  */
+   if (TREE_CODE (from) == COMPONENT_REF)
+     from = TREE_OPERAND (from, 1);
    if (BASELINK_P (from))
      from = BASELINK_FUNCTIONS (from);
    return OVL_CURRENT (from);
*************** cp_cannot_inline_tree_fn (tree* fnp)
*** 2035,2047 ****
        && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
      return 1;
  
!   /* Don't auto-inline anything that might not be bound within
!      this unit of translation.
!      Exclude comdat functions from this rule.  While they can be bound
!      to the other unit, they all must be the same.  This is especially
!      important so templates can inline.  */
!   if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn)
!       && !DECL_COMDAT (fn))
      {
        DECL_UNINLINABLE (fn) = 1;
        return 1;
--- 2038,2046 ----
        && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
      return 1;
  
!   /* Don't auto-inline functions that might be replaced at link-time
!      with an alternative definition.  */ 
!   if (!DECL_DECLARED_INLINE_P (fn) && DECL_REPLACEABLE_P (fn))
      {
        DECL_UNINLINABLE (fn) = 1;
        return 1;
*************** decl_linkage (tree decl)
*** 2188,2196 ****
    return lk_internal;
  }
  
! /* EXP is an expression that we want to pre-evaluate.  Returns via INITP an
!    expression to perform the pre-evaluation, and returns directly an
!    expression to use the precalculated result.  */
  
  tree
  stabilize_expr (tree exp, tree* initp)
--- 2187,2197 ----
    return lk_internal;
  }
  
! /* EXP is an expression that we want to pre-evaluate.  Returns (in
!    *INITP) an expression that will perform the pre-evaluation.  The
!    value returned by this function is a side-effect free expression
!    equivalent to the pre-evaluated expression.  Callers must ensure
!    that *INITP is evaluated before EXP.  */
  
  tree
  stabilize_expr (tree exp, tree* initp)
*************** stabilize_expr (tree exp, tree* initp)
*** 2198,2206 ****
    tree init_expr;
  
    if (!TREE_SIDE_EFFECTS (exp))
!     {
!       init_expr = NULL_TREE;
!     }
    else if (!real_lvalue_p (exp)
  	   || !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (exp)))
      {
--- 2199,2205 ----
    tree init_expr;
  
    if (!TREE_SIDE_EFFECTS (exp))
!     init_expr = NULL_TREE;
    else if (!real_lvalue_p (exp)
  	   || !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (exp)))
      {
*************** stabilize_expr (tree exp, tree* initp)
*** 2214,2221 ****
        exp = TARGET_EXPR_SLOT (init_expr);
        exp = build_indirect_ref (exp, 0);
      }
- 
    *initp = init_expr;
    return exp;
  }
  
--- 2213,2221 ----
        exp = TARGET_EXPR_SLOT (init_expr);
        exp = build_indirect_ref (exp, 0);
      }
    *initp = init_expr;
+ 
+   gcc_assert (!TREE_SIDE_EFFECTS (exp));
    return exp;
  }
  
*************** add_stmt_to_compound (tree orig, tree ne
*** 2232,2239 ****
    return build2 (COMPOUND_EXPR, void_type_node, orig, new);
  }
  
! /* Like stabilize_expr, but for a call whose args we want to
!    pre-evaluate.  */
  
  void
  stabilize_call (tree call, tree *initp)
--- 2232,2241 ----
    return build2 (COMPOUND_EXPR, void_type_node, orig, new);
  }
  
! /* Like stabilize_expr, but for a call whose arguments we want to
!    pre-evaluate.  CALL is modified in place to use the pre-evaluated
!    arguments, while, upon return, *INITP contains an expression to
!    compute the arguments.  */
  
  void
  stabilize_call (tree call, tree *initp)
*************** stabilize_call (tree call, tree *initp)
*** 2258,2307 ****
    *initp = inits;
  }
  
! /* Like stabilize_expr, but for an initialization.  If we are initializing
!    an object of class type, we don't want to introduce an extra temporary,
!    so we look past the TARGET_EXPR and stabilize the arguments of the call
!    instead.  */
  
  bool
  stabilize_init (tree init, tree *initp)
  {
    tree t = init;
  
    if (t == error_mark_node)
      return true;
  
    if (TREE_CODE (t) == INIT_EXPR
        && TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR)
-     TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
-   else
      {
!       if (TREE_CODE (t) == INIT_EXPR)
! 	t = TREE_OPERAND (t, 1);
!       if (TREE_CODE (t) == TARGET_EXPR)
! 	t = TARGET_EXPR_INITIAL (t);
!       if (TREE_CODE (t) == COMPOUND_EXPR)
! 	t = expr_last (t);
!       if (TREE_CODE (t) == CONSTRUCTOR
! 	  && EMPTY_CONSTRUCTOR_P (t))
! 	{
! 	  /* Default-initialization.  */
! 	  *initp = NULL_TREE;
! 	  return true;
! 	}
  
!       /* If the initializer is a COND_EXPR, we can't preevaluate
! 	 anything.  */
!       if (TREE_CODE (t) == COND_EXPR)
! 	return false;
  
!       /* The TARGET_EXPR might be initializing via bitwise copy from
! 	 another variable; leave that alone.  */
!       if (TREE_SIDE_EFFECTS (t))
! 	stabilize_call (t, initp);
      }
  
!   return true;
  }
  
  /* Like "fold", but should be used whenever we might be processing the
--- 2260,2317 ----
    *initp = inits;
  }
  
! /* Like stabilize_expr, but for an initialization.  
! 
!    If the initialization is for an object of class type, this function
!    takes care not to introduce additional temporaries.
! 
!    Returns TRUE iff the expression was successfully pre-evaluated,
!    i.e., if INIT is now side-effect free, except for, possible, a
!    single call to a constructor.  */
  
  bool
  stabilize_init (tree init, tree *initp)
  {
    tree t = init;
  
+   *initp = NULL_TREE;
+ 
    if (t == error_mark_node)
      return true;
  
    if (TREE_CODE (t) == INIT_EXPR
        && TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR)
      {
!       TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
!       return true;
!     }
  
!   if (TREE_CODE (t) == INIT_EXPR)
!     t = TREE_OPERAND (t, 1);
!   if (TREE_CODE (t) == TARGET_EXPR)
!     t = TARGET_EXPR_INITIAL (t);
!   if (TREE_CODE (t) == COMPOUND_EXPR)
!     t = expr_last (t);
!   if (TREE_CODE (t) == CONSTRUCTOR
!       && EMPTY_CONSTRUCTOR_P (t))
!     /* Default-initialization.  */
!     return true;
  
!   /* If the initializer is a COND_EXPR, we can't preevaluate
!      anything.  */
!   if (TREE_CODE (t) == COND_EXPR)
!     return false;
! 
!   if (TREE_CODE (t) == CALL_EXPR
!       || TREE_CODE (t) == AGGR_INIT_EXPR)
!     {
!       stabilize_call (t, initp);
!       return true;
      }
  
!   /* The initialization is being performed via a bitwise copy -- and
!      the item copied may have side effects.  */
!   return TREE_SIDE_EFFECTS (init);
  }
  
  /* Like "fold", but should be used whenever we might be processing the
diff -Nrcpad gcc-4.1.1/gcc/cp/typeck.c gcc-4.1.2/gcc/cp/typeck.c
*** gcc-4.1.1/gcc/cp/typeck.c	Sat May  6 00:23:51 2006
--- gcc-4.1.2/gcc/cp/typeck.c	Fri Dec  1 22:29:13 2006
*************** commonparms (tree p1, tree p2)
*** 227,233 ****
  tree
  original_type (tree t)
  {
!   while (TYPE_NAME (t) != NULL_TREE)
      {
        tree x = TYPE_NAME (t);
        if (TREE_CODE (x) != TYPE_DECL)
--- 227,234 ----
  tree
  original_type (tree t)
  {
!   while (t != error_mark_node
! 	 && TYPE_NAME (t) != NULL_TREE)
      {
        tree x = TYPE_NAME (t);
        if (TREE_CODE (x) != TYPE_DECL)
*************** type_after_usual_arithmetic_conversions 
*** 258,264 ****
  	      || TREE_CODE (t1) == ENUMERAL_TYPE);
    gcc_assert (ARITHMETIC_TYPE_P (t2)
  	      || TREE_CODE (t2) == COMPLEX_TYPE
! 	      || TREE_CODE (t1) == VECTOR_TYPE
  	      || TREE_CODE (t2) == ENUMERAL_TYPE);
  
    /* In what follows, we slightly generalize the rules given in [expr] so
--- 259,265 ----
  	      || TREE_CODE (t1) == ENUMERAL_TYPE);
    gcc_assert (ARITHMETIC_TYPE_P (t2)
  	      || TREE_CODE (t2) == COMPLEX_TYPE
! 	      || TREE_CODE (t2) == VECTOR_TYPE
  	      || TREE_CODE (t2) == ENUMERAL_TYPE);
  
    /* In what follows, we slightly generalize the rules given in [expr] so
*************** compparms (tree parms1, tree parms2)
*** 1232,1269 ****
  tree
  cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
  {
-   enum tree_code type_code;
    tree value;
!   const char *op_name;
  
    gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
    if (type == error_mark_node)
      return error_mark_node;
  
-   if (dependent_type_p (type))
-     {
-       value = build_min (op, size_type_node, type);
-       TREE_READONLY (value) = 1;
-       return value;
-     }
- 
-   op_name = operator_name_info[(int) op].name;
- 
    type = non_reference (type);
!   type_code = TREE_CODE (type);
! 
!   if (type_code == METHOD_TYPE)
      {
        if (complain && (pedantic || warn_pointer_arith))
! 	pedwarn ("invalid application of %qs to a member function", op_name);
        value = size_one_node;
      }
-   else
-     value = c_sizeof_or_alignof_type (complete_type (type),
- 				      op == SIZEOF_EXPR,
- 				      complain);
  
!   return value;
  }
  
  /* Process a sizeof or alignof expression where the operand is an
--- 1233,1276 ----
  tree
  cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
  {
    tree value;
!   bool dependent_p;
  
    gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
    if (type == error_mark_node)
      return error_mark_node;
  
    type = non_reference (type);
!   if (TREE_CODE (type) == METHOD_TYPE)
      {
        if (complain && (pedantic || warn_pointer_arith))
! 	pedwarn ("invalid application of %qs to a member function", 
! 		 operator_name_info[(int) op].name);
        value = size_one_node;
      }
  
!   dependent_p = dependent_type_p (type);
!   if (!dependent_p)
!     complete_type (type);
!   if (dependent_p
!       /* VLA types will have a non-constant size.  In the body of an
! 	 uninstantiated template, we don't need to try to compute the
! 	 value, because the sizeof expression is not an integral
! 	 constant expression in that case.  And, if we do try to
! 	 compute the value, we'll likely end up with SAVE_EXPRs, which
! 	 the template substitution machinery does not expect to see.  */
!       || (processing_template_decl 
! 	  && COMPLETE_TYPE_P (type)
! 	  && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST))
!     {
!       value = build_min (op, size_type_node, type);
!       TREE_READONLY (value) = 1;
!       return value;
!     }
! 
!   return c_sizeof_or_alignof_type (complete_type (type),
! 				   op == SIZEOF_EXPR,
! 				   complain);
  }
  
  /* Process a sizeof or alignof expression where the operand is an
*************** build_binary_op (enum tree_code code, tr
*** 2921,2936 ****
  
    switch (code)
      {
-     case PLUS_EXPR:
-       /* Handle the pointer + int case.  */
-       if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
- 	return cp_pointer_int_sum (PLUS_EXPR, op0, op1);
-       else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
- 	return cp_pointer_int_sum (PLUS_EXPR, op1, op0);
-       else
- 	common = 1;
-       break;
- 
      case MINUS_EXPR:
        /* Subtraction of two similar pointers.
  	 We must subtract them as integers, then divide by object size.  */
--- 2928,2933 ----
*************** build_binary_op (enum tree_code code, tr
*** 2938,2948 ****
  	  && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
  							TREE_TYPE (type1)))
  	return pointer_diff (op0, op1, common_type (type0, type1));
!       /* Handle pointer minus int.  Just like pointer plus int.  */
!       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
! 	return cp_pointer_int_sum (MINUS_EXPR, op0, op1);
!       else
! 	common = 1;
        break;
  
      case MULT_EXPR:
--- 2935,2967 ----
  	  && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
  							TREE_TYPE (type1)))
  	return pointer_diff (op0, op1, common_type (type0, type1));
!       /* In all other cases except pointer - int, the usual arithmetic
! 	 rules aply.  */
!       else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
! 	{
! 	  common = 1;
! 	  break;
! 	}
!       /* The pointer - int case is just like pointer + int; fall
! 	 through.  */
!     case PLUS_EXPR:
!       if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
! 	  && (code0 == INTEGER_TYPE || code1 == INTEGER_TYPE))
! 	{
! 	  tree ptr_operand;
! 	  tree int_operand;
! 	  ptr_operand = ((code0 == POINTER_TYPE) ? op0 : op1);
! 	  int_operand = ((code0 == INTEGER_TYPE) ? op0 : op1);
! 	  if (processing_template_decl)
! 	    {
! 	      result_type = TREE_TYPE (ptr_operand);
! 	      break;
! 	    }
! 	  return cp_pointer_int_sum (code,
! 				     ptr_operand, 
! 				     int_operand);
! 	}
!       common = 1;
        break;
  
      case MULT_EXPR:
*************** build_binary_op (enum tree_code code, tr
*** 2959,2975 ****
  	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
  	      || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
  	{
  	  if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1))
  	    warning (0, "division by zero in %<%E / 0%>", op0);
  	  else if (TREE_CODE (op1) == REAL_CST && real_zerop (op1))
  	    warning (0, "division by zero in %<%E / 0.%>", op0);
  
! 	  if (code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
! 	    code0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
! 	  if (code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)
! 	    code1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
  
! 	  if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
  	    resultcode = RDIV_EXPR;
  	  else
  	    /* When dividing two signed integers, we have to promote to int.
--- 2978,2996 ----
  	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
  	      || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
  	{
+ 	  enum tree_code tcode0 = code0, tcode1 = code1;
+ 
  	  if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1))
  	    warning (0, "division by zero in %<%E / 0%>", op0);
  	  else if (TREE_CODE (op1) == REAL_CST && real_zerop (op1))
  	    warning (0, "division by zero in %<%E / 0.%>", op0);
  
! 	  if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
! 	    tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
! 	  if (tcode1 == COMPLEX_TYPE || tcode1 == VECTOR_TYPE)
! 	    tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
  
! 	  if (!(tcode0 == INTEGER_TYPE && tcode1 == INTEGER_TYPE))
  	    resultcode = RDIV_EXPR;
  	  else
  	    /* When dividing two signed integers, we have to promote to int.
*************** build_unary_op (enum tree_code code, tre
*** 3849,3858 ****
  	  if (!noconvert)
  	    arg = default_conversion (arg);
  	}
!       else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM,
  						   arg, true)))
  	errstring = "wrong type argument to bit-complement";
!       else if (!noconvert)
  	arg = perform_integral_promotions (arg);
        break;
  
--- 3870,3880 ----
  	  if (!noconvert)
  	    arg = default_conversion (arg);
  	}
!       else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM
! 						   | WANT_VECTOR,
  						   arg, true)))
  	errstring = "wrong type argument to bit-complement";
!       else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
  	arg = perform_integral_promotions (arg);
        break;
  
*************** build_modify_expr (tree lhs, enum tree_c
*** 5363,5369 ****
    bool plain_assign = (modifycode == NOP_EXPR);
  
    /* Avoid duplicate error messages from operands that had errors.  */
!   if (lhs == error_mark_node || rhs == error_mark_node)
      return error_mark_node;
  
    /* Handle control structure constructs used as "lvalues".  */
--- 5385,5391 ----
    bool plain_assign = (modifycode == NOP_EXPR);
  
    /* Avoid duplicate error messages from operands that had errors.  */
!   if (error_operand_p (lhs) || error_operand_p (rhs))
      return error_mark_node;
  
    /* Handle control structure constructs used as "lvalues".  */
*************** maybe_warn_about_returning_address_of_lo
*** 6221,6226 ****
--- 6243,6252 ----
  	}
      }
  
+   while (TREE_CODE (whats_returned) == COMPONENT_REF
+ 	 || TREE_CODE (whats_returned) == ARRAY_REF)
+     whats_returned = TREE_OPERAND (whats_returned, 0);
+ 
    if (DECL_P (whats_returned)
        && DECL_NAME (whats_returned)
        && DECL_FUNCTION_SCOPE_P (whats_returned)
diff -Nrcpad gcc-4.1.1/gcc/cp/typeck2.c gcc-4.1.2/gcc/cp/typeck2.c
*** gcc-4.1.1/gcc/cp/typeck2.c	Mon May  1 02:18:14 2006
--- gcc-4.1.2/gcc/cp/typeck2.c	Wed Oct 18 10:57:37 2006
*************** cxx_incomplete_type_diagnostic (tree val
*** 401,407 ****
        break;
  
      case TEMPLATE_TYPE_PARM:
!       p_msg ("invalid use of template type parameter");
        break;
  
      case UNKNOWN_TYPE:
--- 401,412 ----
        break;
  
      case TEMPLATE_TYPE_PARM:
!       p_msg ("invalid use of template type parameter %qT", type);
!       break;
! 
!     case BOUND_TEMPLATE_TEMPLATE_PARM:
!       p_msg ("invalid use of template template parameter %qT",
!             TYPE_NAME (type));
        break;
  
      case UNKNOWN_TYPE:
*************** digest_init (tree type, tree init)
*** 719,724 ****
--- 724,738 ----
  
  	  return error_mark_node;
  	}
+ 
+       if (TREE_CODE (type) == ARRAY_TYPE
+ 	  && TREE_CODE (init) != CONSTRUCTOR)
+ 	{
+ 	  error ("array must be initialized with a brace-enclosed"
+ 		 " initializer");
+ 	  return error_mark_node;
+ 	}
+ 
        return convert_for_initialization (NULL_TREE, type, init,
  					 LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING,
  					 "initialization", NULL_TREE, 0);
*************** process_init_constructor_array (tree typ
*** 788,794 ****
  	{
  	  gcc_assert (TREE_CODE (ce->index) == INTEGER_CST);
  	  if (compare_tree_int (ce->index, i) != 0)
! 	    sorry ("non-trivial designated initializers not supported");
  	}
        else
  	ce->index = size_int (i);
--- 802,811 ----
  	{
  	  gcc_assert (TREE_CODE (ce->index) == INTEGER_CST);
  	  if (compare_tree_int (ce->index, i) != 0)
! 	    {
! 	      ce->value = error_mark_node;
! 	      sorry ("non-trivial designated initializers not supported");
! 	    }
  	}
        else
  	ce->index = size_int (i);
*************** process_init_constructor_record (tree ty
*** 908,914 ****
  			  || TREE_CODE (ce->index) == IDENTIFIER_NODE);
  	      if (ce->index != field
  	          && ce->index != DECL_NAME (field))
! 		sorry ("non-trivial designated initializers not supported");
  	    }
  
  	  gcc_assert (ce->value);
--- 925,934 ----
  			  || TREE_CODE (ce->index) == IDENTIFIER_NODE);
  	      if (ce->index != field
  	          && ce->index != DECL_NAME (field))
! 		{
! 		  ce->value = error_mark_node;
! 		  sorry ("non-trivial designated initializers not supported");
! 		}
  	    }
  
  	  gcc_assert (ce->value);
*************** build_functional_cast (tree exp, tree pa
*** 1320,1331 ****
  
    if (! IS_AGGR_TYPE (type))
      {
-       /* This must build a C cast.  */
        if (parms == NULL_TREE)
! 	parms = integer_zero_node;
!       else
! 	parms = build_x_compound_expr_from_list (parms, "functional cast");
  
        return build_c_cast (type, parms);
      }
  
--- 1340,1350 ----
  
    if (! IS_AGGR_TYPE (type))
      {
        if (parms == NULL_TREE)
! 	return cp_convert (type, integer_zero_node);
  
+       /* This must build a C cast.  */
+       parms = build_x_compound_expr_from_list (parms, "functional cast");
        return build_c_cast (type, parms);
      }
  
diff -Nrcpad gcc-4.1.1/libstdc++-v3/ChangeLog gcc-4.1.2/libstdc++-v3/ChangeLog
*** gcc-4.1.1/libstdc++-v3/ChangeLog	Wed May 24 23:42:21 2006
--- gcc-4.1.2/libstdc++-v3/ChangeLog	Wed Feb 14 05:11:54 2007
***************
*** 1,3 ****
--- 1,198 ----
+ 2007-02-13  Release Manager
+ 
+ 	* GCC 4.1.2 released.
+ 
+ 2007-01-28  Benjamin Kosnik  <bkoz@redhat.com>
+ 
+ 	Revert.
+       	2006-12-11  Benjamin Kosnik  <bkoz@redhat.com>
+ 	PR libstdc++/28125
+ 	* acinclude.m4 (GLIBCXX_CHECK_ICONV_SUPPORT): Remove link test, ie
+ 	AC_CHECK_LIB for libiconv. Instead, use bits of AM_ICONV.
+         * configure: Regenerate.
+         * scripts/testsuite_flags.in (cxxflags): Add LIBICONV bits.
+ 
+ 2007-01-28  Paolo Carlini  <pcarlini@suse.de>
+ 
+ 	PR libstdc++/30586
+ 	* config/cpu/ia64/atomic_word.h: Just include <bits/cxxabi_tweaks.h>.
+ 
+ 	* configure.host (atomic_word_dir): Cover alpha, ia64 and powerpc.
+ 
+ 2007-01-13  John David Anglin  <dave.anglin@nrc-cnrc.gc>
+ 
+ 	* config/cpu/hppa/atomicity.h (__exchange_and_add): Don't use ordered
+ 	store.
+ 	(__atomic_add): Likewise.
+ 
+ 2006-12-12  Benjamin Kosnik  <bkoz@redhat.com>
+ 
+         PR libstdc++/28265
+         * crossconfig.m4: Remove GLIBCXX_CHECK_ICONV_SUPPORT call for
+         mingw crosses.
+         * configure: Regenerate.
+ 
+ 2006-12-12  Benjamin Kosnik  <bkoz@redhat.com>
+ 
+ 	PR libstdc++/26497
+ 	* crossconfig.m4: Add GLIBCXX_CHECK_LINKER_FEATURES for Solaris.
+ 	* acinclude.m4 (GLIBCXX_CHECK_LINKER_FEATURES): Set
+ 	glibcxx_gnu_ld_version only when with GNU ld confirmed.	
+ 	* configure: Regenerate.
+ 
+ 2006-12-11  Benjamin Kosnik  <bkoz@redhat.com>
+ 
+ 	PR libstdc++/28125
+ 	* acinclude.m4 (GLIBCXX_CHECK_ICONV_SUPPORT): Remove link test, ie
+ 	AC_CHECK_LIB for libiconv. Instead, use bits of AM_ICONV.
+         * configure: Regenerate.
+         * scripts/testsuite_flags.in (cxxflags): Add LIBICONV bits.
+ 
+ 2006-12-10  Mark Mitchell  <mark@codesourcery.com>
+ 
+ 	PR c++/29732
+ 	* testsuite/ext/pb_assoc/example/mapping_level_neg.cc: Tweak error
+ 	markers. 
+ 
+ 2006-12-08  Jakub Jelinek  <jakub@redhat.com>
+ 
+ 	* testsuite/testsuite_hooks.cc (set_memory_limits): Don't set
+ 	RLIMIT_AS below 16MB on x86_64-linux.
+ 
+ 2006-11-18  Joseph Myers  <joseph@codesourcery.com>
+ 
+ 	* config/cpu/powerpc/atomic_word.h (_GLIBCXX_WRITE_MEM_BARRIER):
+ 	Use plain sync if __NO_LWSYNC__.
+ 
+ 2006-11-14  Joseph Myers  <joseph@codesourcery.com>
+ 
+ 	* testsuite/26_numerics/complex/13450.cc: Do not test long double
+ 	in IBM long double case.
+ 
+ 2006-11-13  Paolo Carlini  <pcarlini@suse.de>
+ 
+ 	* src/debug.cc (_Safe_sequence_base::_M_revalidate_singular): Fix
+ 	pasto, advance __iter only once per iteration.
+ 
+ 2006-11-10  Jakub Jelinek  <jakub@redhat.com>
+ 
+ 	* config/locale/gnu/c_locale.cc (__convert_to_v): Prefer
+ 	strtold_l over __strtold_l if available.
+ 
+ 2006-10-30  Paolo Carlini  <pcarlini@suse.de>
+ 
+ 	* testsuite/tr1/6_containers/array/capacity/max_size.cc: Actually
+ 	do test max_size().
+ 
+ 2006-10-28  Paolo Carlini  <pcarlini@suse.de>
+ 	
+ 	* include/tr1/array (array<>::_M_at): New.
+ 	(array<>::at): Fix off-by-one bug, use the above.
+ 	* testsuite/tr1/6_containers/array/element_access/
+ 	at_out_of_range.cc: Adjust.
+ 
+ 	* include/tr1/array (class array<>): Remove non-conforming default
+ 	for the second parameter.
+ 	* include/ext/array_allocator.h: Adjust.
+ 
+ 	* include/tr1/array (array<>::front, array<>::back): Do not return
+ 	a reference to memory not belonging to the array when _Nm == 0.
+ 
+ 2006-10-16  Jakub Jelinek  <jakub@redhat.com>
+ 
+ 	* include/bits/basic_string.tcc (_Rep::_S_create): Call
+ 	_M_set_sharable() for backwards compatibility.
+ 
+ 2006-10-09  Benjamin Kosnik  <bkoz@redhat.com>
+ 
+         PR libstdc++/29095
+         * libsupc++/cxxabi.h (__cxa_cdtor_type): Explicit "C" linkage.
+         * config/cpu/arm/cxxabi_tweaks.h: Same.
+         * config/cpu/generic/cxxabi_tweaks.h: Same.
+ 
+ 2006-10-06  Paolo Carlini  <pcarlini@suse.de>
+ 
+ 	PR libstdc++/29368
+ 	* include/bits/basic_string.h: Adjust rfind documentation.
+ 	* include/ext/vstring.h: Likewise.
+ 
+ 2006-10-06  Paolo Carlini  <pcarlini@suse.de>
+ 
+ 	PR libstdc++/29354
+ 	* include/bits/sstream.tcc (basic_stringbuf<>::seekpos(pos_type,
+ 	ios_base::openmode)): Allow for seek to pos_type(off_type(0))
+ 	when the stream is empty.
+ 	* testsuite/27_io/basic_stringbuf/seekpos/char/29354.cc: New.
+ 	* testsuite/27_io/basic_stringbuf/seekpos/wchar_t/29354.cc: New.
+ 
+ 2006-09-29  Joseph S. Myers  <joseph@codesourcery.com>
+ 
+ 	* acinclude.m4 (enable_symvers): Default to no if unable to link.
+ 	* configure: Regenerate.
+ 
+ 2006-09-25  Howard Hinnant  <hhinnant@apple.com>
+ 
+ 	PR libstdc++/29224
+ 	* include/tr1/functional_iterate.h: Avoid -Wshadow warnings.
+ 
+ 2006-09-25  Paolo Carlini  <pcarlini@suse.de>
+ 
+ 	PR libstdc++/29179
+ 	* include/ext/mt_allocator.h (__pool_base): Adjust/extend
+ 	documentation in comments.
+ 
+ 2006-08-18  Paolo Carlini  <pcarlini@suse.de>
+ 
+ 	PR libstdc++/28765
+ 	* include/ext/rc_string_base.h (_M_clear): New.
+ 	* include/ext/sso_string_base.h (_M_clear): Likewise.
+ 	* include/ext/vstring.h (clear): Use it.
+ 
+ 2006-07-03  Paolo Carlini  <pcarlini@suse.de>
+ 
+ 	* include/ext/rc_string_base.h (__rc_string_base::_S_max_size):
+ 	Adjust, take into account rounding in _M_create.
+ 	(__rc_string_base::_M_create): Add early _S_max_size check.
+ 
+ 2006-07-03  Ian Lance Taylor  <ian@airs.com>
+ 	    Paolo Carlini  <pcarlini@suse.de>
+ 
+ 	* include/ext/rc_string_base.h (__rc_string_base::_S_max_size):
+ 	Increase by a factor of two.
+ 	* include/ext/sso_string_base.h (__sso_string_base::_S_max_size):
+ 	Likewise.
+ 
+ 2006-07-03  Paolo Carlini  <pcarlini@suse.de>
+ 
+ 	* include/ext/sso_string_base.h (__sso_string_base::_M_create): Never
+ 	allocate a string bigger than _S_max_size.
+ 
+ 2006-05-26  Paolo Carlini  <pcarlini@suse.de>
+ 
+ 	* include/tr1/hashtable: Minor cosmetic changes.
+ 
+ 2006-05-26  Paolo Carlini  <pcarlini@suse.de>
+ 
+ 	* include/tr1/hashtable (hashtable<>::m_find): Remove; update callers.
+ 
+ 	* include/tr1/hashtable (map_base<>::operator[]): Move out of line.
+ 
+ 	* include/tr1/hashtable (hashtable<>::m_insert(const value_type&,
+ 	std::tr1::false_type)): Avoid memory leak risk for new_node.
+ 
+ 2006-05-26  Paolo Carlini  <pcarlini@suse.de>
+ 
+ 	* include/tr1/hashtable (hashtable<>::m_find, m_insert_bucket): Add.
+ 	(hashtable<>::find, m_insert(const value_type&, std::tr1::true_type),
+ 	map_base<>::operator[]): Use the above.
+ 	* testsuite/performance/23_containers/insert/unordered_map_array.cc:
+ 	New.	
+ 
+ 	* include/tr1/hashtable (hashtable<>::find_node,
+ 	insert(const value_type&, ...), erase_node): Rename to m_*, adjust
+ 	callers.
+ 	* include/tr1/hashtable: Minor cosmetic changes.
+ 
  2006-05-24  Release Manager
  
  	* GCC 4.1.1 released.
diff -Nrcpad gcc-4.1.1/libstdc++-v3/acinclude.m4 gcc-4.1.2/libstdc++-v3/acinclude.m4
*** gcc-4.1.1/libstdc++-v3/acinclude.m4	Wed May  3 17:00:18 2006
--- gcc-4.1.2/libstdc++-v3/acinclude.m4	Mon Jan 29 10:51:01 2007
*************** AC_DEFUN([GLIBCXX_CHECK_LINKER_FEATURES]
*** 222,233 ****
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
!   changequote(,)
!   ldver=`$LD --version 2>/dev/null | head -1 | \
!          sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
!   changequote([,])
!   glibcxx_gnu_ld_version=`echo $ldver | \
!          $AWK -F. '{ if (NF<3) [$]3=0; print ([$]1*100+[$]2)*100+[$]3 }'`
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
--- 222,235 ----
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
!   if test x"$with_gnu_ld" = x"yes"; then
!     changequote(,)
!     ldver=`$LD --version 2>/dev/null | head -1 | \
!            sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
!     changequote([,])
!     glibcxx_gnu_ld_version=`echo $ldver | \
!            $AWK -F. '{ if (NF<3) [$]3=0; print ([$]1*100+[$]2)*100+[$]3 }'`
!   fi
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
*************** AC_REQUIRE([GLIBCXX_CHECK_LINKER_FEATURE
*** 1730,1736 ****
  # Turn a 'yes' into a suitable default.
  if test x$enable_symvers = xyes ; then
    if test $enable_shared = no ||
!      test "x$LD" = x ; then
      enable_symvers=no
    elif test $with_gnu_ld = yes ; then
      enable_symvers=gnu
--- 1732,1738 ----
  # Turn a 'yes' into a suitable default.
  if test x$enable_symvers = xyes ; then
    if test $enable_shared = no ||
!      test "x$LD" = x || test x$gcc_no_link = xyes; then
      enable_symvers=no
    elif test $with_gnu_ld = yes ; then
      enable_symvers=gnu
diff -Nrcpad gcc-4.1.1/libstdc++-v3/config/cpu/arm/cxxabi_tweaks.h gcc-4.1.2/libstdc++-v3/config/cpu/arm/cxxabi_tweaks.h
*** gcc-4.1.1/libstdc++-v3/config/cpu/arm/cxxabi_tweaks.h	Wed Aug 17 02:28:44 2005
--- gcc-4.1.2/libstdc++-v3/config/cpu/arm/cxxabi_tweaks.h	Wed Oct 11 08:30:42 2006
***************
*** 1,6 ****
  // Control various target specific ABI tweaks.  ARM version.
  
! // Copyright (C) 2004 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
--- 1,6 ----
  // Control various target specific ABI tweaks.  ARM version.
  
! // Copyright (C) 2004, 2006 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
***************
*** 33,38 ****
--- 33,40 ----
  #ifdef __cplusplus
  namespace __cxxabiv1
  {
+   extern "C" 
+   {
  #endif
  
  #ifdef __ARM_EABI__
*************** namespace __cxxabiv1
*** 67,73 ****
  #endif //!__ARM_EABI__
  
  #ifdef __cplusplus
  } // namespace __cxxabiv1
  #endif
  
! #endif // __cxxabiv1
--- 69,76 ----
  #endif //!__ARM_EABI__
  
  #ifdef __cplusplus
+   }
  } // namespace __cxxabiv1
  #endif
  
! #endif 
diff -Nrcpad gcc-4.1.1/libstdc++-v3/config/cpu/generic/cxxabi_tweaks.h gcc-4.1.2/libstdc++-v3/config/cpu/generic/cxxabi_tweaks.h
*** gcc-4.1.1/libstdc++-v3/config/cpu/generic/cxxabi_tweaks.h	Wed Aug 17 02:28:44 2005
--- gcc-4.1.2/libstdc++-v3/config/cpu/generic/cxxabi_tweaks.h	Wed Oct 11 08:30:42 2006
***************
*** 1,6 ****
  // Control various target specific ABI tweaks.  Generic version.
  
! // Copyright (C) 2004 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
--- 1,6 ----
  // Control various target specific ABI tweaks.  Generic version.
  
! // Copyright (C) 2004, 2006 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
***************
*** 33,38 ****
--- 33,40 ----
  #ifdef __cplusplus
  namespace __cxxabiv1
  {
+   extern "C" 
+   {
  #endif
  
    // The generic ABI uses the first byte of a 64-bit guard variable.
*************** namespace __cxxabiv1
*** 47,53 ****
    typedef void __cxa_cdtor_return_type;
  
  #ifdef __cplusplus
  } // namespace __cxxabiv1
  #endif
  
! #endif // __cxxabiv1
--- 49,56 ----
    typedef void __cxa_cdtor_return_type;
  
  #ifdef __cplusplus
+   }
  } // namespace __cxxabiv1
  #endif
  
! #endif 
diff -Nrcpad gcc-4.1.1/libstdc++-v3/config/cpu/hppa/atomicity.h gcc-4.1.2/libstdc++-v3/config/cpu/hppa/atomicity.h
*** gcc-4.1.1/libstdc++-v3/config/cpu/hppa/atomicity.h	Wed Aug 17 02:28:44 2005
--- gcc-4.1.2/libstdc++-v3/config/cpu/hppa/atomicity.h	Sat Jan 13 15:13:20 2007
*************** namespace __gnu_cxx
*** 66,73 ****
      
      result = *__mem;
      *__mem = result + __val;
!     /* Reset lock with PA 2.0 "ordered" store.  */
!     __asm__ __volatile__ ("stw,ma %1,0(%0)"
  			  : : "r" (&lock), "r" (tmp) : "memory");
      return result;
    }
--- 66,72 ----
      
      result = *__mem;
      *__mem = result + __val;
!     __asm__ __volatile__ ("stw %1,0(%0)"
  			  : : "r" (&lock), "r" (tmp) : "memory");
      return result;
    }
*************** namespace __gnu_cxx
*** 90,97 ****
  			  : "memory");
      
      *__mem += __val;
!     /* Reset lock with PA 2.0 "ordered" store.  */
!     __asm__ __volatile__ ("stw,ma %1,0(%0)"
  			  : : "r" (&lock), "r" (tmp) : "memory");
    }
  } // namespace __gnu_cxx
--- 89,95 ----
  			  : "memory");
      
      *__mem += __val;
!     __asm__ __volatile__ ("stw %1,0(%0)"
  			  : : "r" (&lock), "r" (tmp) : "memory");
    }
  } // namespace __gnu_cxx
diff -Nrcpad gcc-4.1.1/libstdc++-v3/config/cpu/ia64/atomic_word.h gcc-4.1.2/libstdc++-v3/config/cpu/ia64/atomic_word.h
*** gcc-4.1.1/libstdc++-v3/config/cpu/ia64/atomic_word.h	Wed Aug 17 02:28:44 2005
--- gcc-4.1.2/libstdc++-v3/config/cpu/ia64/atomic_word.h	Sun Jan 28 20:12:40 2007
***************
*** 1,6 ****
  // Low-level type for atomic operations -*- C++ -*-
  
! // Copyright (C) 2004 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
--- 1,6 ----
  // Low-level type for atomic operations -*- C++ -*-
  
! // Copyright (C) 2004, 2005, 2006, 2007 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
***************
*** 30,36 ****
  #ifndef _GLIBCXX_ATOMIC_WORD_H
  #define _GLIBCXX_ATOMIC_WORD_H	1
  
! #include <cxxabi.h>
  
  typedef int _Atomic_word;
  
--- 30,36 ----
  #ifndef _GLIBCXX_ATOMIC_WORD_H
  #define _GLIBCXX_ATOMIC_WORD_H	1
  
! #include <bits/cxxabi_tweaks.h>
  
  typedef int _Atomic_word;
  
diff -Nrcpad gcc-4.1.1/libstdc++-v3/config/cpu/powerpc/atomic_word.h gcc-4.1.2/libstdc++-v3/config/cpu/powerpc/atomic_word.h
*** gcc-4.1.1/libstdc++-v3/config/cpu/powerpc/atomic_word.h	Wed Aug 17 02:28:44 2005
--- gcc-4.1.2/libstdc++-v3/config/cpu/powerpc/atomic_word.h	Sat Nov 18 00:25:49 2006
***************
*** 33,38 ****
--- 33,42 ----
  typedef int _Atomic_word;
  
  #define _GLIBCXX_READ_MEM_BARRIER __asm __volatile ("isync":::"memory")
+ #ifdef __NO_LWSYNC__
+ #define _GLIBCXX_WRITE_MEM_BARRIER __asm __volatile ("sync":::"memory")
+ #else
  #define _GLIBCXX_WRITE_MEM_BARRIER __asm __volatile ("lwsync":::"memory")
+ #endif
  
  #endif 
diff -Nrcpad gcc-4.1.1/libstdc++-v3/config/locale/gnu/c_locale.cc gcc-4.1.2/libstdc++-v3/config/locale/gnu/c_locale.cc
*** gcc-4.1.1/libstdc++-v3/config/locale/gnu/c_locale.cc	Thu Dec 15 10:22:19 2005
--- gcc-4.1.2/libstdc++-v3/config/locale/gnu/c_locale.cc	Fri Nov 10 15:52:39 2006
*************** namespace std 
*** 77,83 ****
--- 77,89 ----
      {
        char* __sanity;
        errno = 0;
+ #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
+       // Prefer strtold_l, as __strtold_l isn't prototyped in more recent
+       // glibc versions.
+       long double __ld = strtold_l(__s, &__sanity, __cloc);
+ #else
        long double __ld = __strtold_l(__s, &__sanity, __cloc);
+ #endif
        if (__sanity != __s && errno != ERANGE)
  	__v = __ld;
        else
diff -Nrcpad gcc-4.1.1/libstdc++-v3/configure gcc-4.1.2/libstdc++-v3/configure
*** gcc-4.1.1/libstdc++-v3/configure	Wed May  3 17:00:18 2006
--- gcc-4.1.2/libstdc++-v3/configure	Mon Jan 29 10:51:01 2007
*************** ac_compiler_gnu=$ac_cv_c_compiler_gnu
*** 8278,8289 ****
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
  
!   ldver=`$LD --version 2>/dev/null | head -1 | \
!          sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!   glibcxx_gnu_ld_version=`echo $ldver | \
!          $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
--- 8278,8291 ----
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
+   if test x"$with_gnu_ld" = x"yes"; then
  
!     ldver=`$LD --version 2>/dev/null | head -1 | \
!            sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!     glibcxx_gnu_ld_version=`echo $ldver | \
!            $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
!   fi
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
*************** ac_compiler_gnu=$ac_cv_c_compiler_gnu
*** 53117,53128 ****
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
  
!   ldver=`$LD --version 2>/dev/null | head -1 | \
!          sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!   glibcxx_gnu_ld_version=`echo $ldver | \
!          $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
--- 53119,53132 ----
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
+   if test x"$with_gnu_ld" = x"yes"; then
  
!     ldver=`$LD --version 2>/dev/null | head -1 | \
!            sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!     glibcxx_gnu_ld_version=`echo $ldver | \
!            $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
!   fi
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
*************** done
*** 74449,74460 ****
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
  
!   ldver=`$LD --version 2>/dev/null | head -1 | \
!          sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!   glibcxx_gnu_ld_version=`echo $ldver | \
!          $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
--- 74453,74466 ----
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
+   if test x"$with_gnu_ld" = x"yes"; then
  
!     ldver=`$LD --version 2>/dev/null | head -1 | \
!            sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!     glibcxx_gnu_ld_version=`echo $ldver | \
!            $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
!   fi
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
*************** done
*** 75944,75955 ****
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
  
!   ldver=`$LD --version 2>/dev/null | head -1 | \
!          sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!   glibcxx_gnu_ld_version=`echo $ldver | \
!          $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
--- 75950,75963 ----
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
+   if test x"$with_gnu_ld" = x"yes"; then
  
!     ldver=`$LD --version 2>/dev/null | head -1 | \
!            sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!     glibcxx_gnu_ld_version=`echo $ldver | \
!            $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
!   fi
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
*************** done
*** 77315,77326 ****
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
  
!   ldver=`$LD --version 2>/dev/null | head -1 | \
!          sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!   glibcxx_gnu_ld_version=`echo $ldver | \
!          $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
--- 77323,77336 ----
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
+   if test x"$with_gnu_ld" = x"yes"; then
  
!     ldver=`$LD --version 2>/dev/null | head -1 | \
!            sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!     glibcxx_gnu_ld_version=`echo $ldver | \
!            $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
!   fi
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
*************** done
*** 79473,79484 ****
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
  
!   ldver=`$LD --version 2>/dev/null | head -1 | \
!          sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!   glibcxx_gnu_ld_version=`echo $ldver | \
!          $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
--- 79483,79496 ----
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
+   if test x"$with_gnu_ld" = x"yes"; then
  
!     ldver=`$LD --version 2>/dev/null | head -1 | \
!            sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!     glibcxx_gnu_ld_version=`echo $ldver | \
!            $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
!   fi
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
*************** done
*** 80097,80609 ****
    fi
  
  
- 
- 
-   enable_iconv=no
-   # Only continue checking if the ISO C99 headers exist and support is on.
-   if test x"$enable_wchar_t" = xyes; then
- 
-     # Use iconv for wchar_t to char conversions. As such, check for
-     # X/Open Portability Guide, version 2 features (XPG2).
-     if test "${ac_cv_header_iconv_h+set}" = set; then
-   echo "$as_me:$LINENO: checking for iconv.h" >&5
- echo $ECHO_N "checking for iconv.h... $ECHO_C" >&6
- if test "${ac_cv_header_iconv_h+set}" = set; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- fi
- echo "$as_me:$LINENO: result: $ac_cv_header_iconv_h" >&5
- echo "${ECHO_T}$ac_cv_header_iconv_h" >&6
- else
-   # Is the header compilable?
- echo "$as_me:$LINENO: checking iconv.h usability" >&5
- echo $ECHO_N "checking iconv.h usability... $ECHO_C" >&6
- cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- $ac_includes_default
- #include <iconv.h>
- _ACEOF
- rm -f conftest.$ac_objext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-   (eval $ac_compile) 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } &&
- 	 { ac_try='test -z "$ac_c_werror_flag"
- 			 || test ! -s conftest.err'
-   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-   (eval $ac_try) 2>&5
-   ac_status=$?
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); }; } &&
- 	 { ac_try='test -s conftest.$ac_objext'
-   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-   (eval $ac_try) 2>&5
-   ac_status=$?
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); }; }; then
-   ac_header_compiler=yes
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
- 
- ac_header_compiler=no
- fi
- rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
- echo "${ECHO_T}$ac_header_compiler" >&6
- 
- # Is the header present?
- echo "$as_me:$LINENO: checking iconv.h presence" >&5
- echo $ECHO_N "checking iconv.h presence... $ECHO_C" >&6
- cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- #include <iconv.h>
- _ACEOF
- if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-   (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } >/dev/null; then
-   if test -s conftest.err; then
-     ac_cpp_err=$ac_c_preproc_warn_flag
-     ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-   else
-     ac_cpp_err=
-   fi
- else
-   ac_cpp_err=yes
- fi
- if test -z "$ac_cpp_err"; then
-   ac_header_preproc=yes
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
- 
-   ac_header_preproc=no
- fi
- rm -f conftest.err conftest.$ac_ext
- echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
- echo "${ECHO_T}$ac_header_preproc" >&6
- 
- # So?  What about this header?
- case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-   yes:no: )
-     { echo "$as_me:$LINENO: WARNING: iconv.h: accepted by the compiler, rejected by the preprocessor!" >&5
- echo "$as_me: WARNING: iconv.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
-     { echo "$as_me:$LINENO: WARNING: iconv.h: proceeding with the compiler's result" >&5
- echo "$as_me: WARNING: iconv.h: proceeding with the compiler's result" >&2;}
-     ac_header_preproc=yes
-     ;;
-   no:yes:* )
-     { echo "$as_me:$LINENO: WARNING: iconv.h: present but cannot be compiled" >&5
- echo "$as_me: WARNING: iconv.h: present but cannot be compiled" >&2;}
-     { echo "$as_me:$LINENO: WARNING: iconv.h:     check for missing prerequisite headers?" >&5
- echo "$as_me: WARNING: iconv.h:     check for missing prerequisite headers?" >&2;}
-     { echo "$as_me:$LINENO: WARNING: iconv.h: see the Autoconf documentation" >&5
- echo "$as_me: WARNING: iconv.h: see the Autoconf documentation" >&2;}
-     { echo "$as_me:$LINENO: WARNING: iconv.h:     section \"Present But Cannot Be Compiled\"" >&5
- echo "$as_me: WARNING: iconv.h:     section \"Present But Cannot Be Compiled\"" >&2;}
-     { echo "$as_me:$LINENO: WARNING: iconv.h: proceeding with the preprocessor's result" >&5
- echo "$as_me: WARNING: iconv.h: proceeding with the preprocessor's result" >&2;}
-     { echo "$as_me:$LINENO: WARNING: iconv.h: in the future, the compiler will take precedence" >&5
- echo "$as_me: WARNING: iconv.h: in the future, the compiler will take precedence" >&2;}
-     (
-       cat <<\_ASBOX
- ## ----------------------------------------- ##
- ## Report this to the package-unused lists.  ##
- ## ----------------------------------------- ##
- _ASBOX
-     ) |
-       sed "s/^/$as_me: WARNING:     /" >&2
-     ;;
- esac
- echo "$as_me:$LINENO: checking for iconv.h" >&5
- echo $ECHO_N "checking for iconv.h... $ECHO_C" >&6
- if test "${ac_cv_header_iconv_h+set}" = set; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-   ac_cv_header_iconv_h=$ac_header_preproc
- fi
- echo "$as_me:$LINENO: result: $ac_cv_header_iconv_h" >&5
- echo "${ECHO_T}$ac_cv_header_iconv_h" >&6
- 
- fi
- if test $ac_cv_header_iconv_h = yes; then
-   ac_has_iconv_h=yes
- else
-   ac_has_iconv_h=no
- fi
- 
- 
-     if test "${ac_cv_header_langinfo_h+set}" = set; then
-   echo "$as_me:$LINENO: checking for langinfo.h" >&5
- echo $ECHO_N "checking for langinfo.h... $ECHO_C" >&6
- if test "${ac_cv_header_langinfo_h+set}" = set; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- fi
- echo "$as_me:$LINENO: result: $ac_cv_header_langinfo_h" >&5
- echo "${ECHO_T}$ac_cv_header_langinfo_h" >&6
- else
-   # Is the header compilable?
- echo "$as_me:$LINENO: checking langinfo.h usability" >&5
- echo $ECHO_N "checking langinfo.h usability... $ECHO_C" >&6
- cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- $ac_includes_default
- #include <langinfo.h>
- _ACEOF
- rm -f conftest.$ac_objext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-   (eval $ac_compile) 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } &&
- 	 { ac_try='test -z "$ac_c_werror_flag"
- 			 || test ! -s conftest.err'
-   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-   (eval $ac_try) 2>&5
-   ac_status=$?
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); }; } &&
- 	 { ac_try='test -s conftest.$ac_objext'
-   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-   (eval $ac_try) 2>&5
-   ac_status=$?
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); }; }; then
-   ac_header_compiler=yes
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
- 
- ac_header_compiler=no
- fi
- rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
- echo "${ECHO_T}$ac_header_compiler" >&6
- 
- # Is the header present?
- echo "$as_me:$LINENO: checking langinfo.h presence" >&5
- echo $ECHO_N "checking langinfo.h presence... $ECHO_C" >&6
- cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- #include <langinfo.h>
- _ACEOF
- if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-   (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } >/dev/null; then
-   if test -s conftest.err; then
-     ac_cpp_err=$ac_c_preproc_warn_flag
-     ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-   else
-     ac_cpp_err=
-   fi
- else
-   ac_cpp_err=yes
- fi
- if test -z "$ac_cpp_err"; then
-   ac_header_preproc=yes
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
- 
-   ac_header_preproc=no
- fi
- rm -f conftest.err conftest.$ac_ext
- echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
- echo "${ECHO_T}$ac_header_preproc" >&6
- 
- # So?  What about this header?
- case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-   yes:no: )
-     { echo "$as_me:$LINENO: WARNING: langinfo.h: accepted by the compiler, rejected by the preprocessor!" >&5
- echo "$as_me: WARNING: langinfo.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
-     { echo "$as_me:$LINENO: WARNING: langinfo.h: proceeding with the compiler's result" >&5
- echo "$as_me: WARNING: langinfo.h: proceeding with the compiler's result" >&2;}
-     ac_header_preproc=yes
-     ;;
-   no:yes:* )
-     { echo "$as_me:$LINENO: WARNING: langinfo.h: present but cannot be compiled" >&5
- echo "$as_me: WARNING: langinfo.h: present but cannot be compiled" >&2;}
-     { echo "$as_me:$LINENO: WARNING: langinfo.h:     check for missing prerequisite headers?" >&5
- echo "$as_me: WARNING: langinfo.h:     check for missing prerequisite headers?" >&2;}
-     { echo "$as_me:$LINENO: WARNING: langinfo.h: see the Autoconf documentation" >&5
- echo "$as_me: WARNING: langinfo.h: see the Autoconf documentation" >&2;}
-     { echo "$as_me:$LINENO: WARNING: langinfo.h:     section \"Present But Cannot Be Compiled\"" >&5
- echo "$as_me: WARNING: langinfo.h:     section \"Present But Cannot Be Compiled\"" >&2;}
-     { echo "$as_me:$LINENO: WARNING: langinfo.h: proceeding with the preprocessor's result" >&5
- echo "$as_me: WARNING: langinfo.h: proceeding with the preprocessor's result" >&2;}
-     { echo "$as_me:$LINENO: WARNING: langinfo.h: in the future, the compiler will take precedence" >&5
- echo "$as_me: WARNING: langinfo.h: in the future, the compiler will take precedence" >&2;}
-     (
-       cat <<\_ASBOX
- ## ----------------------------------------- ##
- ## Report this to the package-unused lists.  ##
- ## ----------------------------------------- ##
- _ASBOX
-     ) |
-       sed "s/^/$as_me: WARNING:     /" >&2
-     ;;
- esac
- echo "$as_me:$LINENO: checking for langinfo.h" >&5
- echo $ECHO_N "checking for langinfo.h... $ECHO_C" >&6
- if test "${ac_cv_header_langinfo_h+set}" = set; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-   ac_cv_header_langinfo_h=$ac_header_preproc
- fi
- echo "$as_me:$LINENO: result: $ac_cv_header_langinfo_h" >&5
- echo "${ECHO_T}$ac_cv_header_langinfo_h" >&6
- 
- fi
- if test $ac_cv_header_langinfo_h = yes; then
-   ac_has_langinfo_h=yes
- else
-   ac_has_langinfo_h=no
- fi
- 
- 
- 
-     # Check for existence of libiconv.a providing XPG2 wchar_t support.
-     echo "$as_me:$LINENO: checking for iconv in -liconv" >&5
- echo $ECHO_N "checking for iconv in -liconv... $ECHO_C" >&6
- if test "${ac_cv_lib_iconv_iconv+set}" = set; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-   ac_check_lib_save_LIBS=$LIBS
- LIBS="-liconv  $LIBS"
- if test x$gcc_no_link = xyes; then
-   { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
- echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
-    { (exit 1); exit 1; }; }
- fi
- cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- 
- /* Override any gcc2 internal prototype to avoid an error.  */
- #ifdef __cplusplus
- extern "C"
- #endif
- /* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
- char iconv ();
- int
- main ()
- {
- iconv ();
-   ;
-   return 0;
- }
- _ACEOF
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-   (eval $ac_link) 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } &&
- 	 { ac_try='test -z "$ac_c_werror_flag"
- 			 || test ! -s conftest.err'
-   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-   (eval $ac_try) 2>&5
-   ac_status=$?
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); }; } &&
- 	 { ac_try='test -s conftest$ac_exeext'
-   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-   (eval $ac_try) 2>&5
-   ac_status=$?
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); }; }; then
-   ac_cv_lib_iconv_iconv=yes
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
- 
- ac_cv_lib_iconv_iconv=no
- fi
- rm -f conftest.err conftest.$ac_objext \
-       conftest$ac_exeext conftest.$ac_ext
- LIBS=$ac_check_lib_save_LIBS
- fi
- echo "$as_me:$LINENO: result: $ac_cv_lib_iconv_iconv" >&5
- echo "${ECHO_T}$ac_cv_lib_iconv_iconv" >&6
- if test $ac_cv_lib_iconv_iconv = yes; then
-   LIBICONV="-liconv"
- fi
- 
-     ac_save_LIBS="$LIBS"
-     LIBS="$LIBS $LIBICONV"
- 
- 
- 
- 
- 
- 
- for ac_func in iconv_open iconv_close iconv nl_langinfo
- do
- as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
- echo "$as_me:$LINENO: checking for $ac_func" >&5
- echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
- if eval "test \"\${$as_ac_var+set}\" = set"; then
-   echo $ECHO_N "(cached) $ECHO_C" >&6
- else
-   if test x$gcc_no_link = xyes; then
-   { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
- echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
-    { (exit 1); exit 1; }; }
- fi
- cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h.  */
- _ACEOF
- cat confdefs.h >>conftest.$ac_ext
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-    For example, HP-UX 11i <limits.h> declares gettimeofday.  */
- #define $ac_func innocuous_$ac_func
- 
- /* System header to define __stub macros and hopefully few prototypes,
-     which can conflict with char $ac_func (); below.
-     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-     <limits.h> exists even on freestanding compilers.  */
- 
- #ifdef __STDC__
- # include <limits.h>
- #else
- # include <assert.h>
- #endif
- 
- #undef $ac_func
- 
- /* Override any gcc2 internal prototype to avoid an error.  */
- #ifdef __cplusplus
- extern "C"
- {
- #endif
- /* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
- char $ac_func ();
- /* The GNU C library defines this for functions which it implements
-     to always fail with ENOSYS.  Some functions are actually named
-     something starting with __ and the normal name is an alias.  */
- #if defined (__stub_$ac_func) || defined (__stub___$ac_func)
- choke me
- #else
- char (*f) () = $ac_func;
- #endif
- #ifdef __cplusplus
- }
- #endif
- 
- int
- main ()
- {
- return f != $ac_func;
-   ;
-   return 0;
- }
- _ACEOF
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-   (eval $ac_link) 2>conftest.er1
-   ac_status=$?
-   grep -v '^ *+' conftest.er1 >conftest.err
-   rm -f conftest.er1
-   cat conftest.err >&5
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } &&
- 	 { ac_try='test -z "$ac_c_werror_flag"
- 			 || test ! -s conftest.err'
-   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-   (eval $ac_try) 2>&5
-   ac_status=$?
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); }; } &&
- 	 { ac_try='test -s conftest$ac_exeext'
-   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-   (eval $ac_try) 2>&5
-   ac_status=$?
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); }; }; then
-   eval "$as_ac_var=yes"
- else
-   echo "$as_me: failed program was:" >&5
- sed 's/^/| /' conftest.$ac_ext >&5
- 
- eval "$as_ac_var=no"
- fi
- rm -f conftest.err conftest.$ac_objext \
-       conftest$ac_exeext conftest.$ac_ext
- fi
- echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
- echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
- if test `eval echo '${'$as_ac_var'}'` = yes; then
-   cat >>confdefs.h <<_ACEOF
- #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
- _ACEOF
-  ac_XPG2funcs=yes
- else
-   ac_XPG2funcs=no
- fi
- done
- 
- 
-     LIBS="$ac_save_LIBS"
- 
-     if test x"$ac_has_iconv_h" = xyes &&
-        test x"$ac_has_langinfo_h" = xyes &&
-        test x"$ac_XPG2funcs" = xyes;
-     then
- 
- cat >>confdefs.h <<\_ACEOF
- #define _GLIBCXX_USE_ICONV 1
- _ACEOF
- 
-       enable_iconv=yes
-     fi
-   fi
-   echo "$as_me:$LINENO: checking for enabled iconv specializations" >&5
- echo $ECHO_N "checking for enabled iconv specializations... $ECHO_C" >&6
-   echo "$as_me:$LINENO: result: $enable_iconv" >&5
- echo "${ECHO_T}$enable_iconv" >&6
- 
      ;;
    *-netbsd*)
  
--- 80109,80114 ----
*************** done
*** 80797,80808 ****
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
  
!   ldver=`$LD --version 2>/dev/null | head -1 | \
!          sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!   glibcxx_gnu_ld_version=`echo $ldver | \
!          $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
--- 80302,80315 ----
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
+   if test x"$with_gnu_ld" = x"yes"; then
  
!     ldver=`$LD --version 2>/dev/null | head -1 | \
!            sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!     glibcxx_gnu_ld_version=`echo $ldver | \
!            $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
!   fi
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
*************** done
*** 82170,82181 ****
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
  
!   ldver=`$LD --version 2>/dev/null | head -1 | \
!          sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!   glibcxx_gnu_ld_version=`echo $ldver | \
!          $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
--- 81677,81690 ----
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
+   if test x"$with_gnu_ld" = x"yes"; then
  
!     ldver=`$LD --version 2>/dev/null | head -1 | \
!            sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!     glibcxx_gnu_ld_version=`echo $ldver | \
!            $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
!   fi
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
*************** echo "${ECHO_T}$glibcxx_cv_WRITEV" >&6
*** 83935,83946 ****
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
  
!   ldver=`$LD --version 2>/dev/null | head -1 | \
!          sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!   glibcxx_gnu_ld_version=`echo $ldver | \
!          $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
--- 83444,83457 ----
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
+   if test x"$with_gnu_ld" = x"yes"; then
  
!     ldver=`$LD --version 2>/dev/null | head -1 | \
!            sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!     glibcxx_gnu_ld_version=`echo $ldver | \
!            $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
!   fi
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
*************** _ACEOF
*** 85124,85129 ****
--- 84635,84770 ----
      #    os_include_dir="os/solaris/solaris2.6"
      #    ;;
        *-solaris2.7 | *-solaris2.8 | *-solaris2.9 | *-solaris2.10)
+ 
+   # If we're not using GNU ld, then there's no point in even trying these
+   # tests.  Check for that first.  We should have already tested for gld
+   # by now (in libtool), but require it now just to be safe...
+   test -z "$SECTION_LDFLAGS" && SECTION_LDFLAGS=''
+   test -z "$OPT_LDFLAGS" && OPT_LDFLAGS=''
+ 
+ 
+ 
+   # The name set by libtool depends on the version of libtool.  Shame on us
+   # for depending on an impl detail, but c'est la vie.  Older versions used
+   # ac_cv_prog_gnu_ld, but now it's lt_cv_prog_gnu_ld, and is copied back on
+   # top of with_gnu_ld (which is also set by --with-gnu-ld, so that actually
+   # makes sense).  We'll test with_gnu_ld everywhere else, so if that isn't
+   # set (hence we're using an older libtool), then set it.
+   if test x${with_gnu_ld+set} != xset; then
+     if test x${ac_cv_prog_gnu_ld+set} != xset; then
+       # We got through "ac_require(ac_prog_ld)" and still not set?  Huh?
+       with_gnu_ld=no
+     else
+       with_gnu_ld=$ac_cv_prog_gnu_ld
+     fi
+   fi
+ 
+   # Start by getting the version number.  I think the libtool test already
+   # does some of this, but throws away the result.
+   if test x"$with_gnu_ld" = x"yes"; then
+ 
+     ldver=`$LD --version 2>/dev/null | head -1 | \
+            sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
+ 
+     glibcxx_gnu_ld_version=`echo $ldver | \
+            $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
+   fi
+ 
+   # Set --gc-sections.
+   if test "$with_gnu_ld" = "notbroken"; then
+     # GNU ld it is!  Joy and bunny rabbits!
+ 
+     # All these tests are for C++; save the language and the compiler flags.
+     # Need to do this so that g++ won't try to link in libstdc++
+     ac_test_CFLAGS="${CFLAGS+set}"
+     ac_save_CFLAGS="$CFLAGS"
+     CFLAGS='-x c++  -Wl,--gc-sections'
+ 
+     # Check for -Wl,--gc-sections
+     # XXX This test is broken at the moment, as symbols required for linking
+     # are now in libsupc++ (not built yet).  In addition, this test has
+     # cored on solaris in the past.  In addition, --gc-sections doesn't
+     # really work at the moment (keeps on discarding used sections, first
+     # .eh_frame and now some of the glibc sections for iconv).
+     # Bzzzzt.  Thanks for playing, maybe next time.
+     echo "$as_me:$LINENO: checking for ld that supports -Wl,--gc-sections" >&5
+ echo $ECHO_N "checking for ld that supports -Wl,--gc-sections... $ECHO_C" >&6
+     if test "$cross_compiling" = yes; then
+   ac_sectionLDflags=yes
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ 
+      int main(void)
+      {
+        try { throw 1; }
+        catch (...) { };
+        return 0;
+      }
+ 
+ _ACEOF
+ rm -f conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+   (eval $ac_link) 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }; }; then
+   ac_sectionLDflags=yes
+ else
+   echo "$as_me: program exited with status $ac_status" >&5
+ echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+ 
+ ( exit $ac_status )
+ ac_sectionLDflags=no
+ fi
+ rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+     if test "$ac_test_CFLAGS" = set; then
+       CFLAGS="$ac_save_CFLAGS"
+     else
+       # this is the suspicious part
+       CFLAGS=''
+     fi
+     if test "$ac_sectionLDflags" = "yes"; then
+       SECTION_LDFLAGS="-Wl,--gc-sections $SECTION_LDFLAGS"
+     fi
+     echo "$as_me:$LINENO: result: $ac_sectionLDflags" >&5
+ echo "${ECHO_T}$ac_sectionLDflags" >&6
+   fi
+ 
+   # Set -z,relro.
+   # Note this is only for shared objects
+   ac_ld_relro=no
+   if test x"$with_gnu_ld" = x"yes"; then
+     echo "$as_me:$LINENO: checking for ld that supports -Wl,-z,relro" >&5
+ echo $ECHO_N "checking for ld that supports -Wl,-z,relro... $ECHO_C" >&6
+     cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
+     if test -n "$cxx_z_relo"; then
+       OPT_LDFLAGS="-Wl,-z,relro"
+       ac_ld_relro=yes
+     fi
+     echo "$as_me:$LINENO: result: $ac_ld_relro" >&5
+ echo "${ECHO_T}$ac_ld_relro" >&6
+   fi
+ 
+   # Set linker optimization flags.
+   if test x"$with_gnu_ld" = x"yes"; then
+     OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"
+   fi
+ 
+ 
+ 
+ 
           cat >>confdefs.h <<\_ACEOF
  #define HAVE_GETPAGESIZE 1
  _ACEOF
*************** done
*** 86021,86032 ****
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
  
!   ldver=`$LD --version 2>/dev/null | head -1 | \
!          sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!   glibcxx_gnu_ld_version=`echo $ldver | \
!          $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
--- 85662,85675 ----
  
    # Start by getting the version number.  I think the libtool test already
    # does some of this, but throws away the result.
+   if test x"$with_gnu_ld" = x"yes"; then
  
!     ldver=`$LD --version 2>/dev/null | head -1 | \
!            sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
  
!     glibcxx_gnu_ld_version=`echo $ldver | \
!            $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
!   fi
  
    # Set --gc-sections.
    if test "$with_gnu_ld" = "notbroken"; then
*************** fi;
*** 87626,87632 ****
  # Turn a 'yes' into a suitable default.
  if test x$enable_symvers = xyes ; then
    if test $enable_shared = no ||
!      test "x$LD" = x ; then
      enable_symvers=no
    elif test $with_gnu_ld = yes ; then
      enable_symvers=gnu
--- 87269,87275 ----
  # Turn a 'yes' into a suitable default.
  if test x$enable_symvers = xyes ; then
    if test $enable_shared = no ||
!      test "x$LD" = x || test x$gcc_no_link = xyes; then
      enable_symvers=no
    elif test $with_gnu_ld = yes ; then
      enable_symvers=gnu
diff -Nrcpad gcc-4.1.1/libstdc++-v3/configure.host gcc-4.1.2/libstdc++-v3/configure.host
*** gcc-4.1.1/libstdc++-v3/configure.host	Thu Nov 17 20:10:51 2005
--- gcc-4.1.2/libstdc++-v3/configure.host	Sun Jan 28 20:12:40 2007
*************** esac
*** 119,127 ****
--- 119,136 ----
  # Set specific CPU overrides for atomic_word_dir. Most can just use generic.
  # THIS TABLE IS SORTED.  KEEP IT THAT WAY.
  case "${host_cpu}" in
+   alpha*)
+     atomic_word_dir=cpu/alpha
+     ;;
    cris*)
      atomic_word_dir=cpu/cris
      ;;
+   ia64)
+     atomic_word_dir=cpu/ia64
+     ;;
+   powerpc* | rs6000)
+     atomic_word_dir=cpu/powerpc
+     ;;
    sparc* | ultrasparc)
      atomic_word_dir=cpu/sparc
      ;;
diff -Nrcpad gcc-4.1.1/libstdc++-v3/crossconfig.m4 gcc-4.1.2/libstdc++-v3/crossconfig.m4
*** gcc-4.1.1/libstdc++-v3/crossconfig.m4	Thu Jan 12 07:59:07 2006
--- gcc-4.1.2/libstdc++-v3/crossconfig.m4	Tue Dec 12 14:18:36 2006
*************** case "${host}" in
*** 238,244 ****
      AC_CHECK_HEADERS([sys/types.h locale.h float.h])
      GLIBCXX_CHECK_LINKER_FEATURES
      GLIBCXX_CHECK_COMPLEX_MATH_SUPPORT
-     GLIBCXX_CHECK_ICONV_SUPPORT
      ;;
    *-netbsd*)
      AC_CHECK_HEADERS([nan.h ieeefp.h endian.h sys/isa_defs.h \
--- 238,243 ----
*************** case "${host}" in
*** 314,319 ****
--- 313,319 ----
      #    os_include_dir="os/solaris/solaris2.6"
      #    ;;
        *-solaris2.7 | *-solaris2.8 | *-solaris2.9 | *-solaris2.10)
+          GLIBCXX_CHECK_LINKER_FEATURES
           AC_DEFINE(HAVE_GETPAGESIZE)
           AC_DEFINE(HAVE_SIGSETJMP)
           AC_DEFINE(HAVE_MBSTATE_T)
diff -Nrcpad gcc-4.1.1/libstdc++-v3/include/bits/basic_string.h gcc-4.1.2/libstdc++-v3/include/bits/basic_string.h
*** gcc-4.1.1/libstdc++-v3/include/bits/basic_string.h	Thu Dec  8 11:24:07 2005
--- gcc-4.1.2/libstdc++-v3/include/bits/basic_string.h	Fri Oct  6 11:48:18 2006
***************
*** 1,6 ****
  // Components for manipulating sequences of characters -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
  // Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
--- 1,6 ----
  // Components for manipulating sequences of characters -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
  // Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
*************** namespace std
*** 1623,1629 ****
        /**
         *  @brief  Find last position of a C string.
         *  @param s  C string to locate.
!        *  @param pos  Index of character to start search at (default 0).
         *  @return  Index of start of  last occurrence.
         *
         *  Starting from @a pos, searches backward for the value of @a s within
--- 1623,1629 ----
        /**
         *  @brief  Find last position of a C string.
         *  @param s  C string to locate.
!        *  @param pos  Index of character to start search at (default end).
         *  @return  Index of start of  last occurrence.
         *
         *  Starting from @a pos, searches backward for the value of @a s within
*************** namespace std
*** 1640,1646 ****
        /**
         *  @brief  Find last position of a character.
         *  @param c  Character to locate.
!        *  @param pos  Index of character to search back from (default 0).
         *  @return  Index of last occurrence.
         *
         *  Starting from @a pos, searches backward for @a c within this string.
--- 1640,1646 ----
        /**
         *  @brief  Find last position of a character.
         *  @param c  Character to locate.
!        *  @param pos  Index of character to search back from (default end).
         *  @return  Index of last occurrence.
         *
         *  Starting from @a pos, searches backward for @a c within this string.
diff -Nrcpad gcc-4.1.1/libstdc++-v3/include/bits/basic_string.tcc gcc-4.1.2/libstdc++-v3/include/bits/basic_string.tcc
*** gcc-4.1.1/libstdc++-v3/include/bits/basic_string.tcc	Wed Aug 17 02:28:44 2005
--- gcc-4.1.2/libstdc++-v3/include/bits/basic_string.tcc	Mon Oct 16 09:56:31 2006
*************** namespace std
*** 588,593 ****
--- 588,601 ----
        void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
        _Rep *__p = new (__place) _Rep;
        __p->_M_capacity = __capacity;
+       // ABI compatibility - 3.4.x set in _S_create both
+       // _M_refcount and _M_length.  All callers of _S_create
+       // in basic_string.tcc then set just _M_length.
+       // In 4.0.x and later both _M_refcount and _M_length
+       // are initialized in the callers, unfortunately we can
+       // have 3.4.x compiled code with _S_create callers inlined
+       // calling 4.0.x+ _S_create.
+       __p->_M_set_sharable();
        return __p;
      }
  
diff -Nrcpad gcc-4.1.1/libstdc++-v3/include/bits/sstream.tcc gcc-4.1.2/libstdc++-v3/include/bits/sstream.tcc
*** gcc-4.1.1/libstdc++-v3/include/bits/sstream.tcc	Mon Mar  6 12:45:23 2006
--- gcc-4.1.2/libstdc++-v3/include/bits/sstream.tcc	Fri Oct  6 09:58:03 2006
*************** namespace std
*** 198,204 ****
        const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
  
        const char_type* __beg = __testin ? this->eback() : this->pbase();
!       if (__beg && (__testin || __testout))
  	{
  	  _M_update_egptr();
  
--- 198,204 ----
        const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
  
        const char_type* __beg = __testin ? this->eback() : this->pbase();
!       if ((__beg || !off_type(__sp)) && (__testin || __testout))
  	{
  	  _M_update_egptr();
  
diff -Nrcpad gcc-4.1.1/libstdc++-v3/include/ext/array_allocator.h gcc-4.1.2/libstdc++-v3/include/ext/array_allocator.h
*** gcc-4.1.1/libstdc++-v3/include/ext/array_allocator.h	Wed Aug 17 02:28:44 2005
--- gcc-4.1.2/libstdc++-v3/include/ext/array_allocator.h	Sat Oct 28 22:03:17 2006
***************
*** 1,6 ****
  // array allocator -*- C++ -*-
  
! // Copyright (C) 2004, 2005 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
--- 1,6 ----
  // array allocator -*- C++ -*-
  
! // Copyright (C) 2004, 2005, 2006 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
*************** namespace __gnu_cxx
*** 84,90 ****
     *  @brief  An allocator that uses previously allocated memory.
     *  This memory can be externally, globally, or otherwise allocated.
     */
!   template<typename _Tp, typename _Array = std::tr1::array<_Tp> >
      class array_allocator : public array_allocator_base<_Tp>
      {
      public:
--- 84,90 ----
     *  @brief  An allocator that uses previously allocated memory.
     *  This memory can be externally, globally, or otherwise allocated.
     */
!   template<typename _Tp, typename _Array = std::tr1::array<_Tp, 1> >
      class array_allocator : public array_allocator_base<_Tp>
      {
      public:
diff -Nrcpad gcc-4.1.1/libstdc++-v3/include/ext/mt_allocator.h gcc-4.1.2/libstdc++-v3/include/ext/mt_allocator.h
*** gcc-4.1.1/libstdc++-v3/include/ext/mt_allocator.h	Mon Dec 26 12:02:12 2005
--- gcc-4.1.2/libstdc++-v3/include/ext/mt_allocator.h	Mon Sep 25 10:05:43 2006
*************** namespace __gnu_cxx
*** 48,54 ****
    struct __pool_base
    {
      // Using short int as type for the binmap implies we are never
!     // caching blocks larger than 65535 with this allocator.
      typedef unsigned short int _Binmap_type;
  
      // Variables used to configure the behavior of the allocator,
--- 48,54 ----
    struct __pool_base
    {
      // Using short int as type for the binmap implies we are never
!     // caching blocks larger than 32768 with this allocator.
      typedef unsigned short int _Binmap_type;
  
      // Variables used to configure the behavior of the allocator,
*************** namespace __gnu_cxx
*** 71,89 ****
        // Allocation requests (after round-up to power of 2) below
        // this value will be handled by the allocator. A raw new/
        // call will be used for requests larger than this value.
        size_t	_M_max_bytes; 
!       
        // Size in bytes of the smallest bin.
!       // NB: Must be a power of 2 and >= _M_align.
        size_t	_M_min_bin;
!       
        // In order to avoid fragmenting and minimize the number of
        // new() calls we always request new memory using this
        // value. Based on previous discussions on the libstdc++
        // mailing list we have choosen the value below.
        // See http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html
        size_t	_M_chunk_size;
!       
        // The maximum number of supported threads. For
        // single-threaded operation, use one. Maximum values will
        // vary depending on details of the underlying system. (For
--- 71,93 ----
        // Allocation requests (after round-up to power of 2) below
        // this value will be handled by the allocator. A raw new/
        // call will be used for requests larger than this value.
+       // NB: Must be much smaller than _M_chunk_size and in any
+       // case <= 32768.
        size_t	_M_max_bytes; 
! 
        // Size in bytes of the smallest bin.
!       // NB: Must be a power of 2 and >= _M_align (and of course
!       // much smaller than _M_max_bytes).
        size_t	_M_min_bin;
! 
        // In order to avoid fragmenting and minimize the number of
        // new() calls we always request new memory using this
        // value. Based on previous discussions on the libstdc++
        // mailing list we have choosen the value below.
        // See http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html
+       // NB: At least one order of magnitude > _M_max_bytes. 
        size_t	_M_chunk_size;
! 
        // The maximum number of supported threads. For
        // single-threaded operation, use one. Maximum values will
        // vary depending on details of the underlying system. (For
*************** namespace __gnu_cxx
*** 91,97 ****
        // /proc/sys/kernel/threads-max, while Linux 2.6.6 reports
        // 65534)
        size_t 	_M_max_threads;
!       
        // Each time a deallocation occurs in a threaded application
        // we make sure that there are no more than
        // _M_freelist_headroom % of used memory on the freelist. If
--- 95,101 ----
        // /proc/sys/kernel/threads-max, while Linux 2.6.6 reports
        // 65534)
        size_t 	_M_max_threads;
! 
        // Each time a deallocation occurs in a threaded application
        // we make sure that there are no more than
        // _M_freelist_headroom % of used memory on the freelist. If
diff -Nrcpad gcc-4.1.1/libstdc++-v3/include/ext/rc_string_base.h gcc-4.1.2/libstdc++-v3/include/ext/rc_string_base.h
*** gcc-4.1.1/libstdc++-v3/include/ext/rc_string_base.h	Thu Jan 19 12:04:31 2006
--- gcc-4.1.2/libstdc++-v3/include/ext/rc_string_base.h	Fri Aug 18 15:42:27 2006
*************** namespace __gnu_cxx
*** 175,185 ****
        // with a terminating character and m _CharT elements, it'd
        // look like this:
        // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
        // Solving for m:
!       // m = ((npos - sizeof(_Rep)) / sizeof(_CharT)) - 1
!       // In addition, this implementation quarters this amount.
!       enum { _S_max_size = (((static_cast<size_type>(-1) - sizeof(_Rep))
! 			     / sizeof(_CharT)) - 1) / 4 };
  
        // Data Member (private):
        mutable typename _Util_Base::template _Alloc_hider<_Alloc>  _M_dataplus;
--- 175,187 ----
        // with a terminating character and m _CharT elements, it'd
        // look like this:
        // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
+       //        + sizeof(_Rep) - 1
+       // (NB: last two terms for rounding reasons, see _M_create below)
        // Solving for m:
!       // m = ((npos - 2 * sizeof(_Rep) + 1) / sizeof(_CharT)) - 1
!       // In addition, this implementation halfs this amount.
!       enum { _S_max_size = (((static_cast<size_type>(-1) - 2 * sizeof(_Rep)
! 			      + 1) / sizeof(_CharT)) - 1) / 2 };
  
        // Data Member (private):
        mutable typename _Util_Base::template _Alloc_hider<_Alloc>  _M_dataplus;
*************** namespace __gnu_cxx
*** 335,340 ****
--- 337,346 ----
        void
        _M_erase(size_type __pos, size_type __n);
  
+       void
+       _M_clear()
+       { _M_erase(size_type(0), _M_length()); }
+ 
        bool
        _M_compare(const __rc_string_base&) const
        { return false; }
*************** namespace __gnu_cxx
*** 385,391 ****
        // meet amortized linear time requirements of the library: see
        // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
        if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
! 	__capacity = 2 * __old_capacity;
  
        // NB: Need an array of char_type[__capacity], plus a terminating
        // null char_type() element, plus enough for the _Rep data structure,
--- 391,402 ----
        // meet amortized linear time requirements of the library: see
        // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
        if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
! 	{
! 	  __capacity = 2 * __old_capacity;
! 	  // Never allocate a string bigger than _S_max_size.
! 	  if (__capacity > size_type(_S_max_size))
! 	    __capacity = size_type(_S_max_size);
! 	}
  
        // NB: Need an array of char_type[__capacity], plus a terminating
        // null char_type() element, plus enough for the _Rep data structure,
*************** namespace __gnu_cxx
*** 400,406 ****
  	{
  	  const size_type __extra = __pagesize - __adj_size % __pagesize;
  	  __capacity += __extra / sizeof(_CharT);
- 	  // Never allocate a string bigger than _S_max_size.
  	  if (__capacity > size_type(_S_max_size))
  	    __capacity = size_type(_S_max_size);
  	  __size = (__capacity + 1) * sizeof(_CharT) + 2 * sizeof(_Rep) - 1;
--- 411,416 ----
diff -Nrcpad gcc-4.1.1/libstdc++-v3/include/ext/sso_string_base.h gcc-4.1.2/libstdc++-v3/include/ext/sso_string_base.h
*** gcc-4.1.1/libstdc++-v3/include/ext/sso_string_base.h	Thu Jan 19 12:04:31 2006
--- gcc-4.1.2/libstdc++-v3/include/ext/sso_string_base.h	Fri Aug 18 15:42:27 2006
*************** namespace __gnu_cxx
*** 61,69 ****
        // npos = m * sizeof(_CharT) + sizeof(_CharT)
        // Solving for m:
        // m = npos / sizeof(_CharT) - 1
!       // In addition, this implementation quarters this amount.
        enum { _S_max_size = (((static_cast<size_type>(-1)
! 			      / sizeof(_CharT)) - 1) / 4) };
  
        // Data Members (private):
        typename _Util_Base::template _Alloc_hider<_CharT_alloc_type>
--- 61,69 ----
        // npos = m * sizeof(_CharT) + sizeof(_CharT)
        // Solving for m:
        // m = npos / sizeof(_CharT) - 1
!       // In addition, this implementation halfs this amount.
        enum { _S_max_size = (((static_cast<size_type>(-1)
! 			      / sizeof(_CharT)) - 1) / 2) };
  
        // Data Members (private):
        typename _Util_Base::template _Alloc_hider<_CharT_alloc_type>
*************** namespace __gnu_cxx
*** 226,231 ****
--- 226,235 ----
        void
        _M_erase(size_type __pos, size_type __n);
  
+       void
+       _M_clear()
+       { _M_set_length(0); }
+ 
        bool
        _M_compare(const __sso_string_base&) const
        { return false; }
*************** namespace __gnu_cxx
*** 324,330 ****
        // meet amortized linear time requirements of the library: see
        // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
        if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
! 	__capacity = 2 * __old_capacity;
  
        // NB: Need an array of char_type[__capacity], plus a terminating
        // null char_type() element.
--- 328,339 ----
        // meet amortized linear time requirements of the library: see
        // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
        if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
! 	{
! 	  __capacity = 2 * __old_capacity;
! 	  // Never allocate a string bigger than _S_max_size.
! 	  if (__capacity > size_type(_S_max_size))
! 	    __capacity = size_type(_S_max_size);
! 	}
  
        // NB: Need an array of char_type[__capacity], plus a terminating
        // null char_type() element.
diff -Nrcpad gcc-4.1.1/libstdc++-v3/include/ext/vstring.h gcc-4.1.2/libstdc++-v3/include/ext/vstring.h
*** gcc-4.1.1/libstdc++-v3/include/ext/vstring.h	Tue Mar 28 12:55:21 2006
--- gcc-4.1.2/libstdc++-v3/include/ext/vstring.h	Fri Oct  6 11:48:18 2006
***************
*** 1,6 ****
  // Versatile string -*- C++ -*-
  
! // Copyright (C) 2005 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
--- 1,6 ----
  // Versatile string -*- C++ -*-
  
! // Copyright (C) 2005, 2006 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
*************** namespace __gnu_cxx
*** 409,415 ****
         */
        void
        clear()
!       { this->_M_erase(size_type(0), this->size()); }
  
        /**
         *  Returns true if the %string is empty.  Equivalent to *this == "".
--- 409,415 ----
         */
        void
        clear()
!       { this->_M_clear(); }
  
        /**
         *  Returns true if the %string is empty.  Equivalent to *this == "".
*************** namespace __gnu_cxx
*** 1365,1371 ****
        /**
         *  @brief  Find last position of a C string.
         *  @param s  C string to locate.
!        *  @param pos  Index of character to start search at (default 0).
         *  @return  Index of start of  last occurrence.
         *
         *  Starting from @a pos, searches backward for the value of @a s within
--- 1365,1371 ----
        /**
         *  @brief  Find last position of a C string.
         *  @param s  C string to locate.
!        *  @param pos  Index of character to start search at (default end).
         *  @return  Index of start of  last occurrence.
         *
         *  Starting from @a pos, searches backward for the value of @a s within
*************** namespace __gnu_cxx
*** 1382,1388 ****
        /**
         *  @brief  Find last position of a character.
         *  @param c  Character to locate.
!        *  @param pos  Index of character to search back from (default 0).
         *  @return  Index of last occurrence.
         *
         *  Starting from @a pos, searches backward for @a c within this string.
--- 1382,1388 ----
        /**
         *  @brief  Find last position of a character.
         *  @param c  Character to locate.
!        *  @param pos  Index of character to search back from (default end).
         *  @return  Index of last occurrence.
         *
         *  Starting from @a pos, searches backward for @a c within this string.
diff -Nrcpad gcc-4.1.1/libstdc++-v3/include/tr1/array gcc-4.1.2/libstdc++-v3/include/tr1/array
*** gcc-4.1.1/libstdc++-v3/include/tr1/array	Thu Mar  2 01:20:52 2006
--- gcc-4.1.2/libstdc++-v3/include/tr1/array	Sat Oct 28 22:03:17 2006
*************** namespace tr1
*** 47,53 ****
  {
    /// @brief  struct array [6.2.2].
    /// NB: Requires complete type _Tp.
!   template<typename _Tp, std::size_t _Nm = 1>
      struct array
      {
        typedef _Tp 	    			      value_type;
--- 47,53 ----
  {
    /// @brief  struct array [6.2.2].
    /// NB: Requires complete type _Tp.
!   template<typename _Tp, std::size_t _Nm>
      struct array
      {
        typedef _Tp 	    			      value_type;
*************** namespace tr1
*** 60,68 ****
        typedef std::reverse_iterator<iterator>	      reverse_iterator;
        typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
  
-       // Compile time constant without other dependencies.
-       enum { _S_index = _Nm };
- 
        // Support for zero-sized arrays mandatory.
        value_type _M_instance[_Nm ? _Nm : 1] __attribute__((__aligned__));
  
--- 60,65 ----
*************** namespace tr1
*** 120,148 ****
        empty() const { return size() == 0; }
  
        // Element access.
!       reference 
        operator[](size_type __n)
        { return _M_instance[__n]; }
  
!       const_reference 
        operator[](size_type __n) const
        { return _M_instance[__n]; }
  
!       const_reference 
!       at(size_type __n) const
!       { 
! 	if (__builtin_expect(__n > _Nm, false))
! 	  std::__throw_out_of_range("array::at");
! 	return _M_instance[__n]; 
!       }
! 
!       reference 
        at(size_type __n)
!       { 
! 	if (__builtin_expect(__n > _Nm, false))
! 	  std::__throw_out_of_range("array::at");
! 	return _M_instance[__n]; 
!       }
  
        reference 
        front()
--- 117,137 ----
        empty() const { return size() == 0; }
  
        // Element access.
!       reference
        operator[](size_type __n)
        { return _M_instance[__n]; }
  
!       const_reference
        operator[](size_type __n) const
        { return _M_instance[__n]; }
  
!       reference
        at(size_type __n)
!       { return _M_at<_Nm>(__n); }
! 
!       const_reference
!       at(size_type __n) const
!       { return _M_at<_Nm>(__n); }
  
        reference 
        front()
*************** namespace tr1
*** 154,164 ****
  
        reference 
        back()
!       { return *(end() - 1); }
  
        const_reference 
        back() const
!       { return *(end() - 1); }
  
        _Tp* 
        data()
--- 143,153 ----
  
        reference 
        back()
!       { return _Nm ? *(end() - 1) : *end(); }
  
        const_reference 
        back() const
!       { return _Nm ? *(end() - 1) : *end(); }
  
        _Tp* 
        data()
*************** namespace tr1
*** 167,172 ****
--- 156,197 ----
        const _Tp* 
        data() const
        { return &_M_instance[0]; }
+ 
+     private:
+       template<std::size_t _Mm>
+         typename std::__enable_if<reference, _Mm>::__type
+         _M_at(size_type __n)
+         {
+ 	  if (__builtin_expect(__n >= _Mm, false))
+ 	    std::__throw_out_of_range("array::_M_at");
+ 	  return _M_instance[__n];
+ 	}
+ 
+       // Avoid "unsigned comparison with zero" warnings.
+       template<std::size_t _Mm>
+         typename std::__enable_if<reference, !_Mm>::__type
+         _M_at(size_type)
+         {
+ 	  std::__throw_out_of_range("array::_M_at");
+ 	  return _M_instance[0];
+ 	}
+ 
+       template<std::size_t _Mm>
+         typename std::__enable_if<const_reference, _Mm>::__type
+         _M_at(size_type __n) const
+         {
+ 	  if (__builtin_expect(__n >= _Mm, false))
+ 	    std::__throw_out_of_range("array::_M_at");
+ 	  return _M_instance[__n];
+ 	}
+ 
+       template<std::size_t _Mm>
+         typename std::__enable_if<const_reference, !_Mm>::__type
+         _M_at(size_type) const
+         {
+ 	  std::__throw_out_of_range("array::_M_at");
+ 	  return _M_instance[0];
+ 	}     
      };
  
    // Array comparisons.
*************** namespace tr1
*** 212,222 ****
    // Tuple interface to class template array [6.2.2.5].
    template<typename _Tp> class tuple_size;
    template<int _Int, typename _Tp> class tuple_element;
!   
    template<typename _Tp, std::size_t _Nm>
      struct tuple_size<array<_Tp, _Nm> >
      { static const int value = _Nm; };
!  
    template<int _Int, typename _Tp, std::size_t _Nm>
      struct tuple_element<_Int, array<_Tp, _Nm> >
      { typedef _Tp type; };
--- 237,247 ----
    // Tuple interface to class template array [6.2.2.5].
    template<typename _Tp> class tuple_size;
    template<int _Int, typename _Tp> class tuple_element;
! 
    template<typename _Tp, std::size_t _Nm>
      struct tuple_size<array<_Tp, _Nm> >
      { static const int value = _Nm; };
! 
    template<int _Int, typename _Tp, std::size_t _Nm>
      struct tuple_element<_Int, array<_Tp, _Nm> >
      { typedef _Tp type; };
diff -Nrcpad gcc-4.1.1/libstdc++-v3/include/tr1/functional_iterate.h gcc-4.1.2/libstdc++-v3/include/tr1/functional_iterate.h
*** gcc-4.1.1/libstdc++-v3/include/tr1/functional_iterate.h	Wed Aug 17 02:28:44 2005
--- gcc-4.1.2/libstdc++-v3/include/tr1/functional_iterate.h	Tue Sep 26 00:59:53 2006
***************
*** 1,6 ****
  // TR1 functional -*- C++ -*-
  
! // Copyright (C) 2005 Free Software Foundation, Inc.
  // Written by Douglas Gregor <doug.gregor -at- gmail.com>
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
--- 1,6 ----
  // TR1 functional -*- C++ -*-
  
! // Copyright (C) 2005, 2006 Free Software Foundation, Inc.
  // Written by Douglas Gregor <doug.gregor -at- gmail.com>
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
*************** template<typename _Res, typename _Class 
*** 199,205 ****
    public:
      typedef _Res result_type;
  
!     explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
  
      // Handle objects
      _Res
--- 199,205 ----
    public:
      typedef _Res result_type;
  
!     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
  
      // Handle objects
      _Res
*************** template<typename _Res, typename _Class 
*** 253,259 ****
    public:
      typedef _Res result_type;
  
!     explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
  
      // Handle objects
      _Res
--- 253,259 ----
    public:
      typedef _Res result_type;
  
!     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
  
      // Handle objects
      _Res
*************** template<typename _Res, typename _Class 
*** 307,313 ****
    public:
      typedef _Res result_type;
  
!     explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
  
      // Handle objects
      _Res
--- 307,313 ----
    public:
      typedef _Res result_type;
  
!     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
  
      // Handle objects
      _Res
*************** template<typename _Res, typename _Class 
*** 361,367 ****
    public:
      typedef _Res result_type;
  
!     explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
  
      // Handle objects
      _Res
--- 361,367 ----
    public:
      typedef _Res result_type;
  
!     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
  
      // Handle objects
      _Res
diff -Nrcpad gcc-4.1.1/libstdc++-v3/include/tr1/hashtable gcc-4.1.2/libstdc++-v3/include/tr1/hashtable
*** gcc-4.1.1/libstdc++-v3/include/tr1/hashtable	Sun May 14 10:53:26 2006
--- gcc-4.1.2/libstdc++-v3/include/tr1/hashtable	Fri May 26 11:15:23 2006
*************** namespace Internal
*** 423,429 ****
      typedef std::size_t result_type;
  
      result_type
!     operator() (first_argument_type r, second_argument_type N) const
      { return r % N; }
    };
  
--- 423,429 ----
      typedef std::size_t result_type;
  
      result_type
!     operator()(first_argument_type r, second_argument_type N) const
      { return r % N; }
    };
  
*************** namespace Internal
*** 583,589 ****
    next_bkt(std::size_t n) const
    {
      const unsigned long* const last = X<>::primes + X<>::n_primes;
!     const unsigned long* p = std::lower_bound (X<>::primes, last, n);
      m_next_resize = static_cast<std::size_t>(std::ceil(*p * m_max_load_factor));
      return *p;
    }
--- 583,589 ----
    next_bkt(std::size_t n) const
    {
      const unsigned long* const last = X<>::primes + X<>::n_primes;
!     const unsigned long* p = std::lower_bound(X<>::primes, last, n);
      m_next_resize = static_cast<std::size_t>(std::ceil(*p * m_max_load_factor));
      return *p;
    }
*************** namespace Internal
*** 596,603 ****
    {
      const unsigned long* const last = X<>::primes + X<>::n_primes;
      const float min_bkts = n / m_max_load_factor;
!     const unsigned long* p = std::lower_bound (X<>::primes, last,
! 					       min_bkts, lt());
      m_next_resize = static_cast<std::size_t>(std::ceil(*p * m_max_load_factor));
      return *p;
    }
--- 596,603 ----
    {
      const unsigned long* const last = X<>::primes + X<>::n_primes;
      const float min_bkts = n / m_max_load_factor;
!     const unsigned long* p = std::lower_bound(X<>::primes, last,
! 					      min_bkts, lt());
      m_next_resize = static_cast<std::size_t>(std::ceil(*p * m_max_load_factor));
      return *p;
    }
*************** namespace Internal
*** 620,629 ****
  	float min_bkts = (float(n_ins) + float(n_elt)) / m_max_load_factor;
  	if (min_bkts > n_bkt)
  	  {
! 	    min_bkts = std::max (min_bkts, m_growth_factor * n_bkt);
  	    const unsigned long* const last = X<>::primes + X<>::n_primes;
! 	    const unsigned long* p = std::lower_bound (X<>::primes, last,
! 						       min_bkts, lt());
  	    m_next_resize = 
  	      static_cast<std::size_t>(std::ceil(*p * m_max_load_factor));
  	    return std::make_pair(true, *p);
--- 620,629 ----
  	float min_bkts = (float(n_ins) + float(n_elt)) / m_max_load_factor;
  	if (min_bkts > n_bkt)
  	  {
! 	    min_bkts = std::max(min_bkts, m_growth_factor * n_bkt);
  	    const unsigned long* const last = X<>::primes + X<>::n_primes;
! 	    const unsigned long* p = std::lower_bound(X<>::primes, last,
! 						      min_bkts, lt());
  	    m_next_resize = 
  	      static_cast<std::size_t>(std::ceil(*p * m_max_load_factor));
  	    return std::make_pair(true, *p);
*************** namespace Internal
*** 673,687 ****
        typedef typename Pair::second_type mapped_type;
        
        mapped_type&
!       operator[](const K& k)
!       {
! 	Hashtable* h = static_cast<Hashtable*>(this);
! 	typename Hashtable::iterator it = 
! 	  h->insert(std::make_pair(k, mapped_type())).first;
! 	return it->second;
!       }
      };
  
    // class template rehash_base.  Give hashtable the max_load_factor
    // functions iff the rehash policy is prime_rehash_policy.
    template<typename RehashPolicy, typename Hashtable>
--- 673,697 ----
        typedef typename Pair::second_type mapped_type;
        
        mapped_type&
!       operator[](const K& k);
      };
  
+   template<typename K, typename Pair, typename Hashtable>
+     typename map_base<K, Pair, extract1st<Pair>, true, Hashtable>::mapped_type&
+     map_base<K, Pair, extract1st<Pair>, true, Hashtable>::
+     operator[](const K& k)
+     {
+       Hashtable* h = static_cast<Hashtable*>(this);
+       typename Hashtable::hash_code_t code = h->m_hash_code(k);
+       std::size_t n = h->bucket_index(k, code, h->bucket_count());
+ 
+       typename Hashtable::node* p = h->m_find_node(h->m_buckets[n], k, code);
+       if (!p)
+ 	return h->m_insert_bucket(std::make_pair(k, mapped_type()),
+ 				  n, code)->second;
+       return (p->m_v).second;
+     }
+ 
    // class template rehash_base.  Give hashtable the max_load_factor
    // functions iff the rehash policy is prime_rehash_policy.
    template<typename RehashPolicy, typename Hashtable>
*************** namespace Internal
*** 744,758 ****
    
        std::size_t
        bucket_index(const Key& k, hash_code_t, std::size_t N) const
!       { return m_ranged_hash (k, N); }
  
        std::size_t
        bucket_index(const hash_node<Value, false>* p, std::size_t N) const
!       { return m_ranged_hash (m_extract (p->m_v), N); }
    
        bool
        compare(const Key& k, hash_code_t, hash_node<Value, false>* n) const
!       { return m_eq (k, m_extract(n->m_v)); }
  
        void
        store_code(hash_node<Value, false>*, hash_code_t) const
--- 754,768 ----
    
        std::size_t
        bucket_index(const Key& k, hash_code_t, std::size_t N) const
!       { return m_ranged_hash(k, N); }
  
        std::size_t
        bucket_index(const hash_node<Value, false>* p, std::size_t N) const
!       { return m_ranged_hash(m_extract(p->m_v), N); }
    
        bool
        compare(const Key& k, hash_code_t, hash_node<Value, false>* n) const
!       { return m_eq(k, m_extract(n->m_v)); }
  
        void
        store_code(hash_node<Value, false>*, hash_code_t) const
*************** namespace Internal
*** 820,834 ****
        
        std::size_t
        bucket_index(const Key&, hash_code_t c, std::size_t N) const
!       { return m_h2 (c, N); }
  
        std::size_t
        bucket_index(const hash_node<Value, false>* p, std::size_t N) const
!       { return m_h2 (m_h1 (m_extract (p->m_v)), N); }
  
        bool
        compare(const Key& k, hash_code_t, hash_node<Value, false>* n) const
!       { return m_eq (k, m_extract(n->m_v)); }
  
        void
        store_code(hash_node<Value, false>*, hash_code_t) const
--- 830,844 ----
        
        std::size_t
        bucket_index(const Key&, hash_code_t c, std::size_t N) const
!       { return m_h2(c, N); }
  
        std::size_t
        bucket_index(const hash_node<Value, false>* p, std::size_t N) const
!       { return m_h2(m_h1(m_extract(p->m_v)), N); }
  
        bool
        compare(const Key& k, hash_code_t, hash_node<Value, false>* n) const
!       { return m_eq(k, m_extract(n->m_v)); }
  
        void
        store_code(hash_node<Value, false>*, hash_code_t) const
*************** namespace Internal
*** 882,892 ****
    
        std::size_t
        bucket_index(const Key&, hash_code_t c, std::size_t N) const
!       { return m_h2 (c, N); }
  
        std::size_t
        bucket_index(const hash_node<Value, true>* p, std::size_t N) const
!       { return m_h2 (p->hash_code, N); }
  
        bool
        compare(const Key& k, hash_code_t c, hash_node<Value, true>* n) const
--- 892,902 ----
    
        std::size_t
        bucket_index(const Key&, hash_code_t c, std::size_t N) const
!       { return m_h2(c, N); }
  
        std::size_t
        bucket_index(const hash_node<Value, true>* p, std::size_t N) const
!       { return m_h2(p->hash_code, N); }
  
        bool
        compare(const Key& k, hash_code_t c, hash_node<Value, true>* n) const
*************** namespace tr1
*** 1028,1033 ****
--- 1038,1046 ----
  						 cache_hash_code>
          const_iterator;
  
+       template<typename K, typename Pair, typename Hashtable>
+         friend struct Internal::map_base;
+ 
      private:
        typedef Internal::hash_node<Value, cache_hash_code>    node;
        typedef typename Allocator::template rebind<node>::other
*************** namespace tr1
*** 1183,1189 ****
  
      public:				// lookup
        iterator
!       find(const key_type&);
  
        const_iterator
        find(const key_type& k) const;
--- 1196,1202 ----
  
      public:				// lookup
        iterator
!       find(const key_type& k);
  
        const_iterator
        find(const key_type& k) const;
*************** namespace tr1
*** 1197,1203 ****
        std::pair<const_iterator, const_iterator>
        equal_range(const key_type& k) const;
  
!     private:			// Insert and erase helper functions
        // ??? This dispatching is a workaround for the fact that we don't
        // have partial specialization of member templates; it would be
        // better to just specialize insert on unique_keys.  There may be a
--- 1210,1216 ----
        std::pair<const_iterator, const_iterator>
        equal_range(const key_type& k) const;
  
!     private:			// Find, insert and erase helper functions
        // ??? This dispatching is a workaround for the fact that we don't
        // have partial specialization of member templates; it would be
        // better to just specialize insert on unique_keys.  There may be a
*************** namespace tr1
*** 1213,1237 ****
          Insert_Conv_Type;
  
        node*
!       find_node(node* p, const key_type& k,
! 		typename hashtable::hash_code_t c) const;
  
        std::pair<iterator, bool>
!       insert(const value_type&, std::tr1::true_type);
    
        iterator
!       insert(const value_type&, std::tr1::false_type);
  
        void
!       erase_node(node*, node**);
  
      public:				// Insert and erase
        Insert_Return_Type
        insert(const value_type& v) 
!       { 
! 	return this->insert(v, std::tr1::integral_constant<bool,
! 			    unique_keys>());
!       }
  
        iterator
        insert(iterator, const value_type& v)
--- 1226,1251 ----
          Insert_Conv_Type;
  
        node*
!       m_find_node(node*, const key_type&,
! 		  typename hashtable::hash_code_t) const;
! 
!       iterator
!       m_insert_bucket(const value_type&, size_type,
! 		      typename hashtable::hash_code_t);
  
        std::pair<iterator, bool>
!       m_insert(const value_type&, std::tr1::true_type);
    
        iterator
!       m_insert(const value_type&, std::tr1::false_type);
  
        void
!       m_erase_node(node*, node**);
  
      public:				// Insert and erase
        Insert_Return_Type
        insert(const value_type& v) 
!       { return m_insert(v, std::tr1::integral_constant<bool, unique_keys>()); }
  
        iterator
        insert(iterator, const value_type& v)
*************** namespace tr1
*** 1324,1330 ****
  	    {
  	      node* tmp = p;
  	      p = p->m_next;
! 	      m_deallocate_node (tmp);
  	    }
  	  array[i] = 0;
  	}
--- 1338,1344 ----
  	    {
  	      node* tmp = p;
  	      p = p->m_next;
! 	      m_deallocate_node(tmp);
  	    }
  	  array[i] = 0;
  	}
*************** namespace tr1
*** 1342,1349 ****
  
        // We allocate one extra bucket to hold a sentinel, an arbitrary
        // non-null pointer.  Iterator increment relies on this.
!       node** p = alloc.allocate(n+1);
!       std::fill(p, p+n, (node*) 0);
        p[n] = reinterpret_cast<node*>(0x1000);
        return p;
      }
--- 1356,1363 ----
  
        // We allocate one extra bucket to hold a sentinel, an arbitrary
        // non-null pointer.  Iterator increment relies on this.
!       node** p = alloc.allocate(n + 1);
!       std::fill(p, p + n, (node*) 0);
        p[n] = reinterpret_cast<node*>(0x1000);
        return p;
      }
*************** namespace tr1
*** 1357,1363 ****
      m_deallocate_buckets(node** p, size_type n)
      {
        bucket_allocator_t alloc(m_node_allocator);
!       alloc.deallocate(p, n+1);
      }
  
    template<typename K, typename V, 
--- 1371,1377 ----
      m_deallocate_buckets(node** p, size_type n)
      {
        bucket_allocator_t alloc(m_node_allocator);
!       alloc.deallocate(p, n + 1);
      }
  
    template<typename K, typename V, 
*************** namespace tr1
*** 1369,1375 ****
  	      const H1& h1, const H2& h2, const H& h,
  	      const Eq& eq, const Ex& exk,
  	      const allocator_type& a)
!     : Internal::rehash_base<RP,hashtable>(),
        Internal::hash_code_base<K, V, Ex, Eq, H1, H2, H, c>(exk, eq, h1, h2, h),
        Internal::map_base<K, V, Ex, u, hashtable>(),
        m_node_allocator(a),
--- 1383,1389 ----
  	      const H1& h1, const H2& h2, const H& h,
  	      const Eq& eq, const Ex& exk,
  	      const allocator_type& a)
!     : Internal::rehash_base<RP, hashtable>(),
        Internal::hash_code_base<K, V, Ex, Eq, H1, H2, H, c>(exk, eq, h1, h2, h),
        Internal::map_base<K, V, Ex, u, hashtable>(),
        m_node_allocator(a),
*************** namespace tr1
*** 1392,1403 ****
  		const H1& h1, const H2& h2, const H& h,
  		const Eq& eq, const Ex& exk,
  		const allocator_type& a)
!       : Internal::rehash_base<RP,hashtable>(),
! 	Internal::hash_code_base<K, V, Ex, Eq, H1, H2, H, c> (exk, eq,
! 							      h1, h2, h),
! 	Internal::map_base<K,V,Ex,u,hashtable>(),
  	m_node_allocator(a),
! 	m_bucket_count (0),
  	m_element_count(0),
  	m_rehash_policy()
        {
--- 1406,1417 ----
  		const H1& h1, const H2& h2, const H& h,
  		const Eq& eq, const Ex& exk,
  		const allocator_type& a)
!       : Internal::rehash_base<RP, hashtable>(),
! 	Internal::hash_code_base<K, V, Ex, Eq, H1, H2, H, c>(exk, eq,
! 							     h1, h2, h),
! 	Internal::map_base<K, V, Ex, u, hashtable>(),
  	m_node_allocator(a),
! 	m_bucket_count(0),
  	m_element_count(0),
  	m_rehash_policy()
        {
*************** namespace tr1
*** 1433,1442 ****
        m_element_count(ht.m_element_count),
        m_rehash_policy(ht.m_rehash_policy)
      {
!       m_buckets = m_allocate_buckets (m_bucket_count);
        try
  	{
! 	  for (size_t i = 0; i < ht.m_bucket_count; ++i)
  	    {
  	      node* n = ht.m_buckets[i];
  	      node** tail = m_buckets + i;
--- 1447,1456 ----
        m_element_count(ht.m_element_count),
        m_rehash_policy(ht.m_rehash_policy)
      {
!       m_buckets = m_allocate_buckets(m_bucket_count);
        try
  	{
! 	  for (size_type i = 0; i < ht.m_bucket_count; ++i)
  	    {
  	      node* n = ht.m_buckets[i];
  	      node** tail = m_buckets + i;
*************** namespace tr1
*** 1449,1458 ****
  		}
  	    }
  	}
!       catch (...)
  	{
  	  clear();
! 	  m_deallocate_buckets (m_buckets, m_bucket_count);
  	  __throw_exception_again;
  	}
      }
--- 1463,1472 ----
  		}
  	    }
  	}
!       catch(...)
  	{
  	  clear();
! 	  m_deallocate_buckets(m_buckets, m_bucket_count);
  	  __throw_exception_again;
  	}
      }
*************** namespace tr1
*** 1513,1519 ****
        m_rehash_policy = pol;
        size_type n_bkt = pol.bkt_for_elements(m_element_count);
        if (n_bkt > m_bucket_count)
! 	m_rehash (n_bkt);
      }
  
    template<typename K, typename V, 
--- 1527,1533 ----
        m_rehash_policy = pol;
        size_type n_bkt = pol.bkt_for_elements(m_element_count);
        if (n_bkt > m_bucket_count)
! 	m_rehash(n_bkt);
      }
  
    template<typename K, typename V, 
*************** namespace tr1
*** 1526,1532 ****
      {
        typename hashtable::hash_code_t code = this->m_hash_code(k);
        std::size_t n = this->bucket_index(k, code, this->bucket_count());
!       node* p = find_node(m_buckets[n], k, code);
        return p ? iterator(p, m_buckets + n) : this->end();
      }
    
--- 1540,1546 ----
      {
        typename hashtable::hash_code_t code = this->m_hash_code(k);
        std::size_t n = this->bucket_index(k, code, this->bucket_count());
!       node* p = m_find_node(m_buckets[n], k, code);
        return p ? iterator(p, m_buckets + n) : this->end();
      }
    
*************** namespace tr1
*** 1540,1546 ****
      {
        typename hashtable::hash_code_t code = this->m_hash_code(k);
        std::size_t n = this->bucket_index(k, code, this->bucket_count());
!       node* p = find_node(m_buckets[n], k, code);
        return p ? const_iterator(p, m_buckets + n) : this->end();
      }
    
--- 1554,1560 ----
      {
        typename hashtable::hash_code_t code = this->m_hash_code(k);
        std::size_t n = this->bucket_index(k, code, this->bucket_count());
!       node* p = m_find_node(m_buckets[n], k, code);
        return p ? const_iterator(p, m_buckets + n) : this->end();
      }
    
*************** namespace tr1
*** 1554,1561 ****
      {
        typename hashtable::hash_code_t code = this->m_hash_code(k);
        std::size_t n = this->bucket_index(k, code, this->bucket_count());
!       size_t result = 0;
!       for (node* p = m_buckets[n]; p ; p = p->m_next)
  	if (this->compare(k, code, p))
  	  ++result;
        return result;
--- 1568,1575 ----
      {
        typename hashtable::hash_code_t code = this->m_hash_code(k);
        std::size_t n = this->bucket_index(k, code, this->bucket_count());
!       std::size_t result = 0;
!       for (node* p = m_buckets[n]; p; p = p->m_next)
  	if (this->compare(k, code, p))
  	  ++result;
        return result;
*************** namespace tr1
*** 1575,1587 ****
        typename hashtable::hash_code_t code = this->m_hash_code(k);
        std::size_t n = this->bucket_index(k, code, this->bucket_count());
        node** head = m_buckets + n;
!       node* p = find_node (*head, k, code);
!       
        if (p)
  	{
  	  node* p1 = p->m_next;
! 	  for (; p1 ; p1 = p1->m_next)
! 	    if (!this->compare (k, code, p1))
  	      break;
  
  	  iterator first(p, head);
--- 1589,1601 ----
        typename hashtable::hash_code_t code = this->m_hash_code(k);
        std::size_t n = this->bucket_index(k, code, this->bucket_count());
        node** head = m_buckets + n;
!       node* p = m_find_node(*head, k, code);
! 
        if (p)
  	{
  	  node* p1 = p->m_next;
! 	  for (; p1; p1 = p1->m_next)
! 	    if (!this->compare(k, code, p1))
  	      break;
  
  	  iterator first(p, head);
*************** namespace tr1
*** 1608,1619 ****
        typename hashtable::hash_code_t code = this->m_hash_code(k);
        std::size_t n = this->bucket_index(k, code, this->bucket_count());
        node** head = m_buckets + n;
!       node* p = find_node(*head, k, code);
  
        if (p)
  	{
  	  node* p1 = p->m_next;
! 	  for (; p1 ; p1 = p1->m_next)
  	    if (!this->compare(k, code, p1))
  	      break;
  
--- 1622,1633 ----
        typename hashtable::hash_code_t code = this->m_hash_code(k);
        std::size_t n = this->bucket_index(k, code, this->bucket_count());
        node** head = m_buckets + n;
!       node* p = m_find_node(*head, k, code);
  
        if (p)
  	{
  	  node* p1 = p->m_next;
! 	  for (; p1; p1 = p1->m_next)
  	    if (!this->compare(k, code, p1))
  	      break;
  
*************** namespace tr1
*** 1635,1677 ****
  	   bool c, bool ci, bool u>
      typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::node* 
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     find_node(node* p, const key_type& k,
! 	      typename hashtable::hash_code_t code) const
      {
!       for ( ; p ; p = p->m_next)
! 	if (this->compare (k, code, p))
  	  return p;
        return false;
      }
  
!   // Insert v if no element with its key is already present.
    template<typename K, typename V, 
  	   typename A, typename Ex, typename Eq,
  	   typename H1, typename H2, typename H, typename RP,
  	   bool c, bool ci, bool u>
!     std::pair<typename hashtable<K, V, A, Ex, Eq, H1,
! 				 H2, H, RP, c, ci, u>::iterator, bool>
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     insert(const value_type& v, std::tr1::true_type)
      {
!       const key_type& k = this->m_extract(v);
!       typename hashtable::hash_code_t code = this->m_hash_code(k);
!       size_type n = this->bucket_index(k, code, m_bucket_count);
!       
!       if (node* p = find_node(m_buckets[n], k, code))
! 	return std::make_pair(iterator(p, m_buckets + n), false);
! 
!       std::pair<bool, size_t> do_rehash
  	= m_rehash_policy.need_rehash(m_bucket_count, m_element_count, 1);
  
        // Allocate the new node before doing the rehash so that we don't
        // do a rehash if the allocation throws.
!       node* new_node = m_allocate_node (v);
!       
        try
  	{
  	  if (do_rehash.first)
  	    {
  	      n = this->bucket_index(k, code, do_rehash.second);
  	      m_rehash(do_rehash.second);
  	    }
--- 1649,1685 ----
  	   bool c, bool ci, bool u>
      typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::node* 
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     m_find_node(node* p, const key_type& k,
! 		typename hashtable::hash_code_t code) const
      {
!       for (; p; p = p->m_next)
! 	if (this->compare(k, code, p))
  	  return p;
        return false;
      }
  
!   // Insert v in bucket n (assumes no element with its key already present).
    template<typename K, typename V, 
  	   typename A, typename Ex, typename Eq,
  	   typename H1, typename H2, typename H, typename RP,
  	   bool c, bool ci, bool u>
!     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     m_insert_bucket(const value_type& v, size_type n,
! 		    typename hashtable::hash_code_t code)
      {
!       std::pair<bool, std::size_t> do_rehash
  	= m_rehash_policy.need_rehash(m_bucket_count, m_element_count, 1);
  
        // Allocate the new node before doing the rehash so that we don't
        // do a rehash if the allocation throws.
!       node* new_node = m_allocate_node(v);
! 
        try
  	{
  	  if (do_rehash.first)
  	    {
+ 	      const key_type& k = this->m_extract(v);
  	      n = this->bucket_index(k, code, do_rehash.second);
  	      m_rehash(do_rehash.second);
  	    }
*************** namespace tr1
*** 1680,1694 ****
  	  this->store_code(new_node, code);
  	  m_buckets[n] = new_node;
  	  ++m_element_count;
! 	  return std::make_pair(iterator(new_node, m_buckets + n), true);
  	}
!       catch (...)
  	{
! 	  m_deallocate_node (new_node);
  	  __throw_exception_again;
  	}
      }
!   
    // Insert v unconditionally.
    template<typename K, typename V, 
  	   typename A, typename Ex, typename Eq,
--- 1688,1721 ----
  	  this->store_code(new_node, code);
  	  m_buckets[n] = new_node;
  	  ++m_element_count;
! 	  return iterator(new_node, m_buckets + n);
  	}
!       catch(...)
  	{
! 	  m_deallocate_node(new_node);
  	  __throw_exception_again;
  	}
      }
! 
!   // Insert v if no element with its key is already present.
!   template<typename K, typename V, 
! 	   typename A, typename Ex, typename Eq,
! 	   typename H1, typename H2, typename H, typename RP,
! 	   bool c, bool ci, bool u>
!     std::pair<typename hashtable<K, V, A, Ex, Eq, H1,
! 				 H2, H, RP, c, ci, u>::iterator, bool>
!     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     m_insert(const value_type& v, std::tr1::true_type)
!     {
!       const key_type& k = this->m_extract(v);
!       typename hashtable::hash_code_t code = this->m_hash_code(k);
!       size_type n = this->bucket_index(k, code, m_bucket_count);
! 
!       if (node* p = m_find_node(m_buckets[n], k, code))
! 	return std::make_pair(iterator(p, m_buckets + n), false);
!       return std::make_pair(m_insert_bucket(v, n, code), true);
!     }
! 
    // Insert v unconditionally.
    template<typename K, typename V, 
  	   typename A, typename Ex, typename Eq,
*************** namespace tr1
*** 1696,1702 ****
  	   bool c, bool ci, bool u>
      typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     insert(const value_type& v, std::tr1::false_type)
      {
        std::pair<bool, std::size_t> do_rehash
  	= m_rehash_policy.need_rehash(m_bucket_count, m_element_count, 1);
--- 1723,1729 ----
  	   bool c, bool ci, bool u>
      typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     m_insert(const value_type& v, std::tr1::false_type)
      {
        std::pair<bool, std::size_t> do_rehash
  	= m_rehash_policy.need_rehash(m_bucket_count, m_element_count, 1);
*************** namespace tr1
*** 1706,1714 ****
        const key_type& k = this->m_extract(v);
        typename hashtable::hash_code_t code = this->m_hash_code(k);
        size_type n = this->bucket_index(k, code, m_bucket_count);
!       
!       node* new_node = m_allocate_node (v);
!       node* prev = find_node(m_buckets[n], k, code);
        if (prev)
  	{
  	  new_node->m_next = prev->m_next;
--- 1733,1743 ----
        const key_type& k = this->m_extract(v);
        typename hashtable::hash_code_t code = this->m_hash_code(k);
        size_type n = this->bucket_index(k, code, m_bucket_count);
! 
!       // First find the node, avoid leaking new_node if compare throws.
!       node* prev = m_find_node(m_buckets[n], k, code);
!       node* new_node = m_allocate_node(v);
! 
        if (prev)
  	{
  	  new_node->m_next = prev->m_next;
*************** namespace tr1
*** 1732,1738 ****
  	   bool c, bool ci, bool u>
      void
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     erase_node(node* p, node** b)
      {
        node* cur = *b;
        if (cur == p)
--- 1761,1767 ----
  	   bool c, bool ci, bool u>
      void
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     m_erase_node(node* p, node** b)
      {
        node* cur = *b;
        if (cur == p)
*************** namespace tr1
*** 1748,1754 ****
  	  cur->m_next = next->m_next;
  	}
  
!       m_deallocate_node (p);
        --m_element_count;
      }
  
--- 1777,1783 ----
  	  cur->m_next = next->m_next;
  	}
  
!       m_deallocate_node(p);
        --m_element_count;
      }
  
*************** namespace tr1
*** 1761,1774 ****
        hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
        insert(InIter first, InIter last)
        {
! 	size_type n_elt = Internal::distance_fw (first, last);
  	std::pair<bool, std::size_t> do_rehash
  	  = m_rehash_policy.need_rehash(m_bucket_count, m_element_count, n_elt);
  	if (do_rehash.first)
  	  m_rehash(do_rehash.second);
  
  	for (; first != last; ++first)
! 	  this->insert (*first);
        }
  
    template<typename K, typename V, 
--- 1790,1803 ----
        hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
        insert(InIter first, InIter last)
        {
! 	size_type n_elt = Internal::distance_fw(first, last);
  	std::pair<bool, std::size_t> do_rehash
  	  = m_rehash_policy.need_rehash(m_bucket_count, m_element_count, n_elt);
  	if (do_rehash.first)
  	  m_rehash(do_rehash.second);
  
  	for (; first != last; ++first)
! 	  this->insert(*first);
        }
  
    template<typename K, typename V, 
*************** namespace tr1
*** 1777,1787 ****
  	   bool c, bool ci, bool u>
      typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     erase(iterator i)
      {
!       iterator result = i;
        ++result;
!       erase_node(i.m_cur_node, i.m_cur_bucket);
        return result;
      }
    
--- 1806,1816 ----
  	   bool c, bool ci, bool u>
      typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     erase(iterator it)
      {
!       iterator result = it;
        ++result;
!       m_erase_node(it.m_cur_node, it.m_cur_bucket);
        return result;
      }
    
*************** namespace tr1
*** 1791,1801 ****
  	   bool c, bool ci, bool u>
      typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::const_iterator
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     erase(const_iterator i)
      {
!       const_iterator result = i;
        ++result;
!       erase_node(i.m_cur_node, i.m_cur_bucket);
        return result;
      }
  
--- 1820,1830 ----
  	   bool c, bool ci, bool u>
      typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::const_iterator
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     erase(const_iterator it)
      {
!       const_iterator result = it;
        ++result;
!       m_erase_node(it.m_cur_node, it.m_cur_bucket);
        return result;
      }
  
*************** namespace tr1
*** 1812,1825 ****
        size_type result = 0;
        
        node** slot = m_buckets + n;
!       while (*slot && ! this->compare(k, code, *slot))
  	slot = &((*slot)->m_next);
  
        while (*slot && this->compare(k, code, *slot))
  	{
! 	  node* n = *slot;
! 	  *slot = n->m_next;
! 	  m_deallocate_node (n);
  	  --m_element_count;
  	  ++result;
  	}
--- 1841,1854 ----
        size_type result = 0;
        
        node** slot = m_buckets + n;
!       while (*slot && !this->compare(k, code, *slot))
  	slot = &((*slot)->m_next);
  
        while (*slot && this->compare(k, code, *slot))
  	{
! 	  node* p = *slot;
! 	  *slot = p->m_next;
! 	  m_deallocate_node(p);
  	  --m_element_count;
  	  ++result;
  	}
*************** namespace tr1
*** 1887,1917 ****
  	   bool c, bool ci, bool u>
      void
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     m_rehash(size_type N)
      {
!       node** new_array = m_allocate_buckets (N);
        try
  	{
  	  for (size_type i = 0; i < m_bucket_count; ++i)
  	    while (node* p = m_buckets[i])
  	      {
! 		size_type new_index = this->bucket_index (p, N);
  		m_buckets[i] = p->m_next;
  		p->m_next = new_array[new_index];
  		new_array[new_index] = p;
  	      }
  	  m_deallocate_buckets(m_buckets, m_bucket_count);
! 	  m_bucket_count = N;
  	  m_buckets = new_array;
  	}
!       catch (...)
  	{
  	  // A failure here means that a hash function threw an exception.
  	  // We can't restore the previous state without calling the hash
  	  // function again, so the only sensible recovery is to delete
  	  // everything.
! 	  m_deallocate_nodes(new_array, N);
! 	  m_deallocate_buckets(new_array, N);
  	  m_deallocate_nodes(m_buckets, m_bucket_count);
  	  m_element_count = 0;
  	  __throw_exception_again;
--- 1916,1946 ----
  	   bool c, bool ci, bool u>
      void
      hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
!     m_rehash(size_type n)
      {
!       node** new_array = m_allocate_buckets(n);
        try
  	{
  	  for (size_type i = 0; i < m_bucket_count; ++i)
  	    while (node* p = m_buckets[i])
  	      {
! 		size_type new_index = this->bucket_index(p, n);
  		m_buckets[i] = p->m_next;
  		p->m_next = new_array[new_index];
  		new_array[new_index] = p;
  	      }
  	  m_deallocate_buckets(m_buckets, m_bucket_count);
! 	  m_bucket_count = n;
  	  m_buckets = new_array;
  	}
!       catch(...)
  	{
  	  // A failure here means that a hash function threw an exception.
  	  // We can't restore the previous state without calling the hash
  	  // function again, so the only sensible recovery is to delete
  	  // everything.
! 	  m_deallocate_nodes(new_array, n);
! 	  m_deallocate_buckets(new_array, n);
  	  m_deallocate_nodes(m_buckets, m_bucket_count);
  	  m_element_count = 0;
  	  __throw_exception_again;
diff -Nrcpad gcc-4.1.1/libstdc++-v3/libsupc++/cxxabi.h gcc-4.1.2/libstdc++-v3/libsupc++/cxxabi.h
*** gcc-4.1.1/libstdc++-v3/libsupc++/cxxabi.h	Wed Aug 17 02:28:44 2005
--- gcc-4.1.2/libstdc++-v3/libsupc++/cxxabi.h	Wed Oct 11 08:30:42 2006
***************
*** 1,6 ****
  // new abi support -*- C++ -*-
    
! // Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
  //
  // This file is part of GCC.
  //
--- 1,6 ----
  // new abi support -*- C++ -*-
    
! // Copyright (C) 2000, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
  //
  // This file is part of GCC.
  //
***************
*** 54,65 ****
  #ifdef __cplusplus
  namespace __cxxabiv1
  {  
-   typedef __cxa_cdtor_return_type (*__cxa_cdtor_type)(void *);
- 
    extern "C" 
    {
  #endif
  
    // Allocate array.
    void* 
    __cxa_vec_new(size_t __element_count, size_t __element_size, 
--- 54,65 ----
  #ifdef __cplusplus
  namespace __cxxabiv1
  {  
    extern "C" 
    {
  #endif
  
+   typedef __cxa_cdtor_return_type (*__cxa_cdtor_type)(void *);
+ 
    // Allocate array.
    void* 
    __cxa_vec_new(size_t __element_count, size_t __element_size, 
diff -Nrcpad gcc-4.1.1/libstdc++-v3/src/debug.cc gcc-4.1.2/libstdc++-v3/src/debug.cc
*** gcc-4.1.1/libstdc++-v3/src/debug.cc	Fri Sep  9 10:14:55 2005
--- gcc-4.1.2/libstdc++-v3/src/debug.cc	Mon Nov 13 09:22:36 2006
*************** namespace __gnu_debug
*** 146,168 ****
  	  __old->_M_attach(0, true);
        }
    }
!   
!   void 
    _Safe_sequence_base::
    _M_revalidate_singular()
    {
!     _Safe_iterator_base* __iter;
!     for (__iter = _M_iterators; __iter; __iter = __iter->_M_next)
!       {
! 	__iter->_M_version = _M_version;
! 	__iter = __iter->_M_next;
!       }
!     
!     for (__iter = _M_const_iterators; __iter; __iter = __iter->_M_next)
!       {
! 	__iter->_M_version = _M_version;
! 	__iter = __iter->_M_next;
!       }
    }
  
    void 
--- 146,163 ----
  	  __old->_M_attach(0, true);
        }
    }
! 
!   void
    _Safe_sequence_base::
    _M_revalidate_singular()
    {
!     for (_Safe_iterator_base* __iter = _M_iterators; __iter;
! 	 __iter = __iter->_M_next)
!       __iter->_M_version = _M_version;
! 
!     for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;
! 	 __iter2 = __iter2->_M_next)
!       __iter2->_M_version = _M_version;
    }
  
    void 
diff -Nrcpad gcc-4.1.1/libstdc++-v3/testsuite/26_numerics/complex/13450.cc gcc-4.1.2/libstdc++-v3/testsuite/26_numerics/complex/13450.cc
*** gcc-4.1.1/libstdc++-v3/testsuite/26_numerics/complex/13450.cc	Wed Aug 17 02:28:44 2005
--- gcc-4.1.2/libstdc++-v3/testsuite/26_numerics/complex/13450.cc	Tue Nov 14 16:03:15 2006
*************** void test01()
*** 61,66 ****
--- 61,71 ----
    d2 = 1.4;
    test01_do(d1, d2);
  
+ #if __LDBL_MANT_DIG__ != 106
+   /* For IBM long double, epsilon is too small (since 1.0 plus any
+      double is representable) to be able to expect results within
+      epsilon * 100 (which may be much less than 1ulp for a particular
+      long double value).  */
    long double ld1 = -1.0l;
    long double ld2 = 0.5l;
    test01_do(ld1, ld2);
*************** void test01()
*** 68,73 ****
--- 73,79 ----
    ld1 = -3.2l;
    ld2 = 1.4l;
    test01_do(ld1, ld2);
+ #endif
  }
  
  int main()
diff -Nrcpad gcc-4.1.1/libstdc++-v3/testsuite/27_io/basic_stringbuf/seekpos/char/29354.cc gcc-4.1.2/libstdc++-v3/testsuite/27_io/basic_stringbuf/seekpos/char/29354.cc
*** gcc-4.1.1/libstdc++-v3/testsuite/27_io/basic_stringbuf/seekpos/char/29354.cc	Thu Jan  1 00:00:00 1970
--- gcc-4.1.2/libstdc++-v3/testsuite/27_io/basic_stringbuf/seekpos/char/29354.cc	Fri Oct  6 09:58:03 2006
***************
*** 0 ****
--- 1,44 ----
+ // Copyright (C) 2006 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ // USA.
+ 
+ #include <sstream>
+ #include <testsuite_hooks.h>
+ 
+ // libstdc++/29354
+ void test01()
+ {
+   bool test __attribute__((unused)) = true;
+   using namespace std;
+   typedef stringbuf::pos_type pos_type;
+   typedef stringbuf::off_type off_type;
+ 
+   stringbuf strb_01(ios_base::out);
+ 
+   pos_type pt_1 = strb_01.pubseekoff(0, ios_base::cur, ios_base::out);
+   VERIFY( pt_1 == pos_type(off_type(0)) );  
+ 
+   pos_type pt_2 = strb_01.pubseekpos(pt_1, ios_base::out);
+   VERIFY( pt_2 == pos_type(off_type(0)) );
+ }
+ 
+ int
+ main()
+ {
+   test01();
+   return 0;
+ }
diff -Nrcpad gcc-4.1.1/libstdc++-v3/testsuite/27_io/basic_stringbuf/seekpos/wchar_t/29354.cc gcc-4.1.2/libstdc++-v3/testsuite/27_io/basic_stringbuf/seekpos/wchar_t/29354.cc
*** gcc-4.1.1/libstdc++-v3/testsuite/27_io/basic_stringbuf/seekpos/wchar_t/29354.cc	Thu Jan  1 00:00:00 1970
--- gcc-4.1.2/libstdc++-v3/testsuite/27_io/basic_stringbuf/seekpos/wchar_t/29354.cc	Fri Oct  6 09:58:03 2006
***************
*** 0 ****
--- 1,44 ----
+ // Copyright (C) 2006 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ // USA.
+ 
+ #include <sstream>
+ #include <testsuite_hooks.h>
+ 
+ // libstdc++/29354
+ void test01()
+ {
+   bool test __attribute__((unused)) = true;
+   using namespace std;
+   typedef stringbuf::pos_type pos_type;
+   typedef stringbuf::off_type off_type;
+ 
+   wstringbuf strb_01(ios_base::out);
+ 
+   pos_type pt_1 = strb_01.pubseekoff(0, ios_base::cur, ios_base::out);
+   VERIFY( pt_1 == pos_type(off_type(0)) );  
+ 
+   pos_type pt_2 = strb_01.pubseekpos(pt_1, ios_base::out);
+   VERIFY( pt_2 == pos_type(off_type(0)) );
+ }
+ 
+ int
+ main()
+ {
+   test01();
+   return 0;
+ }
diff -Nrcpad gcc-4.1.1/libstdc++-v3/testsuite/ext/pb_assoc/example/mapping_level_neg.cc gcc-4.1.2/libstdc++-v3/testsuite/ext/pb_assoc/example/mapping_level_neg.cc
*** gcc-4.1.1/libstdc++-v3/testsuite/ext/pb_assoc/example/mapping_level_neg.cc	Wed Aug 17 02:28:44 2005
--- gcc-4.1.2/libstdc++-v3/testsuite/ext/pb_assoc/example/mapping_level_neg.cc	Sun Dec 10 23:48:13 2006
*************** main()
*** 77,83 ****
     * t1 is a "map" type, and cannot be rebound.
     **/
  
!   typedef t_1::rebind<1>::other t_1_rebound; // { dg-error "expected" }
  }
  
  
--- 77,83 ----
     * t1 is a "map" type, and cannot be rebound.
     **/
  
!   typedef t_1::rebind<1>::other t_1_rebound; // { dg-error "parameter-lists" }
  }
  
  
diff -Nrcpad gcc-4.1.1/libstdc++-v3/testsuite/performance/23_containers/insert/unordered_map_array.cc gcc-4.1.2/libstdc++-v3/testsuite/performance/23_containers/insert/unordered_map_array.cc
*** gcc-4.1.1/libstdc++-v3/testsuite/performance/23_containers/insert/unordered_map_array.cc	Thu Jan  1 00:00:00 1970
--- gcc-4.1.2/libstdc++-v3/testsuite/performance/23_containers/insert/unordered_map_array.cc	Fri May 26 11:15:23 2006
***************
*** 0 ****
--- 1,61 ----
+ // Copyright (C) 2006 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ // USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ #include <tr1/unordered_map>
+ #include <testsuite_performance.h>
+ 
+ typedef std::tr1::unordered_map<int, int> map_type;
+ typedef std::tr1::unordered_map<int, map_type> matrix_type;
+ 
+ int main()
+ {
+   using namespace __gnu_test;
+ 
+   time_counter time;
+   resource_counter resource;
+ 
+   const int sz = 1000;
+ 
+   matrix_type matrix;
+ 
+   start_counters(time, resource);
+   for (int iter = 0; iter < 50; ++iter)
+     {
+       for (int i = 0; i < sz; ++i)
+ 	{
+ 	  for (int j = 0; j < sz; ++j)
+ 	    {
+ 	      map_type& row = matrix[i / 4];
+ 	      ++row[j / 4];
+ 	    }
+ 	}
+     }
+   stop_counters(time, resource);
+   report_performance(__FILE__, "", time, resource);
+ 
+   return 0;
+ }
diff -Nrcpad gcc-4.1.1/libstdc++-v3/testsuite/testsuite_hooks.cc gcc-4.1.2/libstdc++-v3/testsuite/testsuite_hooks.cc
*** gcc-4.1.1/libstdc++-v3/testsuite/testsuite_hooks.cc	Mon Jan  9 00:45:57 2006
--- gcc-4.1.2/libstdc++-v3/testsuite/testsuite_hooks.cc	Fri Dec  8 10:11:00 2006
*************** namespace __gnu_test
*** 89,94 ****
--- 89,104 ----
  #endif
  
      // Virtual memory.
+     // On x86_64-linux, the default is -z max-page-size=0x200000
+     // which means up to 2MB of address space are accounted for
+     // PROT_NONE mappings between text and data segments of
+     // each shared library.  There are 4 shared libs involved
+     // in addition to the dynamic linker.  Use at least 16MB address space
+     // limit.
+ #if defined(__x86_64__) && defined(__linux__)
+     if (limit < 16777216)
+       limit = 16777216;
+ #endif
      // On HP-UX 11.23, a trivial C++ program that sets RLIMIT_AS to
      // anything less than 128MB cannot "malloc" even 1K of memory.
      // Therefore, we skip RLIMIT_AS on HP-UX.
diff -Nrcpad gcc-4.1.1/libstdc++-v3/testsuite/tr1/6_containers/array/capacity/max_size.cc gcc-4.1.2/libstdc++-v3/testsuite/tr1/6_containers/array/capacity/max_size.cc
*** gcc-4.1.1/libstdc++-v3/testsuite/tr1/6_containers/array/capacity/max_size.cc	Wed Aug 17 02:28:44 2005
--- gcc-4.1.2/libstdc++-v3/testsuite/tr1/6_containers/array/capacity/max_size.cc	Mon Oct 30 18:59:33 2006
***************
*** 1,6 ****
  // 2004-10-20  Benjamin Kosnik  <bkoz@redhat.com>
  //
! // Copyright (C) 2004 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
--- 1,6 ----
  // 2004-10-20  Benjamin Kosnik  <bkoz@redhat.com>
  //
! // Copyright (C) 2004, 2005, 2006 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
*************** test01() 
*** 32,38 ****
      bool test __attribute__((unused)) = true;
      array_type a = { 0, 1, 2, 3, 4 };
      
!     VERIFY( a.size() == len );
    }
  
    {
--- 32,38 ----
      bool test __attribute__((unused)) = true;
      array_type a = { 0, 1, 2, 3, 4 };
      
!     VERIFY( a.max_size() == len );
    }
  
    {
*************** test01() 
*** 41,47 ****
      bool test __attribute__((unused)) = true;
      array_type a;
      
!     VERIFY( a.size() == len );
    }
  }
  
--- 41,47 ----
      bool test __attribute__((unused)) = true;
      array_type a;
      
!     VERIFY( a.max_size() == len );
    }
  }
  
*************** int main()
*** 50,53 ****
    test01();
    return 0;
  }
- 
--- 50,52 ----
diff -Nrcpad gcc-4.1.1/libstdc++-v3/testsuite/tr1/6_containers/array/element_access/at_out_of_range.cc gcc-4.1.2/libstdc++-v3/testsuite/tr1/6_containers/array/element_access/at_out_of_range.cc
*** gcc-4.1.1/libstdc++-v3/testsuite/tr1/6_containers/array/element_access/at_out_of_range.cc	Wed Aug 17 02:28:44 2005
--- gcc-4.1.2/libstdc++-v3/testsuite/tr1/6_containers/array/element_access/at_out_of_range.cc	Sat Oct 28 22:03:17 2006
***************
*** 1,6 ****
  // 2004-10-20  Benjamin Kosnik  <bkoz@redhat.com>
  //
! // Copyright (C) 2004 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
--- 1,6 ----
  // 2004-10-20  Benjamin Kosnik  <bkoz@redhat.com>
  //
! // Copyright (C) 2004, 2005, 2006 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
***************
*** 22,27 ****
--- 22,28 ----
  
  #include <tr1/array>
  #include <stdexcept>
+ #include <testsuite_hooks.h>
  
  void
  test01() 
*************** test01() 
*** 34,48 ****
    try
      {
        a.at(len);
      }
    catch(std::out_of_range& obj)
      {
        // Expected.
      }
    catch(...)
      {
        // Failed.
!       throw;
      }
  }
  
--- 35,51 ----
    try
      {
        a.at(len);
+       VERIFY( false );
      }
    catch(std::out_of_range& obj)
      {
        // Expected.
+       VERIFY( true );
      }
    catch(...)
      {
        // Failed.
!       VERIFY( false );
      }
  }
  
*************** int main()
*** 51,54 ****
    test01();
    return 0;
  }
- 
--- 54,56 ----
