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 + + PR target/29487 + * decl.c (finish_function): Use DECL_REPLACEABLE. + * tree.c (cp_cannot_inline_tree_fn): Likewise. + + 2007-01-28 Andrew Pinski + + PR C++/28988 + * semantics.c (finish_pseudo_destructor_expr): Check the + destrutor name by calling check_dtor_name. + + 2007-01-10 Mark Mitchell + + PR c++/28999 + * decl.c (make_typename_type): If the qualified name is not a + type, issue an error. + + 2007-01-05 Jakub Jelinek + + PR c++/30382 + Backported from mainline + 2006-06-29 Jason Merrill + * parser.c (cp_parser_enum_specifier): Return early if + type is error_mark_node. + + 2007-01-03 Jakub Jelinek + + Backported from mainline + 2006-07-12 Jason Merrill + PR c++/28217 + * semantics.c (note_decl_for_pch): Don't premangle templates. + + 2007-01-03 Jakub Jelinek + + 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 + 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 + + 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 + + PR c++/29730 + * parser.c (cp_parser_init_declarator): Reject initialization of + functions. + + 2006-12-05 Mark Mitchell + + 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 + + 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 + Andrew Pinski + + PR C++/14329 + * error.c (cp_printer) <'D'>: Handle DECL_DEBUG_EXPR. + + 2006-12-04 Mark Mitchell + + 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 + + Backport: + 2006-08-27 Simon Martin + + PR c++/28284 + * pt.c (fold_non_dependent_expr): Make sure expr is not dereferenced if it + is NULL. + + 2006-12-01 Volker Reichelt + + 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 + + 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 + + PR c++/29735 + * decl.c (grokfndecl): Check main's type after applying + attributes, not before. + + 2006-11-26 Mark Mitchell + + 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 + + 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 + + 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 + + PR c++/20647 + * rtti.c (tinfo_base_init): The type info string is always global. + + 2006-10-18 Mark Shinwell + + PR c++/26884 + * typeck2.c (digest_init): Raise error upon attempts to + initialize arrays with variables. + + 2006-10-18 Richard Guenther + + PR C++/25878 + Backport from mainline: + 2006-08-25 Nathan Sidwell + + 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 + + Backport from mainline: + 2006-09-07 Andrew Pinski + + 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 + + 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 + + PR c++/29408 + * parser.c (cp_parser_using_declaration): Stop parsing when + something goes wrong with an access declaration. + + 2006-10-14 Richard Guenther + + PR rtl-optimization/29323 + * decl.c (finish_function): Set TREE_NOTHROW only for + functions that bind local. + + 2006-10-13 Mark Mitchell + + 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 + + PR c++/29318 + * rtti.c (get_tinfo_decl): Refuse to create type info objects for + variably modified types. + + 2006-10-12 Mark Mitchell + + PR c++/29175 + * decl.c (check_initializer): Issue errors about trying to + initialize arrays whose elements have variable size. + + 2006-10-07 Andrew Pinski + + 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 + + PR c++/28302 + * typeck.c (build_unary_op ): Don't call + perform_integral_promotions for non integral type + + 2006-10-06 Andrew Pinski + + PR C++/28450 + * cp/init.c (build_zero_init): Handle VECTOR_TYPE and + COMPLEX_TYPEs. + + 2006-10-05 Andrew Pinski + + 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 + + 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 + + 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 + + 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 + + PR c++/28996 + * cvt.c (convert_to_void): Strip COMPONENT_REF to functions. + + 2006-09-21 Steven Bosscher + + 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 + + PR c++/26957 + * method.c (use_thunk): Clear DECL_HAS_VALUE_EXPR_P on copied + parms. + + 2006-09-06 Mark Mitchell + + PR c++/28886 + * pt.c (unify): Avoid unnecessary calls to fold_build2 for array + dimensions. + + 2006-09-06 Zak Kipling + + 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 + + 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 + + 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 + + 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 + + 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 + + PR c++/26577 + * cvt.c (convert_to_void): Don't automatically load from volatiles + of TREE_ADDRESSABLE type. + + 2006-08-28 Volker Reichelt + + 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 + + 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 + + PR c++/28595 + * pt.c (tsubst): Issue errors about attempts to create VLAs at + template-instantiation time. + + 2006-08-25 Volker Reichelt + + 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 + + PR c++/28056 + * decl.c (grokdeclarator): Disallow declarations with qualified + names in local scopes. + + 2006-08-23 Jason Merrill + + PR c++/27714 + * pt.c (push_template_decl_real): A friend template with class + scope isn't primary. + + 2006-08-22 Jason Merrill + + 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 + + PR c++/28346 + * pt.c (tsubst_qualified_id): Do not strip references from + OFFSET_REFs. + + 2006-08-17 Jason Merrill + + PR c++/28385 + * pt.c (tsubst) [TEMPLATE_TYPE_PARM]: Ignore quals from template + if arg is a function. + + 2006-08-17 Volker Reichelt + + 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 + + PR c++/28593 + * init.c (build_new): Return early on invalid placement. + + 2006-08-13 Jakub Jelinek + + 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 + + PR c++/28594 + PR c++/28637 + PR c++/28638 + PR c++/28639 + PR c++/28640 + PR c++/28641 + + Revert + 2006-07-28 Lee Millward + + 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 + + * pt.c (coerce_template_parms): Fix misplaced parenthesis. + + 2006-08-03 Lee Millward + + 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 + + PR c++/28432 + * decl2.c (check_classfn): Remove early return. + * search.c (lookup_member): Return NULL with bad type. + + 2006-08-03 Steve Ellcey + + PR c++/28256 + * decl.c (check_initializer): Check for 1 initializer on scalar types. + + 2006-08-03 Volker Reichelt + + 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 + + PR c++/28557 + * pt.c (tsubst_baselink): Substitute into BASELINK_OPTYPE. + + 2006-07-31 Mark Mitchell + + 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 + + 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 + + PR c++/27572 + * decl.c (grokdeclarator): Return error_mark_node after invalid + typedef. + + 2006-07-23 Mark Mitchell + + 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 + + PR c++/28258 + * method.c (locate_copy): Check for non_reference + returning error_mark_node. + + 2006-07-21 Volker Reichelt + + PR c++/28363 + * semantics.c (check_template_template_default_arg): Simplify + error handling. + + 2006-07-20 Steve Ellcey + + PR c++/27495 + * search.c (adjust_result_of_qualified_name_lookup): Change + assert to part of if statement. + + 2006-07-19 Mark Mitchell + + 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 + + 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 + + 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 + + PR c++/28291 + * decl.c (reshape_init_class): Return error_mark_node on error. + + 2006-07-18 Steve Ellcey + + PR c++/28304 + * decl2.c (check_classfn): Return NULL_TREE on error. + + 2006-07-15 Volker Reichelt + + 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 + + PR c++/28343 + * decl.c (cp_finish_decl): Check asmspec_tree for error_mark_node. + * decl2.c (grokfield): Likewise. + + 2006-06-16 Mark Mitchell + + PR c++/28016 + * decl.c (cp_finsh_decl): Do not emit uninstantiated static data + members. + + 2006-07-11 Lee Millward + + 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 + + PR c++/27019 + * typeck2.c (process_init_constructor_array): Set ce->value on errors. + + 2006-07-10 Steve Ellcey + + PR c++/28114 + * name-lookup.c (pushtag): Return if we have error_mark_node. + + 2006-07-08 Lee Millward + Andrew Pinski + + 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 + + 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 + + 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 + + PR c++/27424 + * pt.c (convert_template_argument): Pass all template arguments + on to coerce_template_template_parms. + + 2006-06-25 Lee Millward + + PR c++/27821 + * decl.c (grokdeclarator): Return error_mark_node on + invalid uses of the scope resolution operator. + + 2006-06-23 Volker Reichelt + + PR c++/28112 + * parser.c (cp_parser_attribute_list): Skip attributes with invalid + arguments. Fix comment. + + 2006-06-22 Volker Reichelt + + PR c++/28110 + * pt.c (unify) : Check for invalid + parameters. + + PR c++/28109 + * rtti.c (get_tinfo_decl_dynamic): Robustify. + + 2006-06-16 Mark Mitchell + + 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 + + PR c++/27689 + * cp-tree.h (CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P): New + macro. + * pt.c (unify): Use it. + + 2006-06-15 Mark Mitchell + + PR c++/27666 + * call.c (build_conditional_expr): Robustify. + + 2006-06-15 Mark Mitchell + + 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 + + PR c++/27648 + * parser.c (cp_parser_declarator): Robustify. + + 2006-06-14 Mark Mitchell + + PR c++/26559 + * pt.c (value_dependent_expression_p): All CALL_EXPRs are dependent. + + 2006-06-13 Mark Mitchell + + 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 + + * cp-tree.def: Fix typo. + + 2006-06-13 Roger Sayle + + 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + PR c++/20173 + * pt.c (determine_specialization): Disallow partial + specializations of templates. + + 2006-05-29 Volker Reichelt + + 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 %", 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 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 struct S { friend void f(T) {} }; *************** extern void decl_shadowed_for_var_insert *** 2088,2094 **** In this case, S::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::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::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 struct S {}; + template struct S {}; + + the CLASSTPYE_TI_TEMPLATE for S will be S, not the S. */ #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); ! 3=explicit template instantiation, e.g. template int min (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), ! ! 3=explicit instantiation, e.g.: ! ! template int min (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 struct O { ! void f(); ! struct I {}; ! }; ! ! both O::f and O::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 ("% 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 ("% 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 %"); - 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 %"); + 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 ("% is too long for GCC"); + else if (pedantic && !in_system_header && warn_long_long) + pedwarn ("ISO C++ does not support %"); + } + 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::B::C' may have resulted in a nested-name-specifier - of `A::', where it should now be `A::B::'. 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 %"); - 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 %"); - 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 ("% is too long for GCC"); ! else if (pedantic && !in_system_header && warn_long_long) ! pedwarn ("ISO C++ does not support %"); ! } ! 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 ... A::", A is the abstract A ! template (rather than some instantiation thereof) only if ! is not nested within some other construct. For example, in ! "template void f(T) { A::", A 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 = ¶meters; + 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::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::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 friend void A::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 friend class F; ! }; ! template struct B { ! template 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 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 void g() { T t; } + template void g(); + + 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 + 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 % 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 % 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 + + Revert. + 2006-12-11 Benjamin Kosnik + 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 + + PR libstdc++/30586 + * config/cpu/ia64/atomic_word.h: Just include . + + * configure.host (atomic_word_dir): Cover alpha, ia64 and powerpc. + + 2007-01-13 John David Anglin + + * config/cpu/hppa/atomicity.h (__exchange_and_add): Don't use ordered + store. + (__atomic_add): Likewise. + + 2006-12-12 Benjamin Kosnik + + PR libstdc++/28265 + * crossconfig.m4: Remove GLIBCXX_CHECK_ICONV_SUPPORT call for + mingw crosses. + * configure: Regenerate. + + 2006-12-12 Benjamin Kosnik + + 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 + + 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 + + PR c++/29732 + * testsuite/ext/pb_assoc/example/mapping_level_neg.cc: Tweak error + markers. + + 2006-12-08 Jakub Jelinek + + * testsuite/testsuite_hooks.cc (set_memory_limits): Don't set + RLIMIT_AS below 16MB on x86_64-linux. + + 2006-11-18 Joseph Myers + + * config/cpu/powerpc/atomic_word.h (_GLIBCXX_WRITE_MEM_BARRIER): + Use plain sync if __NO_LWSYNC__. + + 2006-11-14 Joseph Myers + + * testsuite/26_numerics/complex/13450.cc: Do not test long double + in IBM long double case. + + 2006-11-13 Paolo Carlini + + * src/debug.cc (_Safe_sequence_base::_M_revalidate_singular): Fix + pasto, advance __iter only once per iteration. + + 2006-11-10 Jakub Jelinek + + * config/locale/gnu/c_locale.cc (__convert_to_v): Prefer + strtold_l over __strtold_l if available. + + 2006-10-30 Paolo Carlini + + * testsuite/tr1/6_containers/array/capacity/max_size.cc: Actually + do test max_size(). + + 2006-10-28 Paolo Carlini + + * 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 + + * include/bits/basic_string.tcc (_Rep::_S_create): Call + _M_set_sharable() for backwards compatibility. + + 2006-10-09 Benjamin Kosnik + + 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 + + PR libstdc++/29368 + * include/bits/basic_string.h: Adjust rfind documentation. + * include/ext/vstring.h: Likewise. + + 2006-10-06 Paolo Carlini + + 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 + + * acinclude.m4 (enable_symvers): Default to no if unable to link. + * configure: Regenerate. + + 2006-09-25 Howard Hinnant + + PR libstdc++/29224 + * include/tr1/functional_iterate.h: Avoid -Wshadow warnings. + + 2006-09-25 Paolo Carlini + + PR libstdc++/29179 + * include/ext/mt_allocator.h (__pool_base): Adjust/extend + documentation in comments. + + 2006-08-18 Paolo Carlini + + 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 + + * 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 + Paolo Carlini + + * 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 + + * 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 + + * include/tr1/hashtable: Minor cosmetic changes. + + 2006-05-26 Paolo Carlini + + * 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 + + * 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 typedef int _Atomic_word; --- 30,36 ---- #ifndef _GLIBCXX_ATOMIC_WORD_H #define _GLIBCXX_ATOMIC_WORD_H 1 ! #include 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 - _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 - _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 - _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 - _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 declares $ac_func. - For example, HP-UX 11i 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 to if __STDC__ is defined, since - exists even on freestanding compilers. */ - - #ifdef __STDC__ - # include - #else - # include - #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 > 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 > 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(-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(-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(-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(-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 struct array { typedef _Tp value_type; --- 47,53 ---- { /// @brief struct array [6.2.2]. /// NB: Requires complete type _Tp. ! template struct array { typedef _Tp value_type; *************** namespace tr1 *** 60,68 **** typedef std::reverse_iterator reverse_iterator; typedef std::reverse_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 + typename std::__enable_if::__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 + typename std::__enable_if::__type + _M_at(size_type) + { + std::__throw_out_of_range("array::_M_at"); + return _M_instance[0]; + } + + template + typename std::__enable_if::__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 + typename std::__enable_if::__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 class tuple_size; template class tuple_element; ! template struct tuple_size > { static const int value = _Nm; }; ! template struct tuple_element<_Int, array<_Tp, _Nm> > { typedef _Tp type; }; --- 237,247 ---- // Tuple interface to class template array [6.2.2.5]. template class tuple_size; template class tuple_element; ! template struct tuple_size > { static const int value = _Nm; }; ! template 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 // // 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 // // This file is part of the GNU ISO C++ Library. This library is free *************** template::primes + X<>::n_primes; ! const unsigned long* p = std::lower_bound (X<>::primes, last, n); m_next_resize = static_cast(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::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::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::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::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::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(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 --- 673,697 ---- typedef typename Pair::second_type mapped_type; mapped_type& ! operator[](const K& k); }; + template + typename map_base, true, Hashtable>::mapped_type& + map_base, true, Hashtable>:: + operator[](const K& k) + { + Hashtable* h = static_cast(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 *************** 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* 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* n) const ! { return m_eq (k, m_extract(n->m_v)); } void store_code(hash_node*, 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* 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* n) const ! { return m_eq(k, m_extract(n->m_v)); } void store_code(hash_node*, 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* 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* n) const ! { return m_eq (k, m_extract(n->m_v)); } void store_code(hash_node*, 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* 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* n) const ! { return m_eq(k, m_extract(n->m_v)); } void store_code(hash_node*, 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* p, std::size_t N) const ! { return m_h2 (p->hash_code, N); } bool compare(const Key& k, hash_code_t c, hash_node* 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* p, std::size_t N) const ! { return m_h2(p->hash_code, N); } bool compare(const Key& k, hash_code_t c, hash_node* n) const *************** namespace tr1 *** 1028,1033 **** --- 1038,1046 ---- cache_hash_code> const_iterator; + template + friend struct Internal::map_base; + private: typedef Internal::hash_node node; typedef typename Allocator::template rebind::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 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 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 ! 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()); ! } 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 ! 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()); } 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(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(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(), Internal::hash_code_base(exk, eq, h1, h2, h), Internal::map_base(), 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(), Internal::hash_code_base(exk, eq, h1, h2, h), Internal::map_base(), 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(), ! Internal::hash_code_base (exk, eq, ! h1, h2, h), ! Internal::map_base(), 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(), ! Internal::hash_code_base(exk, eq, ! h1, h2, h), ! Internal::map_base(), 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 m_bucket_count) ! m_rehash(n_bkt); } templatem_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::node* hashtable:: ! 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 ! std::pair::iterator, bool> hashtable:: ! 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 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::node* hashtable:: ! 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 hashtable::iterator hashtable:: ! m_insert_bucket(const value_type& v, size_type n, ! typename hashtable::hash_code_t code) { ! std::pair 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. templatestore_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 ! std::pair::iterator, bool> ! hashtable:: ! 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 hashtable::iterator hashtable:: ! insert(const value_type& v, std::tr1::false_type) { std::pair do_rehash = m_rehash_policy.need_rehash(m_bucket_count, m_element_count, 1); --- 1723,1729 ---- bool c, bool ci, bool u> typename hashtable::iterator hashtable:: ! m_insert(const value_type& v, std::tr1::false_type) { std::pair 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:: ! erase_node(node* p, node** b) { node* cur = *b; if (cur == p) --- 1761,1767 ---- bool c, bool ci, bool u> void hashtable:: ! 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:: insert(InIter first, InIter last) { ! size_type n_elt = Internal::distance_fw (first, last); std::pair 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:: insert(InIter first, InIter last) { ! size_type n_elt = Internal::distance_fw(first, last); std::pair 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 hashtable::iterator hashtable:: ! 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::iterator hashtable:: ! 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::const_iterator hashtable:: ! 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::const_iterator hashtable:: ! 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:: ! 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:: ! 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 + #include + + // 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 + #include + + // 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 + #include + + typedef std::tr1::unordered_map map_type; + typedef std::tr1::unordered_map 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 // ! // 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 // ! // 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 // ! // 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 // ! // 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 #include + #include 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 ----