diff -Nrcpad gcc-4.0.3/gcc/cp/call.c gcc-4.0.4/gcc/cp/call.c *** gcc-4.0.3/gcc/cp/call.c 2006-01-24 21:44:57.000000000 +0000 --- gcc-4.0.4/gcc/cp/call.c 2006-10-10 04:38:25.000000000 +0000 *************** build_x_va_arg (tree expr, tree type) *** 4488,4497 **** if (! pod_type_p (type)) { /* Undefined behavior [expr.call] 5.2.2/7. */ warning ("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); --- 4488,4499 ---- 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 ("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 *** 4780,4785 **** --- 4782,4793 ---- 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 *** 5434,5442 **** 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); } } } --- 5442,5450 ---- 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); } } } diff -Nrcpad gcc-4.0.3/gcc/cp/ChangeLog gcc-4.0.4/gcc/cp/ChangeLog *** gcc-4.0.3/gcc/cp/ChangeLog 2006-03-09 20:44:29.000000000 +0000 --- gcc-4.0.4/gcc/cp/ChangeLog 2007-01-31 10:21:25.000000000 +0000 *************** *** 1,3 **** --- 1,423 ---- + 2007-01-31 Release Manager + + * GCC 4.0.4 released. + + 2007-01-27 Volker Reichelt + + Backport: + 2006-11-13 Mark Mitchell + + PR c++/29106 + * g++.dg/init/self1.C: New test. + * g++.dg/other/fold1.C: Adjust error markers. + * g++.dg/init/member1.C: Likewise. + + 2006-08-27 Simon Martin + + PR c++/28284 + * g++.dg/template/pr28284.C: New test. + + 2006-11-18 Lee Millward + + PR c++/29022 + PR c++/27316 + PR c++/28740 + * parser.c (cp_parser_class_head): Move processing + of any base classes to... + (cp_parser_class_specifier) ...here. Take an extra + tree* parameter for the base classes. Only process + them if the opening brace was found. + + 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-10-11 Andrew Pinski + + PR c++/28302 + * typeck.c (build_unary_op ): Don't call + perform_integral_promotions for non integral type + + 2006-10-11 Andrew Pinski + + PR C++/29002 + * init.c (build_zero_init): If we have an error mark node for + the array size, return. + + 2006-10-10 Andrew Pinski + + PR C++/28450 + * cp/init.c (build_zero_init): Handle VECTOR_TYPE and + COMPLEX_TYPEs. + + 2006-10-09 Andrew Pinski + + PR C++/28349 + * call.c (build_x_va_arg): Remove the reference type + from the type before creating the pointer type. + + 2006-09-09 Jason Merrill + + PR c++/28996 + * cvt.c (convert_to_void): Strip COMPONENT_REF to functions. + + 2006-09-09 Jason Merrill + + PR c++/26957 + * method.c (use_thunk): Fix patch for 4.0 branch. + + 2006-09-07 Jason Merrill + + PR c++/26957 + * method.c (use_thunk): Clear DECL_HAS_VALUE_EXPR_P on copied + parms. + + 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++/19809 + * pt.c (tsubst_friend_function): Set DECL_INITIAL before pushdecl. + + 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-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-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-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-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 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-07-24 Volker Reichelt + + PR c++/27572 + * decl.c (grokdeclarator): Return error_mark_node after invalid + typedef. + + 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-18 Steve Ellcey + + PR c++/28304 + * decl2.c (check_classfn): Return NULL_TREE on error. + + 2006-07-17 Lee Millward + + PR c++/28051 + * search.c (lookup_member): Robustify. + + 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-07-12 Steve Ellcey + + PR c++/28114 + * name-lookup.c (pushtag): Return if we have error_mark_node. + + 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 Jason Merrill + + * class.c (check_field_decls): Fix warning call. + + 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. + + 2006-07-05 Nathan Sidwell + + PR c++/21166 + * class.c (check_field_decls): Only set DECL_PACKED on a field + when its natural alignment is > BITS_PER_UNIT. + + 2006-07-05 Jason Merrill + + 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++/28109 + * rtti.c (get_tinfo_decl_dynamic): Robustify. + + 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-05-29 Volker Reichelt + + PR c++/27713 + * pt.c (push_template_decl_real): Return error_mark_node instead + of broken decl. + + 2006-05-22 Volker Reichelt + + PR c++/27716 + * typeck.c (build_modify_expr): Test arguments for error_operand_p. + + 2006-05-15 Volker Reichelt + + PR c++/27582 + * pt.c (any_dependent_template_arguments_p): Return early on invalid + argument list. + + PR c++/27581 + * search.c (adjust_result_of_qualified_name_lookup): Skip on + invalid context_class. + + PR c++/27315 + * pt.c (do_decl_instantiation): Return early on invalid decl. + + 2006-05-11 Volker Reichelt + + PR c++/27547 + * decl.c (copy_fn_p): Return early on non-member functions. + + 2006-05-08 Volker Reichelt + + * decl.c (grok_op_properties): Add missing return value. + + 2006-05-06 Volker Reichelt + + PR c++/27427 + * pt.c (convert_nontype_argument): Return early on invalid arguments. + + PR c++/27422 + * typeck.c (convert_arguments): Return early on args with + invalid types. + + 2006-04-30 Volker Reichelt + + PR c++/27278 + * decl.c (grok_op_properties): Skip operators with invalid args + when checking for class-type or enum-type args. + + 2006-04-29 Volker Reichelt + + PR c++/27279 + * decl.c (copy_fn_p): Skip functions with invalid first arg. + + 2006-04-19 Volker Reichelt + + PR c++/26558 + * parser.c (cp_parser_class_name): Check for invalid typenames. + Rearrange code. + + PR c++/26036 + * typeck.c (convert_arguments): Return error_mark_node instead of + error_mark_list. + * cp-tree.h (error_mark_list): Remove declaration. + * decl.c (error_mark_list): Remove definition. + (cxx_init_decl_processing): Do not initialize error_mark_list. + + PR c++/10385 + * rtti.c (build_dynamic_cast_1): Check for invalid conversions + before calling convert_to_reference. + * cvt.c (convert_to_reference): Assert that reftype is a + REFERENCE_TYPE. + 2006-03-09 Release Manager * GCC 4.0.3 released. *************** *** 2154,2160 **** * pt.c (instantiate_class_template, resolve_typename_type): Likewise. ! 2005-01-03 Volker Reichelt PR c++/14136 * parser.c (cp_parser_unqualified_id): Do not issue error message --- 2574,2580 ---- * pt.c (instantiate_class_template, resolve_typename_type): Likewise. ! 2005-01-03 Volker Reichelt PR c++/14136 * parser.c (cp_parser_unqualified_id): Do not issue error message diff -Nrcpad gcc-4.0.3/gcc/cp/class.c gcc-4.0.4/gcc/cp/class.c *** gcc-4.0.3/gcc/cp/class.c 2006-02-18 09:41:18.000000000 +0000 --- gcc-4.0.4/gcc/cp/class.c 2006-07-10 17:01:54.000000000 +0000 *************** check_field_decls (tree t, tree *access_ *** 2850,2888 **** 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))) - cp_warning_at - ("ignoring packed attribute on unpacked non-POD field %q#D", - x); - else - 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. */ --- 2850,2855 ---- *************** check_field_decls (tree t, tree *access_ *** 2979,2984 **** --- 2946,2978 ---- type = strip_array_types (type); + if (TYPE_PACKED (t)) + { + if (!pod_type_p (type) && !TYPE_PACKED (type)) + cp_warning_at + ("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 + { + /* 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. */ diff -Nrcpad gcc-4.0.3/gcc/cp/cp-tree.def gcc-4.0.4/gcc/cp/cp-tree.def *** gcc-4.0.3/gcc/cp/cp-tree.def 2005-09-09 21:05:53.000000000 +0000 --- gcc-4.0.4/gcc/cp/cp-tree.def 2006-06-14 19:10:17.000000000 +0000 *************** 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.0.3/gcc/cp/cp-tree.h gcc-4.0.4/gcc/cp/cp-tree.h *** gcc-4.0.3/gcc/cp/cp-tree.h 2006-02-18 09:41:18.000000000 +0000 --- gcc-4.0.4/gcc/cp/cp-tree.h 2006-08-28 23:12:32.000000000 +0000 *************** typedef enum base_kind { *** 3116,3125 **** binfo. */ } base_kind; - /* in decl{2}.c */ - /* A node that is a list (length 1) of error_mark_nodes. */ - extern GTY(()) tree error_mark_list; - /* Node for "pointer to (virtual) function". This may be distinct from ptr_type_node so gdb can distinguish them. */ #define vfunc_ptr_type_node vtable_entry_type --- 3116,3121 ---- *************** extern int template_class_depth *** 4045,4051 **** 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); --- 4041,4047 ---- 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 finish_id_expression *** 4219,4224 **** --- 4215,4221 ---- 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.0.3/gcc/cp/cvt.c gcc-4.0.4/gcc/cp/cvt.c *** gcc-4.0.3/gcc/cp/cvt.c 2006-02-18 09:41:18.000000000 +0000 --- gcc-4.0.4/gcc/cp/cvt.c 2006-09-22 23:28:13.000000000 +0000 *************** convert_to_reference (tree reftype, tree *** 458,463 **** --- 458,464 ---- intype = TREE_TYPE (expr); gcc_assert (TREE_CODE (intype) != REFERENCE_TYPE); + gcc_assert (TREE_CODE (reftype) == REFERENCE_TYPE); intype = TYPE_MAIN_VARIANT (intype); *************** convert_to_void (tree expr, const char * *** 847,869 **** case INDIRECT_REF: { ! tree type = TREE_TYPE (expr); ! int is_reference = TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) ! == REFERENCE_TYPE; ! int is_volatile = TYPE_VOLATILE (type); ! int is_complete = COMPLETE_TYPE_P (complete_type (type)); ! ! if (is_volatile && !is_complete) ! warning ("object of incomplete type %qT will not be accessed in %s", ! type, implicit ? implicit : "void context"); ! else if (is_reference && is_volatile) ! warning ("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; } case VAR_DECL: --- 848,873 ---- case INDIRECT_REF: { ! tree type = TREE_TYPE (expr); ! int is_reference = TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) ! == REFERENCE_TYPE; ! 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 ("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 ("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; } case VAR_DECL: *************** convert_to_void (tree expr, const char * *** 894,902 **** expr = void_zero_node; } else if (implicit && probe == expr && is_overloaded_fn (probe)) ! /* Only warn when there is no &. */ ! warning ("%s is a reference, not call, to function %qE", ! implicit, expr); } if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr))) --- 898,910 ---- expr = void_zero_node; } else if (implicit && probe == expr && is_overloaded_fn (probe)) ! { ! /* Only warn when there is no &. */ ! warning ("%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 * *** 943,948 **** --- 951,958 ---- } expr = build1 (CONVERT_EXPR, void_type_node, expr); } + if (! TREE_SIDE_EFFECTS (expr)) + expr = void_zero_node; return expr; } diff -Nrcpad gcc-4.0.3/gcc/cp/decl2.c gcc-4.0.4/gcc/cp/decl2.c *** gcc-4.0.3/gcc/cp/decl2.c 2006-02-18 09:41:18.000000000 +0000 --- gcc-4.0.4/gcc/cp/decl2.c 2006-08-03 17:16:20.000000000 +0000 *************** check_classfn (tree ctype, tree function *** 707,714 **** 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 --- 707,716 ---- 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 *************** grokfield (const cp_declarator *declarat *** 830,835 **** --- 832,839 ---- if (!declspecs->any_specifiers_p && declarator->kind == cdk_id && declarator->u.id.qualifying_scope + && TYPE_P (declarator->u.id.qualifying_scope) + && IS_AGGR_TYPE (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, *************** grokfield (const cp_declarator *declarat *** 898,904 **** return void_type_node; } ! if (asmspec_tree) asmspec = TREE_STRING_POINTER (asmspec_tree); if (init) --- 902,908 ---- 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) *** 1183,1188 **** --- 1187,1194 ---- } main_decl = build_anon_union_vars (type, anon_union_decl); + if (main_decl == error_mark_node) + return; if (main_decl == NULL_TREE) { warning ("anonymous union with no members"); diff -Nrcpad gcc-4.0.3/gcc/cp/decl.c gcc-4.0.4/gcc/cp/decl.c *** gcc-4.0.3/gcc/cp/decl.c 2006-02-28 11:36:26.000000000 +0000 --- gcc-4.0.4/gcc/cp/decl.c 2006-09-07 22:38:03.000000000 +0000 *************** static void expand_static_init (tree, tr *** 116,124 **** static tree next_initializable_field (tree); static tree reshape_init (tree, tree *); - /* Erroneous argument lists can use this *IFF* they do not modify it. */ - tree error_mark_list; - /* The following symbols are subsumed in the cp_global_trees array, and listed here individually for documentation purposes. --- 116,121 ---- *************** duplicate_decls (tree newdecl, tree oldd *** 1576,1581 **** --- 1573,1581 ---- } 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 *** 2331,2337 **** pedwarn ("label named wchar_t"); if (DECL_INITIAL (decl) != NULL_TREE) ! error ("duplicate label %qD", decl); else { /* Mark label as having been defined. */ --- 2331,2340 ---- 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. */ *************** cxx_init_decl_processing (void) *** 2925,2933 **** /* Initially, C. */ current_lang_name = lang_name_c; - error_mark_list = build_tree_list (error_mark_node, error_mark_node); - TREE_TYPE (error_mark_list) = error_mark_node; - /* Create the `std' namespace. */ push_namespace (std_identifier); std_node = current_namespace; --- 2928,2933 ---- *************** make_rtl_for_nonlocal_decl (tree decl, t *** 4621,4627 **** { /* Fool with the linkage of static consts according to #pragma interface. */ ! struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename)); if (!finfo->interface_unknown && !TREE_PUBLIC (decl)) { TREE_PUBLIC (decl) = 1; --- 4621,4627 ---- { /* Fool with the linkage of static consts according to #pragma interface. */ ! struct c_fileinfo *finfo = get_fileinfo (input_filename); if (!finfo->interface_unknown && !TREE_PUBLIC (decl)) { TREE_PUBLIC (decl) = 1; *************** cp_finish_decl (tree decl, tree init, bo *** 4755,4761 **** /* 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) --- 4755,4761 ---- /* 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 (init && TREE_CODE (init) == NAMESPACE_DECL) *************** grokdeclarator (const cp_declarator *dec *** 6584,6591 **** 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)); --- 6584,6589 ---- *************** grokdeclarator (const cp_declarator *dec *** 6936,6942 **** 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) --- 6934,6943 ---- 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 *** 7798,7804 **** { /* Something like struct S { int N::j; }; */ error ("invalid use of %<::%>"); ! decl = NULL_TREE; } else if (TREE_CODE (type) == FUNCTION_TYPE) { --- 7799,7805 ---- { /* Something like struct S { int N::j; }; */ error ("invalid use of %<::%>"); ! return error_mark_node; } else if (TREE_CODE (type) == FUNCTION_TYPE) { *************** copy_fn_p (tree d) *** 8482,8488 **** tree arg_type; int result = 1; ! gcc_assert (DECL_FUNCTION_MEMBER_P (d)); if (DECL_TEMPLATE_INFO (d) && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d))) --- 8483,8491 ---- tree arg_type; int result = 1; ! if (!DECL_FUNCTION_MEMBER_P (d)) ! /* Non-members are invalid. We complained, but kept the declaration. */ ! return 0; if (DECL_TEMPLATE_INFO (d) && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d))) *************** copy_fn_p (tree d) *** 8497,8502 **** --- 8500,8507 ---- return 0; arg_type = TREE_VALUE (args); + if (arg_type == error_mark_node) + return 0; if (TYPE_MAIN_VARIANT (arg_type) == DECL_CONTEXT (d)) { *************** grok_op_properties (tree decl, bool comp *** 8751,8756 **** --- 8756,8764 ---- for (p = argtypes; p && p != void_list_node; p = TREE_CHAIN (p)) { tree arg = non_reference (TREE_VALUE (p)); + if (arg == error_mark_node) + return false; + /* IS_AGGR_TYPE, rather than CLASS_TYPE_P, is used because these checks are performed even on template functions. */ *************** xref_tag (enum tag_types tag_code, tree *** 9271,9277 **** && CLASSTYPE_IS_TEMPLATE (t)) { error ("redeclaration of %qT as a non-template", t); ! t = error_mark_node; } /* Make injected friend class visible. */ --- 9279,9286 ---- && CLASSTYPE_IS_TEMPLATE (t)) { error ("redeclaration of %qT as a non-template", t); ! cp_error_at ("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 *** 9904,9910 **** struct cp_binding_level *bl; tree current_function_parms; struct c_fileinfo *finfo ! = get_fileinfo (lbasename (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)))); /* Sanity check. */ gcc_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE); --- 9913,9919 ---- struct cp_binding_level *bl; tree current_function_parms; struct c_fileinfo *finfo ! = get_fileinfo (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1))); /* Sanity check. */ gcc_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE); *************** start_preparsed_function (tree decl1, tr *** 10002,10009 **** 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); --- 10011,10016 ---- diff -Nrcpad gcc-4.0.3/gcc/cp/friend.c gcc-4.0.4/gcc/cp/friend.c *** gcc-4.0.3/gcc/cp/friend.c 2004-11-29 20:10:18.000000000 +0000 --- gcc-4.0.4/gcc/cp/friend.c 2006-07-05 20:40:06.000000000 +0000 *************** 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.0.3/gcc/cp/init.c gcc-4.0.4/gcc/cp/init.c *** gcc-4.0.3/gcc/cp/init.c 2006-02-28 14:24:05.000000000 +0000 --- gcc-4.0.4/gcc/cp/init.c 2007-01-27 19:58:38.000000000 +0000 *************** 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, *** 226,231 **** --- 227,237 ---- 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, *** 248,253 **** --- 254,261 ---- CONSTRUCTOR_ELTS (init) = nreverse (inits); } + else if (TREE_CODE (type) == VECTOR_TYPE) + init = fold_convert (type, integer_zero_node); else gcc_assert (TREE_CODE (type) == REFERENCE_TYPE); *************** constant_value_1 (tree decl, bool integr *** 1600,1607 **** mark_used (decl); init = DECL_INITIAL (decl); } if (init == error_mark_node) ! return error_mark_node; if (!init || !TREE_TYPE (init) || (integral_p --- 1608,1618 ---- 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 *** 1668,1674 **** { tree rval; ! if (type == error_mark_node) return error_mark_node; if (processing_template_decl) --- 1679,1685 ---- { tree rval; ! if (placement == error_mark_node || type == error_mark_node) return error_mark_node; if (processing_template_decl) diff -Nrcpad gcc-4.0.3/gcc/cp/lex.c gcc-4.0.4/gcc/cp/lex.c *** gcc-4.0.3/gcc/cp/lex.c 2005-05-01 01:12:59.000000000 +0000 --- gcc-4.0.4/gcc/cp/lex.c 2006-09-07 22:38:03.000000000 +0000 *************** handle_pragma_interface (cpp_reader* dfi *** 467,473 **** else filename = ggc_strdup (TREE_STRING_POINTER (fname)); ! finfo = get_fileinfo (filename); if (impl_file_chain == 0) { --- 467,473 ---- 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) *** 773,779 **** /* 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; } --- 773,779 ---- /* 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.0.3/gcc/cp/mangle.c gcc-4.0.4/gcc/cp/mangle.c *** gcc-4.0.3/gcc/cp/mangle.c 2005-09-13 15:17:12.000000000 +0000 --- gcc-4.0.4/gcc/cp/mangle.c 2006-07-11 17:37:31.000000000 +0000 *************** mangle_conv_op_name_for_type (const tree *** 2771,2776 **** --- 2771,2779 ---- 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.0.3/gcc/cp/method.c gcc-4.0.4/gcc/cp/method.c *** gcc-4.0.3/gcc/cp/method.c 2005-11-16 20:26:06.000000000 +0000 --- gcc-4.0.4/gcc/cp/method.c 2006-09-09 16:11:34.000000000 +0000 *************** use_thunk (tree thunk_fndecl, bool emit_ *** 408,413 **** --- 408,414 ---- TREE_CHAIN (x) = t; DECL_CONTEXT (x) = thunk_fndecl; SET_DECL_RTL (x, NULL_RTX); + DECL_VALUE_EXPR (x) = NULL_TREE; t = x; } a = nreverse (t); *************** locate_copy (tree type, void *client_) *** 932,937 **** --- 933,942 ---- 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.0.3/gcc/cp/name-lookup.c gcc-4.0.4/gcc/cp/name-lookup.c *** gcc-4.0.3/gcc/cp/name-lookup.c 2006-02-18 09:41:18.000000000 +0000 --- gcc-4.0.4/gcc/cp/name-lookup.c 2006-08-03 02:41:33.000000000 +0000 *************** pushdecl (tree x) *** 601,609 **** { 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); --- 601,606 ---- *************** pushdecl (tree x) *** 732,737 **** --- 729,737 ---- } } + 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 *** 2556,2561 **** --- 2556,2564 ---- 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 *************** tree *** 2695,2700 **** --- 2698,2706 ---- do_class_using_decl (tree scope, tree name) { tree value, type; + + if (name == error_mark_node) + return NULL_TREE; if (!scope || !TYPE_P (scope)) { *************** tree *** 3590,3595 **** --- 3596,3602 ---- 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 *** 3599,3615 **** 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: --- 3606,3619 ---- 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: *************** pushtag (tree name, tree type, tag_scope *** 4668,4674 **** pushdecl_class_level (decl); } else if (b->kind != sk_template_parms) ! decl = pushdecl_with_scope (decl, b); /* FIXME what if it gets a name from typedef? */ if (ANON_AGGRNAME_P (name)) --- 4672,4682 ---- pushdecl_class_level (decl); } else if (b->kind != sk_template_parms) ! { ! decl = pushdecl_with_scope (decl, b); ! if (decl == error_mark_node) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); ! } /* FIXME what if it gets a name from typedef? */ if (ANON_AGGRNAME_P (name)) diff -Nrcpad gcc-4.0.3/gcc/cp/parser.c gcc-4.0.4/gcc/cp/parser.c *** gcc-4.0.3/gcc/cp/parser.c 2006-02-18 09:41:18.000000000 +0000 --- gcc-4.0.4/gcc/cp/parser.c 2006-12-03 13:11:51.000000000 +0000 *************** static tree cp_parser_class_name *** 1550,1556 **** 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 --- 1550,1556 ---- 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 *************** cp_parser_simulate_error (cp_parser* par *** 1894,1899 **** --- 1894,1942 ---- 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. */ *************** cp_parser_diagnose_invalid_type_name (cp *** 2006,2013 **** /* If the lookup found a template-name, it means that the user forgot to specify an argument list. Emit an 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 || parser->scope == error_mark_node) { /* Issue an error message. */ --- 2049,2060 ---- /* If the lookup found a template-name, it means that the user forgot to specify an argument list. Emit an 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 || parser->scope == error_mark_node) { /* Issue an error message. */ *************** cp_parser_parse_and_diagnose_invalid_typ *** 2100,2107 **** 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. */ --- 2147,2153 ---- 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_unqualified_id (cp_parser* par *** 3256,3263 **** 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) --- 3302,3327 ---- 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. */ ! if (scope && cp_lexer_next_token_is (parser->lexer, CPP_NAME) && (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_PAREN) *************** cp_parser_unqualified_id (cp_parser* par *** 3340,3346 **** 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; --- 3404,3410 ---- 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 *** 3351,3356 **** --- 3415,3421 ---- 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_builtin_offsetof (cp_parser *p *** 5911,5917 **** 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; --- 5976,5982 ---- 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_decl_specifier_seq (cp_parser* *** 7186,7192 **** 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); --- 7251,7256 ---- *************** cp_parser_decl_specifier_seq (cp_parser* *** 7387,7427 **** 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 --- 7451,7457 ---- 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_type_specifier_seq (cp_parser* *** 11756,11762 **** flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES; } ! return; } /* Parse a parameter-declaration-clause. --- 11786,11792 ---- flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES; } ! cp_parser_check_decl_spec (type_specifier_seq); } /* Parse a parameter-declaration-clause. *************** cp_parser_class_name (cp_parser *parser, *** 12542,12556 **** standard does not seem to be definitive, but there is no other valid interpretation of the following `::'. Therefore, those names are considered class-names. */ - decl = TYPE_NAME (make_typename_type (scope, decl, tag_type, tf_error)); - else if (decl == error_mark_node - || TREE_CODE (decl) != TYPE_DECL - || TREE_TYPE (decl) == error_mark_node - || !IS_AGGR_TYPE (TREE_TYPE (decl))) { ! cp_parser_error (parser, "expected class-name"); ! return error_mark_node; } return decl; } --- 12572,12589 ---- standard does not seem to be definitive, but there is no other valid interpretation of the following `::'. Therefore, those names are considered class-names. */ { ! decl = make_typename_type (scope, decl, tag_type, tf_error); ! if (decl != error_mark_node) ! decl = TYPE_NAME (decl); } + else if (TREE_CODE (decl) != TYPE_DECL + || TREE_TYPE (decl) == error_mark_node + || !IS_AGGR_TYPE (TREE_TYPE (decl))) + decl = error_mark_node; + + if (decl == error_mark_node) + cp_parser_error (parser, "expected class-name"); return decl; } *************** cp_parser_class_specifier (cp_parser* pa *** 12573,12585 **** 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) --- 12606,12620 ---- unsigned saved_num_template_parameter_lists; tree old_scope = NULL_TREE; tree scope = NULL_TREE; + tree bases; 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 *** 12596,12601 **** --- 12631,12639 ---- 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 *** 12750,12756 **** 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; --- 12788,12795 ---- 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, *** 12763,12769 **** 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; --- 12802,12807 ---- *************** cp_parser_class_head (cp_parser* parser, *** 12978,12984 **** if (template_id_p) { type = TREE_TYPE (id); ! maybe_process_partial_specialization (type); if (nested_name_specifier) pushed_scope = push_scope (nested_name_specifier); } --- 13016,13022 ---- 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, *** 13059,13072 **** 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 --- 13097,13107 ---- 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_attribute_list (cp_parser* par *** 14286,14291 **** --- 14321,14328 ---- 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 *** 14299,14316 **** /* 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); } --- 14336,14354 ---- /* 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); } diff -Nrcpad gcc-4.0.3/gcc/cp/pt.c gcc-4.0.4/gcc/cp/pt.c *** gcc-4.0.3/gcc/cp/pt.c 2006-02-18 09:41:18.000000000 +0000 --- gcc-4.0.4/gcc/cp/pt.c 2007-01-27 19:58:38.000000000 +0000 *************** check_specialization_namespace (tree tmp *** 676,688 **** /* 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); --- 676,695 ---- /* 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 *** 767,773 **** } } else if (processing_specialization) ! error ("explicit specialization of non-template %qT", type); } /* Returns nonzero if we can optimize the retrieval of specializations --- 774,785 ---- } } 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 *************** push_template_decl_real (tree decl, int *** 2947,2953 **** DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); /* See if this is a primary template. */ ! primary = template_parm_scope_p (); if (primary) { --- 2959,2971 ---- 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, int *** 2979,2985 **** 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) --- 2997,3003 ---- 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 *** 3296,3301 **** --- 3314,3322 ---- 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_nontype_argument (tree type, tre *** 3426,3431 **** --- 3447,3454 ---- instantiated -- but here we need the resolved form so that we can convert the argument. */ expr = fold_non_dependent_expr (expr); + if (error_operand_p (expr)) + return error_mark_node; expr_type = TREE_TYPE (expr); /* HACK: Due to double coercion, we can get a *************** convert_template_argument (tree parm, *** 3792,3802 **** 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) { --- 3815,3822 ---- *************** convert_template_argument (tree parm, *** 3888,3894 **** if (coerce_template_template_parms (parmparm, argparm, complain, in_decl, ! inner_args)) { val = arg; --- 3908,3914 ---- if (coerce_template_template_parms (parmparm, argparm, complain, in_decl, ! args)) { val = arg; *************** tsubst_friend_function (tree decl, tree *** 5189,5194 **** --- 5209,5218 ---- 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 (tree t, tree args, tsubst_flags_ *** 7066,7075 **** { 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) { --- 7090,7109 ---- { 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_copy_and_build (tree t, *** 8939,8945 **** in_decl)); case OFFSETOF_EXPR: ! return fold_offsetof (RECUR (TREE_OPERAND (t, 0))); case STMT_EXPR: { --- 8973,8979 ---- in_decl)); case OFFSETOF_EXPR: ! return finish_offsetof (RECUR (TREE_OPERAND (t, 0))); case STMT_EXPR: { *************** do_decl_instantiation (tree decl, tree s *** 11040,11046 **** tree result = NULL_TREE; int extern_p = 0; ! if (!decl) /* An error occurred, for which grokdeclarator has already issued an appropriate message. */ return; --- 11074,11080 ---- tree result = NULL_TREE; int extern_p = 0; ! if (!decl || decl == error_mark_node) /* An error occurred, for which grokdeclarator has already issued an appropriate message. */ return; *************** any_dependent_template_arguments_p (tree *** 12559,12564 **** --- 12593,12600 ---- if (!args) return false; + if (args == error_mark_node) + return true; for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i) { diff -Nrcpad gcc-4.0.3/gcc/cp/rtti.c gcc-4.0.4/gcc/cp/rtti.c *** gcc-4.0.3/gcc/cp/rtti.c 2006-02-18 09:41:18.000000000 +0000 --- gcc-4.0.4/gcc/cp/rtti.c 2006-06-22 09:43:53.000000000 +0000 *************** get_tinfo_decl_dynamic (tree exp) *** 202,208 **** tree type; tree t; ! if (exp == error_mark_node) return error_mark_node; /* peel back references, so they match. */ --- 202,208 ---- tree type; tree t; ! if (error_operand_p (exp)) return error_mark_node; /* peel back references, so they match. */ *************** build_dynamic_cast_1 (tree type, tree ex *** 485,494 **** } else { - /* Apply trivial conversion T -> T& for dereferenced ptrs. */ exprtype = build_reference_type (exprtype); - expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT, - LOOKUP_NORMAL, NULL_TREE); /* T is a reference type, v shall be an lvalue of a complete class type, and the result is an lvalue of the type referred to by T. */ --- 485,491 ---- *************** build_dynamic_cast_1 (tree type, tree ex *** 504,509 **** --- 501,509 ---- goto fail; } + /* Apply trivial conversion T -> T& for dereferenced ptrs. */ + expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT, + LOOKUP_NORMAL, NULL_TREE); } /* The dynamic_cast operator shall not cast away constness. */ diff -Nrcpad gcc-4.0.3/gcc/cp/search.c gcc-4.0.4/gcc/cp/search.c *** gcc-4.0.3/gcc/cp/search.c 2005-10-20 18:04:35.000000000 +0000 --- gcc-4.0.4/gcc/cp/search.c 2006-08-18 16:27:03.000000000 +0000 *************** friend_accessible_p (tree scope, tree de *** 793,800 **** 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)) --- 793,800 ---- 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 *** 1201,1206 **** --- 1201,1209 ---- const char *errstr = 0; + if (name == error_mark_node) + return NULL_TREE; + gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); if (TREE_CODE (xbasetype) == TREE_BINFO) *************** lookup_member (tree xbasetype, tree name *** 1210,1216 **** } else { ! gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype))); type = xbasetype; xbasetype = NULL_TREE; } --- 1213,1220 ---- } 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 qualifying_scope, tree context_class) { ! if (context_class && 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 --- 1484,1497 ---- tree qualifying_scope, 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.0.3/gcc/cp/semantics.c gcc-4.0.4/gcc/cp/semantics.c *** gcc-4.0.3/gcc/cp/semantics.c 2005-12-22 20:02:21.000000000 +0000 --- gcc-4.0.4/gcc/cp/semantics.c 2006-09-07 22:38:03.000000000 +0000 *************** tree *** 1250,1255 **** --- 1250,1259 ---- 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_template_template_default_arg (tre *** 2052,2070 **** && 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; --- 2056,2063 ---- && 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) *** 2130,2136 **** 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); --- 2123,2129 ---- 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); *************** finish_typeof (tree expr) *** 2784,2789 **** --- 2777,2806 ---- 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.0.3/gcc/cp/tree.c gcc-4.0.4/gcc/cp/tree.c *** gcc-4.0.3/gcc/cp/tree.c 2005-10-02 21:44:37.000000000 +0000 --- gcc-4.0.4/gcc/cp/tree.c 2006-09-07 22:38:03.000000000 +0000 *************** int *** 807,813 **** 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); --- 807,814 ---- 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) *** 836,841 **** --- 837,844 ---- { 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); diff -Nrcpad gcc-4.0.3/gcc/cp/typeck2.c gcc-4.0.4/gcc/cp/typeck2.c *** gcc-4.0.3/gcc/cp/typeck2.c 2006-02-11 00:19:30.000000000 +0000 --- gcc-4.0.4/gcc/cp/typeck2.c 2006-08-26 00:59:09.000000000 +0000 *************** cxx_incomplete_type_diagnostic (tree val *** 412,418 **** break; case TEMPLATE_TYPE_PARM: ! (*p_msg) ("invalid use of template type parameter"); break; case UNKNOWN_TYPE: --- 412,423 ---- 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: *************** build_functional_cast (tree exp, tree pa *** 1386,1397 **** 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); } --- 1391,1401 ---- 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.0.3/gcc/cp/typeck.c gcc-4.0.4/gcc/cp/typeck.c *** gcc-4.0.3/gcc/cp/typeck.c 2006-01-24 21:44:57.000000000 +0000 --- gcc-4.0.4/gcc/cp/typeck.c 2006-12-01 22:32:00.000000000 +0000 *************** type_after_usual_arithmetic_conversions *** 274,280 **** || 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 --- 274,280 ---- || 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 *************** convert_arguments (tree typelist, tree v *** 2569,2575 **** tree type = typetail ? TREE_VALUE (typetail) : 0; tree val = TREE_VALUE (valtail); ! if (val == error_mark_node) return error_mark_node; if (type == void_type_node) --- 2569,2575 ---- tree type = typetail ? TREE_VALUE (typetail) : 0; tree val = TREE_VALUE (valtail); ! if (val == error_mark_node || type == error_mark_node) return error_mark_node; if (type == void_type_node) *************** convert_arguments (tree typelist, tree v *** 2685,2691 **** } else error ("too few arguments to function"); ! return error_mark_list; } } --- 2685,2691 ---- } else error ("too few arguments to function"); ! return error_mark_node; } } *************** build_binary_op (enum tree_code code, tr *** 2901,2917 **** && (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)) { if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1)) warning ("division by zero in %<%E / 0%>", op0); else if (TREE_CODE (op1) == REAL_CST && real_zerop (op1)) warning ("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. --- 2901,2919 ---- && (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 ("division by zero in %<%E / 0%>", op0); else if (TREE_CODE (op1) == REAL_CST && real_zerop (op1)) warning ("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 *** 3784,3790 **** 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; --- 3786,3792 ---- else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM, 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 *** 5275,5281 **** 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". */ --- 5277,5283 ---- 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 *** 6083,6088 **** --- 6085,6094 ---- } } + 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.0.3/libstdc++-v3/ChangeLog gcc-4.0.4/libstdc++-v3/ChangeLog *** gcc-4.0.3/libstdc++-v3/ChangeLog 2006-03-09 20:44:44.000000000 +0000 --- gcc-4.0.4/libstdc++-v3/ChangeLog 2007-01-31 10:24:23.000000000 +0000 *************** *** 1,3 **** --- 1,23 ---- + 2007-01-31 Release Manager + + * GCC 4.0.4 released. + + 2007-01-13 John David Anglin + + * config/cpu/hppa/atomicity.h (__exchange_and_add): Don't use ordered + store. + (__atomic_add): Likewise. + + 2006-10-06 Paolo Carlini + + PR libstdc++/29368 + * include/bits/basic_string.h: Adjust rfind documentation. + + 2006-04-10 Matthias Klose + + * testsuite/lib/libstdc++.exp (libstdc++_init): Recognize multilib + directory names containing underscores. + 2006-03-09 Release Manager * GCC 4.0.3 released. diff -Nrcpad gcc-4.0.3/libstdc++-v3/config/cpu/hppa/atomicity.h gcc-4.0.4/libstdc++-v3/config/cpu/hppa/atomicity.h *** gcc-4.0.3/libstdc++-v3/config/cpu/hppa/atomicity.h 2004-08-20 16:08:49.000000000 +0000 --- gcc-4.0.4/libstdc++-v3/config/cpu/hppa/atomicity.h 2007-01-13 15:17:14.000000000 +0000 *************** 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.0.3/libstdc++-v3/include/bits/basic_string.h gcc-4.0.4/libstdc++-v3/include/bits/basic_string.h *** gcc-4.0.3/libstdc++-v3/include/bits/basic_string.h 2005-07-16 09:13:29.000000000 +0000 --- gcc-4.0.4/libstdc++-v3/include/bits/basic_string.h 2006-10-06 11:48:34.000000000 +0000 *************** *** 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 *** 1618,1624 **** /** * @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 --- 1618,1624 ---- /** * @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 *** 1635,1641 **** /** * @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. --- 1635,1641 ---- /** * @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.0.3/libstdc++-v3/include/bits/c++config gcc-4.0.4/libstdc++-v3/include/bits/c++config *** gcc-4.0.3/libstdc++-v3/include/bits/c++config 2006-03-09 00:16:47.000000000 +0000 --- gcc-4.0.4/libstdc++-v3/include/bits/c++config 2007-01-31 00:16:42.000000000 +0000 *************** *** 35,41 **** #include // The current version of the C++ library in compressed ISO date format. ! #define __GLIBCXX__ 20060309 // Allow use of "export template." This is currently not a feature // that g++ supports. --- 35,41 ---- #include // The current version of the C++ library in compressed ISO date format. ! #define __GLIBCXX__ 20070131 // Allow use of "export template." This is currently not a feature // that g++ supports. diff -Nrcpad gcc-4.0.3/libstdc++-v3/testsuite/lib/libstdc++.exp gcc-4.0.4/libstdc++-v3/testsuite/lib/libstdc++.exp *** gcc-4.0.3/libstdc++-v3/testsuite/lib/libstdc++.exp 2005-06-22 20:39:38.000000000 +0000 --- gcc-4.0.4/libstdc++-v3/testsuite/lib/libstdc++.exp 2006-04-10 22:01:37.000000000 +0000 *************** proc libstdc++_init { testfile } { *** 137,143 **** if { [is_remote host] == 0 && [which $compiler] != 0 } { foreach i "[exec $compiler --print-multi-lib]" { set mldir "" ! regexp -- "\[a-z0-9=/\.-\]*;" $i mldir set mldir [string trimright $mldir "\;@"] if { "$mldir" == "." } { continue --- 137,143 ---- if { [is_remote host] == 0 && [which $compiler] != 0 } { foreach i "[exec $compiler --print-multi-lib]" { set mldir "" ! regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir set mldir [string trimright $mldir "\;@"] if { "$mldir" == "." } { continue