diff options
author | kan <kan@FreeBSD.org> | 2005-06-03 03:28:44 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2005-06-03 03:28:44 +0000 |
commit | 2156e40a831a8e0ab68e4bc091c2940bf46ca6df (patch) | |
tree | f0dc8ad34f9fcaf27052e24e893a4284b5fee6e9 /contrib/gcc/cp | |
parent | 0a20abcc95340c9d2bb59421bac84eca4fb43b0c (diff) | |
download | FreeBSD-src-2156e40a831a8e0ab68e4bc091c2940bf46ca6df.zip FreeBSD-src-2156e40a831a8e0ab68e4bc091c2940bf46ca6df.tar.gz |
Gcc 3.4.4 release.
Diffstat (limited to 'contrib/gcc/cp')
-rw-r--r-- | contrib/gcc/cp/ChangeLog | 620 | ||||
-rw-r--r-- | contrib/gcc/cp/Make-lang.in | 3 | ||||
-rw-r--r-- | contrib/gcc/cp/call.c | 50 | ||||
-rw-r--r-- | contrib/gcc/cp/class.c | 225 | ||||
-rw-r--r-- | contrib/gcc/cp/cp-tree.h | 26 | ||||
-rw-r--r-- | contrib/gcc/cp/cvt.c | 5 | ||||
-rw-r--r-- | contrib/gcc/cp/cxx-pretty-print.c | 4 | ||||
-rw-r--r-- | contrib/gcc/cp/decl.c | 242 | ||||
-rw-r--r-- | contrib/gcc/cp/decl2.c | 10 | ||||
-rw-r--r-- | contrib/gcc/cp/error.c | 12 | ||||
-rw-r--r-- | contrib/gcc/cp/except.c | 24 | ||||
-rw-r--r-- | contrib/gcc/cp/g++spec.c | 3 | ||||
-rw-r--r-- | contrib/gcc/cp/init.c | 63 | ||||
-rw-r--r-- | contrib/gcc/cp/mangle.c | 13 | ||||
-rw-r--r-- | contrib/gcc/cp/method.c | 59 | ||||
-rw-r--r-- | contrib/gcc/cp/name-lookup.c | 45 | ||||
-rw-r--r-- | contrib/gcc/cp/parser.c | 419 | ||||
-rw-r--r-- | contrib/gcc/cp/pt.c | 261 | ||||
-rw-r--r-- | contrib/gcc/cp/search.c | 52 | ||||
-rw-r--r-- | contrib/gcc/cp/semantics.c | 107 | ||||
-rw-r--r-- | contrib/gcc/cp/tree.c | 35 | ||||
-rw-r--r-- | contrib/gcc/cp/typeck.c | 30 | ||||
-rw-r--r-- | contrib/gcc/cp/typeck2.c | 32 |
23 files changed, 1762 insertions, 578 deletions
diff --git a/contrib/gcc/cp/ChangeLog b/contrib/gcc/cp/ChangeLog index 7462819..a40a034 100644 --- a/contrib/gcc/cp/ChangeLog +++ b/contrib/gcc/cp/ChangeLog @@ -1,3 +1,623 @@ +2005-05-19 Release Manager + + * GCC 3.4.4 released. + +2005-05-08 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/21427 + Backport 2005-03-01 Nathan Sidwell <nathan@codesourcery.com> + * class.c (update_vtable_entry_for_fn): Don't crash on invalid + covariancy. + + * cp-tree.h (THUNK_TARGET): Expand comment. + * method.c (use_thunk): Make sure we also use the target, if that + is a thunk. + + Backport 2005-02-11 Nathan Sidwell <nathan@codesourcery.com> + * class.c (update_vtable_entry_for_fn): Walk the covariant's binfo + chain rather than using lookup_base. + +2005-05-04 Mark Mitchell <mark@codesourcery.com> + + Backport: + 2004-12-21 Mark Mitchell <mark@codesourcery.com> + PR c++/19034 + * tree.c (cp_tree_equal): Handle OVERLOAD. + +2005-05-02 Mark Mitchell <mark@codesourcery.com> + + Revert: + 2005-05-01 Mark Mitchell <mark@codesourcery.com> + * typeck.c (unary_complex_lvalue): In a template, always refuse + simplifications. + +2005-05-01 Mark Mitchell <mark@codesourcery.com> + + Backport: + 2005-02-22 Mark Mitchell <mark@codesourcery.com> + PR c++/19991 + * init.c (decl_constant_value): Iterate if the value of a decl + is itself a constant. + +2005-05-01 Mark Mitchell <mark@codesourcery.com> + + Backport: + 2004-12-22 Mark Mitchell <mark@codesourcery.com> + PR c++/18464 + * call.c (build_this): In templates, do not bother with + build_unary_op. + * typeck.c (unary_complex_lvalue): In a template, always refuse + simplifications. + +2005-04-25 Roger Sayle <roger@eyesopen.com> + Mark Mitchell <mark@codesourcery.com> + + PR c++/20995 + Partial backport from mainline. + 2004-09-27 Mark Mitchell <mark@codesourcery.com> + * tree.c (fold_if_not_in_template): New function. + * cp-tree.h (fold_if_not_in_template): Prototype here. + * call.c (build_conditional_expr): Use fold_if_not_in_template. + * typeck.c (build_binary_op): Likewise. + +2005-04-16 Mark Mitchell <mark@codesourcery.com> + + PR c++/21025 + * typeck.c (cxx_sizeof_or_alignof_type): Check whether the type to + which sizeof/alignof is dependent, rather than just whether we are + processing_template_decl. + +2005-04-06 Jason Merrill <jason@redhat.com> + + PR c++/19312 + * tree.c (stabilize_init): Don't bother trying to stabilize + something with no side-effects. + +2005-04-04 Mark Mitchell <mark@codesourcery.com> + + PR c++/20679 + * parser.c (cp_parser_template_name): Fix thinko. + +2005-04-03 Gabriel Dos Reis <gdr@integrable-solutions.net> + + PR c++/18644 + * call.c (build_new_op): Remove check for -Wsynth. + +2005-03-21 Paolo Carlini <pcarlini@suse.de> + + PR c++/20147 + * semantics.c (finish_stmt_expr_expr): Return immediately + if error_operand_p (expr). + +2005-03-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/20240 + * decl.c (decls_match): Compare context of VAR_DECL. + +2005-03-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/20333 + * parser.c (cp_parser_postfix_expression) <case RID_TYPENAME>: + Check the return value of cp_parser_nested_name_specifier. + +2005-03-08 Mark Mitchell <mark@codesourcery.com> + + PR c++/20142 + * init.c (build_vec_init): When determining whether or not the + element type has an asignment operator, look through all array + dimensions. + +2005-03-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/19311 + * init.c (build_offset_ref): Don't build non-dependent SCOPE_REF. + * pt.c (build_non_dependent_expr): Don't build NON_DEPENDENT_EXPR + for OFFSET_TYPE. + * typeck.c (build_x_unary_op): Don't build non-dependent SCOPE_REF. + Also set PTRMEM_OK_P for NON_DEPENDENT_EXPR. + (build_unary_op): Handle building ADDR_EXPR of OFFSET_REF inside + template. + +2005-03-02 Alexandre Oliva <aoliva@redhat.com> + + * name-lookup.c (push_overloaded_decl): Don't error if the new + decl matches the old one. + * decl.c (redeclaration_error_message): Likewise. + +2005-02-24 Jakub Jelinek <jakub@redhat.com> + + PR c++/20175 + * decl.c (reshape_init): Don't warn about missing braces if STRING_CST + initializes a char/wchar_t array. + +2005-02-21 Alexandre Oliva <aoliva@redhat.com> + + PR c++/20028 + * class.c (finish_struct): Initialize TYPE_SIZE_UNIT of a + template along with TYPE_SIZE. + +2005-02-14 Mark Mitchell <mark@codesourcery.com> + + * decl.c (reshape_init): Use explicit quotes in error message + instead of %q. + +2005-02-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/14479 + PR c++/19487 + * pt.c (maybe_check_template_type): Remove. + * cp-tree.h (maybe_check_template_type): Remove prototype. + * name-lookup.c (maybe_process_template_type_declaration): Don't + use maybe_check_template_type. + +2005-02-10 Mark Mitchell <mark@codesourcery.com> + + PR c++/19755 + * decl.c (reshape_init): Issue warnings about missing braces. + +2005-02-09 Mark Mitchell <mark@codesourcery.com> + + * parser.c (cp_parser_unqualified_id): Initialize type_decl. + + PR c++/19787 + * call.c (initialize_reference): Robustify. + + PR c++/19762 + * parser.c (cp_parser_unqualified_id): Avoid creating destructor + names with invalid types. + + PR c++/19739 + * parser.c (cp_parser_attributes_list): Allow empty lists. + +2005-02-08 Mark Mitchell <mark@codesourcery.com> + + PR c++/19733 + * cvt.c (convert_to_void): Issue errors about pseudo-destructor + expressions. + +2005-02-01 Alexandre Oliva <aoliva@redhat.com> + + PR c++/18757 + PR c++/19366 + PR c++/19499 + * parser.c (cp_parser_template_id): Revert 2004-12-09's patch. + Issue an error when creating the template id. + * pt.c (fn_type_unification): Return early if the explicit + template arg list is an error_mark_node. + +2005-01-27 J"orn Rennecke <joern.rennecke@st.com> + + PR c++/18370 + * parser.c (cp_parser_initializer_clause): Initialize *non_constant_p. + +2005-01-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/19375 + * semantics.c (finish_id_expression): Disable access checking for + already lookuped FIELD_DECL. + +2005-01-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/19258 + * parser.c (cp_parser_late_parsing_default_args): Handle friend + defined in class. + * pt.c (push_access_scope, pop_access_scope): Likewise. + +2005-01-15 Jakub Jelinek <jakub@redhat.com> + + PR c++/19263 + * typeck2.c (split_nonconstant_init_1) <case VECTOR_TYPE>: Put a copy + of CONSTRUCTOR's node into MODIFY_EXPR, as the original is modified. + Store code to *pcode. + +2004-12-28 Jakub Jelinek <jakub@redhat.com> + + PR c++/18384, c++/18327 + * decl.c (reshape_init_array): Use UHWI type for max_index_cst + and index. Convert max_index to size_type_node if it isn't + host_integerp (, 1). + +2004-12-23 Alexandre Oliva <aoliva@redhat.com> + + PR c++/18962 + * pt.c (check_explicit_specialization): Use the argument list from + the definition in a template function specialization definition. + +2004-12-23 Alexandre Oliva <aoliva@redhat.com> + + PR c++/18757 + * parser.c (cp_parser_template_id): Don't create a CPP_TEMPLATE_ID + if parsing failed. + +2004-12-17 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/18975 + * method.c (do_build_copy_constructor): Refactor. Don't const + qualify a mutable field. + (do_build_assign_ref): Likewise. + +2004-12-10 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/18731 + * parser.c (cp_parser_class_head): Reject typedef-name in class head. + +2004-12-09 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/16681 + * init.c (build_zero_init): Build a RANGE_EXPR for an array + initializer. + +2004-12-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/18100 + * name-lookup.c (push_class_level_binding): Diagnose nested + class template with the same name as enclosing class. + +2004-12-04 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/17011, c++/17971 + * pt.c (tsubst_copy) <FIELD_DECL case>: Check and diagnose + invalid field. + (tsubst_copy_and_build) <COMPONENT_REF case>: Check + error_mark_node after member substitution. + * semantics.c (finish_id_expression): Call + finish_non_static_data_member for dependent FIELD_DECL. + +2004-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/18123 + * parser.c (cp_parser_type_specifier): Don't create new enum + type if it is not in the form 'enum [identifier] { [...] };'. + Catch template declaration of enum. + +2004-12-01 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/17431 + * call.c (standard_conversion): Add FLAGS parameter. Do not allow + derived to base conversion when checking constructor + accessibility. + (implicit_conversion): Pass FLAGS to standard_conversion. + (check_constructir_callable): Disallow conversion functions. + +2004-11-12 Mark Mitchell <mark@codesourcery.com> + + PR c++/18389 + * decl.c (start_decl): Make sure to set *pop_scope_p. Return + error_mark_node to indicate errors. + + PR c++/18436 + * pt.c (tsubst_copy_and_build): Do not do Koenig lookup when an + unqualified name resolves to a member function. + + PR c++/18407 + * pt.c (tsubst_copy_and_build): Handle qualified names used from a + derived class correctly. + +2004-11-04 Release Manager + + * GCC 3.4.3 released. + +2004-10-31 Mark Mitchell <mark@codesourcery.com> + + PR c++/15172 + * typeck2.c (store_init_value): Use split_nonconstant_init even + for types that require construction. + +2004-10-28 Mark Mitchell <mark@codesourcery.com> + + PR c++/17132 + * pt.c (instantiate_class_template): Increment + processing_template_decl when substituting into a member class + template. + +2004-10-27 Mark Mitchell <mark@codesourcery.com> + + PR c++/18140 + * parser.c (cp_parser_next_token_ends_template_argument_p): Do not + include ">>". + +2004-10-27 Andrew Pinski <pinskia@physics.uc.edu> + + PR c++/13560 + * error.c (cp_error_at): Output the context as it might be + different file as the other location. + +2004-10-26 Mark Mitchell <mark@codesourcery.com> + + PR c++/18093 + * search.c (current_scope): Return the innermost non-block scope, + not the innermost non-block, non-namespace scope. + (at_namespace_scope_p): Adjust accordingly. + (dfs_accessible_post): Do not pass namespaces to is_friend. + (dfs_walk_once_accessible_r): Likewise. + * decl.c (grokvardecl): Adjust call to current_scope. + (build_enumerator): Likewise. + * parser.c (cp_parser_using_declaration): Likewise. + (cp_parser_direct_declarator): Use at_namespace_scope_p instead of + current_scope. + (cp_parser_class_head): Adjust call to current_scope. + * name-lookup.c (do_namespace_alias): Set the DECL_CONTEXT for the + alias. + + PR c++/18020 + * pt.c (tusbst_copy_and_build): Resolve enumeration constants to + their underlying values. + +2004-10-17 Andrew Pinski <pinskia@physics.uc.edu> + + PR c++/16301 + * name-lookup.c (parse_using_directive): If we have a + error_mark_node, do not set the decl namespace associations + on it. + +2004-10-14 Mark Mitchell <mark@codesourcery.com> + + PR c++/17976 + * decl.c (cp_finish_decl): Do not call expand_static_init more + than once for a single variable. + +2004-10-11 Mark Mitchell <mark@codesourcery.com> + + PR c++/15786 + * parser.c (cp_parser_declarator): Add member_p parameter. + (cp_parser_condition): Adjust calls to cp_parser_declarator. + (cp_parser_explicit_instantiation): Likewise. + (cp_parser_init_declarator): Likewise. + (cp_parser_direct_declarator): Add member_p parameter. Do not + parse tentatively when parsing the parameters to a member. + (cp_parser_type_id): Adjust calls to cp_parser_declarator. + (cp_parser_parameter_declaration): Likewise. + (cp_parser_member_declaration): Likewise. + (cp_parser_exception_declaration): Likewise. + +2004-10-11 Mark Mitchell <mark@codesourcery.com> + + * decl2.c (finish_anon_union): Robustify. + +2004-10-10 Mark Mitchell <mark@codesourcery.com> + + PR c++/17393 + * decl.c (grokdeclarator): Robustify error-recovery on invalid + declarations. + +2004-10-09 Mark Mitchell <mark@codesourcery.com> + + PR c++/17821 + * parser.c (cp_parser_postfix_dot_deref_expression): If the + pseduo-destructor-name production does not work, fall back to the + ordinary production. + + PR c++/17826 + * tree.c (cp_tree_equal): Handle a BASELINK. + +2004-10-09 Mark Mitchell <mark@codesourcery.com> + + PR c++/17524 + * cp-tree.h (check_var_type): New function. + * decl.c (check_var_type): New function, split out from ... + (grokdeclarator): ... here. + * pt.c (tsubst_decl): Use check_var_type. + + PR c++/17685 + * decl.c (grokdeclarator): Disallow declarations of operators as + non-functions. + +2004-10-08 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/17868 + * error.c (dump_expr): Add missing case for RDIV_EXPR. + +2004-10-08 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/17829 + * parser.c (cp_parser_postfix_expression): Inhibit Koenig when + unqualified lookup finds a member function. + +2004-09-28 Roger Sayle <roger@eyesopen.com> + + PR driver/17537 + * g++spec.c (lang_specific_driver): Unrecognized libraries, other + than -lc and -lm, may require linking against libstc++. + +2004-09-27 Mark Mitchell <mark@codesourcery.com> + + PR c++/17585 + * cp-tree.h (shared_member_p): Declare. + * search.c (shared_member_p): Give it external linkage. + * semantics.c (finish_qualified_id_expr): Use it. + (finish_id_expression): Likewise. + +2004-09-22 Giovanni Bajo <giovannibajo@gcc.gnu.org> + + PR c++/14179 + * parser.c (cp_parser_initializer): Speed up parsing of simple + literals as initializers. + +2004-09-21 Giovanni Bajo <giovannibajo@gcc.gnu.org> + + PR c++/14179 + * decl.c (reshape_init): Extract array handling into... + (reshape_init_array): New function. Use integers instead of trees + for indices. Handle out-of-range designated initializers. + +2004-09-16 Mark Mitchell <mark@codesourcery.com> + + PR c++/17501 + * parser.c (cp_parser_nested_name_specifier): Do not resolve + typename types if the user explicitly said "typename". + +2004-09-13 Mark Mitchell <mark@codesourcery.com> + + PR c++/16162 + * parser.c (cp_parser_id_expression): Correct value for + is_declarator. + (cp_parser_nested_name_specifier_opt): Look through typenames as + necessary. + (cp_parser_template_name): Honor check_dependency_p. + +2004-09-13 Mark Mitchell <mark@codesourcery.com> + + PR c++/17327 + * pt.c (unify): Add ENUMERAL_TYPE case. Replace sorry with + gcc_unreacable. + +2004-09-06 Release Manager + + * GCC 3.4.2 released. + +2004-08-25 Roger Sayle <roger@eyesopen.com> + + PR middle-end/16693 + PR tree-optimization/16372 + * decl.c (finish_enum): Make the precision of the enumerated type + the same width as the underlying integer type. + +2004-08-24 Jason Merrill <jason@redhat.com> + + PR c++/16851 + * tree.c (stabilize_init): See through a COMPOUND_EXPR. + + PR c++/15461 + * semantics.c (nullify_returns_r): Replace a DECL_STMT + for the NRV with an INIT_EXPR. + +2004-08-24 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/16889 + * (is_subobject_of_p): Resurrect & optimize. + (lookup_field_r): Use it. + +2004-08-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/16706 + * search.c (friend_accessible_p): Increment processing_template_decl + when deal with TEMPLATE_DECL of SCOPE. + +2004-08-23 Janis Johnson <janis187@us.ibm.com> + + Backports from mainline: + + 2004-02-27 Ziemowit Laski <zlaski@apple.com> + 2004-03-24 Ziemowit Laski <zlaski@apple.com> + + * Make-lang.in (cp/mangle.o): Depend on $(TARGET_H). + * mangle.c (write_type): Add call to 'mangle_fundamental_type' + target hook. + * tree.c (pod_type_p): Treat VECTOR_TYPEs as PODs. + +2004-08-19 Mark Mitchell <mark@codesourcery.com> + + PR c++/15890 + * pt.c (push_template_decl_real): Disallow template allocation + functions with fewer than two parameters. + +2004-08-18 Mark Mitchell <mark@codesourcery.com> + + PR c++/17068 + * pt.c (dependent_template_p): Treat IDENTIFIER_NODEs as + dependent. + +2004-08-17 Mark Mitchell <mark@codesourcery.com> + + PR c++/16246 + * pt.c (unify): Make sure that non-type arguments have the same + type as the corresponding parameter. + +2004-08-12 Mark Mitchell <mark@codesourcery.com> + + PR c++/16273 + * class.c (count_depth_data): New type. + (dfs_depth_post): New function. + (dfs_depth_q): Likewise. + (find_final_overrider_data_s): Change type of vpath. + Add vpath_list. + (dfs_find_final_overrider_1): New function. + (dfs_find_final_overrider): Use it. + (dfs_find_final_overrider_q): Adjust use of vpath. + (dfs_find_final_overrider_post): Likewise. + (find_final_overrider): Use dfs_depth. Allocate and deallocate + vpath_list. + +2004-08-12 Jan Beulich <jbeulich@novell.com> + + * parser.c (cp_parser_asm_definition): Properly consume scope operator + tokens preceding the clobbers. Don't check for scope operator + following inputs. Simplify inputs handling to match that now used for + clobbers. + +2004-08-11 Mark Mitchell <mark@codesourcery.com> + + PR c++/16698 + * except.c (build_throw): Allocate cleanup_type and the function + for __cxa_throw separately. + +2004-08-11 Mark Mitchell <mark@codesourcery.com> + + PR c++/16717 + * semantics.c (expand_body): Do not update static_ctors and + static_dtors here. + (expand_or_defer_fn): Do it here, instead. + + PR c++/16853 + * call.c (standard_conversion): Do not accept conversions between + pointers to members if the class types are unrelated. + + PR c++/16870 + * pt.c (tsubst): Just return the unknown_type_node. + + PR c++/16964 + * parser.c (cp_parser_class_specifier): Robustify. + + PR c++/16904 + * pt.c (tsubst_copy_and_build): Complain about invalid + qualification. + + PR c++/16929 + * pt.c (tsubst_default_argument): Clear out current_class_ptr and + current_class_ref while tsubsting. + +2004-08-01 Mark Mitchell <mark@codesourcery.com> + + PR c++/16224 + * name-lookup.c (decl_namespace): Remove. + (current_decl_namespace): Use decl_namespace_context instead of + decl_namespace. + (push_decl_namespace): Likewise. + (arg_assoc_class): Likewise. + (arg_assoc_type): Likewise. + * pt.c (check_specialization_namespace): New function. + (maybe_process_partial_specialization): Use it. + (register_specialization): Likewise. + +2004-08-01 Mark Mitchell <mark@codesourcery.com> + + PR c++/16489 + * cp-tree.h (DECL_INTEGRAL_CONSTANT_VAR_P): New macro. + * call.c (null_ptr_cst_p): Handle variables with constant + initializers. + * pt.c (convert_nontype_argument): Use + DECL_INTEGRAL_CONSTANT_VAR_P. + * semantics.c (finish_id_expression): Likewise. + + PR c++/16529 + * decl.c (duplicate_decls): Reject duplicate namespace + declarations. + + PR c++/16810 + * typeck.c (build_ptrmemfunc): Loosen assertion. + +2004-07-28 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/13092 + * init.c (build_offset_ref): Build SCOPE_REF with non-null + TREE_TYPE for non-dependent names. + * typeck.c (build_x_unary_op): Handle non-dependent SCOPE_REF. + * pt.c (type_dependent_expression_p): Handle SCOPE_REF with + unknown_type_node as its TREE_TYPE. + * cxx-pretty_print.c (pp_cxx_unqualified_id): Handle BASELINK. + * error.c (dump_decl) <SCOPE_REF case>: Use pp_expression. + (dump_expr) <SCOPE_REF case>: Likewise. + 2004-07-21 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> PR c++/16175 diff --git a/contrib/gcc/cp/Make-lang.in b/contrib/gcc/cp/Make-lang.in index 9f7ebfb..5888110 100644 --- a/contrib/gcc/cp/Make-lang.in +++ b/contrib/gcc/cp/Make-lang.in @@ -258,7 +258,8 @@ cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) cp/lex.h except.h toplev.h cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) tree-dump.h cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h integrate.h insn-config.h \ input.h $(PARAMS_H) debug.h tree-inline.h -cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h $(TM_P_H) +cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h \ + $(TARGET_H) $(TM_P_H) cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) diagnostic.h gt-cp-parser.h output.h diff --git a/contrib/gcc/cp/call.c b/contrib/gcc/cp/call.c index b1353f5..aeed315 100644 --- a/contrib/gcc/cp/call.c +++ b/contrib/gcc/cp/call.c @@ -1,6 +1,6 @@ /* Functions related to invoking methods and overloaded functions. Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) and modified by Brendan Kehoe (brendan@cygnus.com). @@ -86,7 +86,7 @@ static struct z_candidate *add_conv_candidate static struct z_candidate *add_function_candidate (struct z_candidate **, tree, tree, tree, tree, tree, int); static tree implicit_conversion (tree, tree, tree, int); -static tree standard_conversion (tree, tree, tree); +static tree standard_conversion (tree, tree, tree, int); static tree reference_binding (tree, tree, tree, int); static tree build_conv (enum tree_code, tree, tree); static bool is_subseq (tree, tree); @@ -373,6 +373,9 @@ struct z_candidate GTY(()) { #define USER_CONV_CAND(NODE) WRAPPER_ZC (TREE_OPERAND (NODE, 1)) #define USER_CONV_FN(NODE) (USER_CONV_CAND (NODE)->fn) +/* Returns true iff T is a null pointer constant in the sense of + [conv.ptr]. */ + bool null_ptr_cst_p (tree t) { @@ -380,6 +383,8 @@ null_ptr_cst_p (tree t) A null pointer constant is an integral constant expression (_expr.const_) rvalue of integer type that evaluates to zero. */ + if (DECL_INTEGRAL_CONSTANT_VAR_P (t)) + t = decl_constant_value (t); if (t == null_node || (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t))) return true; @@ -449,7 +454,7 @@ strip_top_quals (tree t) also pass the expression EXPR to convert from. */ static tree -standard_conversion (tree to, tree from, tree expr) +standard_conversion (tree to, tree from, tree expr, int flags) { enum tree_code fcode, tcode; tree conv; @@ -500,7 +505,7 @@ standard_conversion (tree to, tree from, tree expr) the standard conversion sequence to perform componentwise conversion. */ tree part_conv = standard_conversion - (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE); + (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, flags); if (part_conv) { @@ -573,6 +578,8 @@ standard_conversion (tree to, tree from, tree expr) TYPE_PTRMEM_POINTED_TO_TYPE (from)); conv = build_conv (PMEM_CONV, from, conv); } + else if (!same_type_p (fbase, tbase)) + return NULL; } else if (IS_AGGR_TYPE (TREE_TYPE (from)) && IS_AGGR_TYPE (TREE_TYPE (to)) @@ -685,7 +692,8 @@ standard_conversion (tree to, tree from, tree expr) && ((*targetm.vector_opaque_p) (from) || (*targetm.vector_opaque_p) (to))) return build_conv (STD_CONV, to, conv); - else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from) + else if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE) + && IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from) && is_properly_derived_from (from, to)) { if (TREE_CODE (conv) == RVALUE_CONV) @@ -1098,7 +1106,7 @@ implicit_conversion (tree to, tree from, tree expr, int flags) if (TREE_CODE (to) == REFERENCE_TYPE) conv = reference_binding (to, from, expr, flags); else - conv = standard_conversion (to, from, expr); + conv = standard_conversion (to, from, expr, flags); if (conv) return conv; @@ -2195,10 +2203,18 @@ any_strictly_viable (struct z_candidate *cands) return false; } +/* OBJ is being used in an expression like "OBJ.f (...)". In other + words, it is about to become the "this" pointer for a member + function call. Take the address of the object. */ + static tree build_this (tree obj) { - /* Fix this to work on non-lvalues. */ + /* In a template, we are only concerned about the type of the + expression, so we can take a shortcut. */ + if (processing_template_decl) + return build_address (obj); + return build_unary_op (ADDR_EXPR, obj, 0); } @@ -3270,7 +3286,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) } valid_operands: - result = fold (build (COND_EXPR, result_type, arg1, arg2, arg3)); + result = fold_if_not_in_template (build (COND_EXPR, result_type, + arg1, arg2, arg3)); /* We can't use result_type below, as fold might have returned a throw_expr. */ @@ -3554,20 +3571,6 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, if (overloaded_p) *overloaded_p = true; - if (warn_synth - && fnname == ansi_assopname (NOP_EXPR) - && DECL_ARTIFICIAL (cand->fn) - && candidates->next - && ! candidates->next->next) - { - warning ("using synthesized `%#D' for copy assignment", - cand->fn); - cp_warning_at (" where cfront would use `%#D'", - cand == candidates - ? candidates->next->fn - : candidates->fn); - } - return build_over_call (cand, LOOKUP_NORMAL); } @@ -3871,6 +3874,7 @@ check_constructor_callable (tree type, tree expr) build_tree_list (NULL_TREE, expr), TYPE_BINFO (type), LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING + | LOOKUP_NO_CONVERSION | LOOKUP_CONSTRUCTOR_CALLABLE); } @@ -6181,6 +6185,8 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup) /*fn=*/NULL_TREE, /*argnum=*/0, /*inner=*/-1, /*issue_conversion_warnings=*/true); + if (error_operand_p (expr)) + return error_mark_node; if (!real_lvalue_p (expr)) { tree init; diff --git a/contrib/gcc/cp/class.c b/contrib/gcc/cp/class.c index 9fa7f26..09daf11 100644 --- a/contrib/gcc/cp/class.c +++ b/contrib/gcc/cp/class.c @@ -1,6 +1,7 @@ /* Functions related to building classes and their related objects. Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -1847,6 +1848,36 @@ base_derived_from (tree derived, tree base) return false; } +typedef struct count_depth_data { + /* The depth of the current subobject, with "1" as the depth of the + most derived object in the hierarchy. */ + size_t depth; + /* The maximum depth found so far. */ + size_t max_depth; +} count_depth_data; + +/* Called from find_final_overrider via dfs_walk. */ + +static tree +dfs_depth_post (tree binfo ATTRIBUTE_UNUSED, void *data) +{ + count_depth_data *cd = (count_depth_data *) data; + if (cd->depth > cd->max_depth) + cd->max_depth = cd->depth; + cd->depth--; + return NULL_TREE; +} + +/* Called from find_final_overrider via dfs_walk. */ + +static tree +dfs_depth_q (tree derived, int i, void *data) +{ + count_depth_data *cd = (count_depth_data *) data; + cd->depth++; + return BINFO_BASETYPE (derived, i); +} + typedef struct find_final_overrider_data_s { /* The function for which we are trying to find a final overrider. */ tree fn; @@ -1856,70 +1887,74 @@ typedef struct find_final_overrider_data_s { tree most_derived_type; /* The candidate overriders. */ tree candidates; - /* Binfos which inherited virtually on the current path. */ - tree vpath; + /* Each entry in this array is the next-most-derived class for a + virtual base class along the current path. */ + tree *vpath_list; + /* A pointer one past the top of the VPATH_LIST. */ + tree *vpath; } find_final_overrider_data; -/* Called from find_final_overrider via dfs_walk. */ +/* Add the overrider along the current path to FFOD->CANDIDATES. + Returns true if an overrider was found; false otherwise. */ -static tree -dfs_find_final_overrider (tree binfo, void* data) +static bool +dfs_find_final_overrider_1 (tree binfo, + tree *vpath, + find_final_overrider_data *ffod) { - find_final_overrider_data *ffod = (find_final_overrider_data *) data; - - if (binfo == ffod->declaring_base) + tree method; + + /* If BINFO is not the most derived type, try a more derived class. + A definition there will overrider a definition here. */ + if (!same_type_p (BINFO_TYPE (binfo), ffod->most_derived_type)) { - /* We've found a path to the declaring base. Walk the path from - derived to base, looking for an overrider for FN. */ - tree path, probe, vpath; + tree derived; + + if (TREE_VIA_VIRTUAL (binfo)) + derived = *--vpath; + else + derived = BINFO_INHERITANCE_CHAIN (binfo); + if (dfs_find_final_overrider_1 (derived, vpath, ffod)) + return true; + } - /* Build the path, using the inheritance chain and record of - virtual inheritance. */ - for (path = NULL_TREE, probe = binfo, vpath = ffod->vpath;;) + method = look_for_overrides_here (BINFO_TYPE (binfo), ffod->fn); + if (method) + { + tree *candidate = &ffod->candidates; + + /* Remove any candidates overridden by this new function. */ + while (*candidate) { - path = tree_cons (NULL_TREE, probe, path); - if (same_type_p (BINFO_TYPE (probe), ffod->most_derived_type)) - break; - if (TREE_VIA_VIRTUAL (probe)) - { - probe = TREE_VALUE (vpath); - vpath = TREE_CHAIN (vpath); - } + /* If *CANDIDATE overrides METHOD, then METHOD + cannot override anything else on the list. */ + if (base_derived_from (TREE_VALUE (*candidate), binfo)) + return true; + /* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */ + if (base_derived_from (binfo, TREE_VALUE (*candidate))) + *candidate = TREE_CHAIN (*candidate); else - probe = BINFO_INHERITANCE_CHAIN (probe); - } - /* Now walk path, looking for overrides. */ - for (; path; path = TREE_CHAIN (path)) - { - tree method = look_for_overrides_here - (BINFO_TYPE (TREE_VALUE (path)), ffod->fn); - - if (method) - { - tree *candidate = &ffod->candidates; - path = TREE_VALUE (path); - - /* Remove any candidates overridden by this new function. */ - while (*candidate) - { - /* If *CANDIDATE overrides METHOD, then METHOD - cannot override anything else on the list. */ - if (base_derived_from (TREE_VALUE (*candidate), path)) - return NULL_TREE; - /* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */ - if (base_derived_from (path, TREE_VALUE (*candidate))) - *candidate = TREE_CHAIN (*candidate); - else - candidate = &TREE_CHAIN (*candidate); - } - - /* Add the new function. */ - ffod->candidates = tree_cons (method, path, ffod->candidates); - break; - } + candidate = &TREE_CHAIN (*candidate); } + + /* Add the new function. */ + ffod->candidates = tree_cons (method, binfo, ffod->candidates); + return true; } + return false; +} + +/* Called from find_final_overrider via dfs_walk. */ + +static tree +dfs_find_final_overrider (tree binfo, void* data) +{ + find_final_overrider_data *ffod = (find_final_overrider_data *) data; + + if (binfo == ffod->declaring_base) + dfs_find_final_overrider_1 (binfo, ffod->vpath, ffod); + return NULL_TREE; } @@ -1930,7 +1965,7 @@ dfs_find_final_overrider_q (tree derived, int ix, void *data) find_final_overrider_data *ffod = (find_final_overrider_data *) data; if (TREE_VIA_VIRTUAL (binfo)) - ffod->vpath = tree_cons (NULL_TREE, derived, ffod->vpath); + *ffod->vpath++ = derived; return binfo; } @@ -1940,8 +1975,8 @@ dfs_find_final_overrider_post (tree binfo, void *data) { find_final_overrider_data *ffod = (find_final_overrider_data *) data; - if (TREE_VIA_VIRTUAL (binfo) && TREE_CHAIN (ffod->vpath)) - ffod->vpath = TREE_CHAIN (ffod->vpath); + if (TREE_VIA_VIRTUAL (binfo)) + ffod->vpath--; return NULL_TREE; } @@ -1955,6 +1990,7 @@ static tree find_final_overrider (tree derived, tree binfo, tree fn) { find_final_overrider_data ffod; + count_depth_data cd; /* Getting this right is a little tricky. This is valid: @@ -1976,12 +2012,18 @@ find_final_overrider (tree derived, tree binfo, tree fn) different overriders along any two, then there is a problem. */ if (DECL_THUNK_P (fn)) fn = THUNK_TARGET (fn); - + + /* Determine the depth of the hierarchy. */ + cd.depth = 0; + cd.max_depth = 0; + dfs_walk (derived, dfs_depth_post, dfs_depth_q, &cd); + ffod.fn = fn; ffod.declaring_base = binfo; ffod.most_derived_type = BINFO_TYPE (derived); ffod.candidates = NULL_TREE; - ffod.vpath = NULL_TREE; + ffod.vpath_list = (tree *) xcalloc (cd.max_depth, sizeof (tree)); + ffod.vpath = ffod.vpath_list; dfs_walk_real (derived, dfs_find_final_overrider, @@ -1989,6 +2031,8 @@ find_final_overrider (tree derived, tree binfo, tree fn) dfs_find_final_overrider_q, &ffod); + free (ffod.vpath_list); + /* If there was no winner, issue an error message. */ if (!ffod.candidates || TREE_CHAIN (ffod.candidates)) { @@ -2072,6 +2116,9 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, also be converting to the return type of FN, we have to combine the two conversions here. */ tree fixed_offset, virtual_offset; + + over_return = TREE_TYPE (over_return); + base_return = TREE_TYPE (base_return); if (DECL_THUNK_P (fn)) { @@ -2089,32 +2136,51 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, virtual_offset = TREE_VALUE (purpose_member (BINFO_TYPE (virtual_offset), - CLASSTYPE_VBASECLASSES (TREE_TYPE (over_return)))); - else if (!same_type_p (TREE_TYPE (over_return), - TREE_TYPE (base_return))) + CLASSTYPE_VBASECLASSES (over_return))); + else if (!same_type_ignoring_top_level_qualifiers_p + (over_return, base_return)) { - /* There was no existing virtual thunk (which takes - precedence). */ - tree thunk_binfo; - base_kind kind; + /* There was no existing virtual thunk (which takes + precedence). So find the binfo of the base function's + return type within the overriding function's return type. + We cannot call lookup base here, because we're inside a + dfs_walk, and will therefore clobber the BINFO_MARKED + flags. Fortunately we know the covariancy is valid (it + has already been checked), so we can just iterate along + the binfos, which have been chained in inheritance graph + order. Of course it is lame that we have to repeat the + search here anyway -- we should really be caching pieces + of the vtable and avoiding this repeated work. */ + tree thunk_binfo, base_binfo; + + /* Find the base binfo within the overriding function's + return type. We will always find a thunk_binfo, except + when the covariancy is invalid (which we will have + already diagnosed). */ + for (base_binfo = TYPE_BINFO (base_return), + thunk_binfo = TYPE_BINFO (over_return); + thunk_binfo; + thunk_binfo = TREE_CHAIN (thunk_binfo)) + if (same_type_p (BINFO_TYPE (thunk_binfo), + BINFO_TYPE (base_binfo))) + break; - thunk_binfo = lookup_base (TREE_TYPE (over_return), - TREE_TYPE (base_return), - ba_check | ba_quiet, &kind); - - if (thunk_binfo && (kind == bk_via_virtual - || !BINFO_OFFSET_ZEROP (thunk_binfo))) + /* See if virtual inheritance is involved. */ + for (virtual_offset = thunk_binfo; + virtual_offset; + virtual_offset = BINFO_INHERITANCE_CHAIN (virtual_offset)) + if (TREE_VIA_VIRTUAL (virtual_offset)) + break; + + if (virtual_offset + || (thunk_binfo && !BINFO_OFFSET_ZEROP (thunk_binfo))) { tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo)); - if (kind == bk_via_virtual) + if (virtual_offset) { - /* We convert via virtual base. Find the virtual - base and adjust the fixed offset to be from there. */ - while (!TREE_VIA_VIRTUAL (thunk_binfo)) - thunk_binfo = BINFO_INHERITANCE_CHAIN (thunk_binfo); - - virtual_offset = thunk_binfo; + /* We convert via virtual base. Adjust the fixed + offset to be from there. */ offset = size_diffop (offset, convert (ssizetype, BINFO_OFFSET (virtual_offset))); @@ -5174,6 +5240,7 @@ finish_struct (tree t, tree attributes) { finish_struct_methods (t); TYPE_SIZE (t) = bitsize_zero_node; + TYPE_SIZE_UNIT (t) = size_zero_node; } else finish_struct_1 (t); diff --git a/contrib/gcc/cp/cp-tree.h b/contrib/gcc/cp/cp-tree.h index b3ceab4..ed33f32 100644 --- a/contrib/gcc/cp/cp-tree.h +++ b/contrib/gcc/cp/cp-tree.h @@ -1,6 +1,6 @@ /* Definitions for C++ parsing and type checking. Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -1899,6 +1899,23 @@ struct lang_decl GTY(()) #define DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(NODE) \ (TREE_LANG_FLAG_2 (VAR_DECL_CHECK (NODE))) +/* Nonzero for a VAR_DECL that can be used in an integral constant + expression. + + [expr.const] + + An integral constant-expression can only involve ... const + variables of static or enumeration types initialized with + constant expressions ... + + The standard does not require that the expression be non-volatile. + G++ implements the proposed correction in DR 457. */ +#define DECL_INTEGRAL_CONSTANT_VAR_P(NODE) \ + (TREE_CODE (NODE) == VAR_DECL \ + && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (NODE)) \ + && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (NODE)) \ + && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (NODE)) + /* Nonzero if the DECL was initialized in the class definition itself, rather than outside the class. This is used for both static member VAR_DECLS, and FUNTION_DECLS that are defined in the class. */ @@ -2900,7 +2917,8 @@ struct lang_decl GTY(()) #define THUNK_ALIAS(DECL) \ (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.u.thunk_alias) -/* For thunk NODE, this is the FUNCTION_DECL thunked to. */ +/* For thunk NODE, this is the FUNCTION_DECL thunked to. It is + possible for the target to be a thunk too. */ #define THUNK_TARGET(NODE) \ (DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes) @@ -3711,6 +3729,7 @@ extern tree cp_fname_init (const char *, tree *); extern tree check_elaborated_type_specifier (enum tag_types, tree, bool); extern tree cxx_builtin_type_decls (void); extern void warn_extern_redeclared_static (tree, tree); +extern tree check_var_type (tree, tree); extern bool have_extern_spec; @@ -3903,7 +3922,6 @@ 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 void maybe_check_template_type (tree); extern tree most_specialized_instantiation (tree); extern void print_candidates (tree); extern int instantiate_pending_templates (void); @@ -3997,6 +4015,7 @@ extern tree adjust_result_of_qualified_name_lookup (tree, tree, tree); extern tree copied_binfo (tree, tree); extern tree original_binfo (tree, tree); +extern int shared_member_p (tree); /* in semantics.c */ extern void push_deferring_access_checks (deferring_kind); @@ -4176,6 +4195,7 @@ extern int cp_cannot_inline_tree_fn (tree*); extern tree cp_add_pending_fn_decls (void*,tree); extern int cp_is_overload_p (tree); extern int cp_auto_var_in_fn_p (tree,tree); +extern tree fold_if_not_in_template (tree); extern tree cp_copy_res_decl_for_inlining (tree, tree, tree, void*, int*, tree); diff --git a/contrib/gcc/cp/cvt.c b/contrib/gcc/cp/cvt.c index 48be5c5..95fce07 100644 --- a/contrib/gcc/cp/cvt.c +++ b/contrib/gcc/cp/cvt.c @@ -793,6 +793,11 @@ convert_to_void (tree expr, const char *implicit) return expr; if (invalid_nonstatic_memfn_p (expr)) return error_mark_node; + if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR) + { + error ("pseudo-destructor is not called"); + return error_mark_node; + } if (VOID_TYPE_P (TREE_TYPE (expr))) return expr; switch (TREE_CODE (expr)) diff --git a/contrib/gcc/cp/cxx-pretty-print.c b/contrib/gcc/cp/cxx-pretty-print.c index 53c677a..e4d304a 100644 --- a/contrib/gcc/cp/cxx-pretty-print.c +++ b/contrib/gcc/cp/cxx-pretty-print.c @@ -177,6 +177,10 @@ pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t) pp_cxx_template_id (pp, t); break; + case BASELINK: + pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t)); + break; + case RECORD_TYPE: case UNION_TYPE: case ENUMERAL_TYPE: diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c index eb34d39..6c7cece 100644 --- a/contrib/gcc/cp/decl.c +++ b/contrib/gcc/cp/decl.c @@ -1,6 +1,6 @@ /* Process declarations and variables for C++ compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -119,6 +119,7 @@ static void initialize_local_var (tree, tree); static void expand_static_init (tree, tree); static tree next_initializable_field (tree); static tree reshape_init (tree, tree *); +static bool reshape_init_array (tree, tree, tree *, tree); static tree build_typename_type (tree, tree, tree); /* Erroneous argument lists can use this *IFF* they do not modify it. */ @@ -1067,6 +1068,12 @@ decls_match (tree newdecl, tree olddecl) } else { + /* 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) types_match = TREE_TYPE (olddecl) == error_mark_node; else if (TREE_TYPE (olddecl) == NULL_TREE) @@ -1410,19 +1417,32 @@ duplicate_decls (tree newdecl, tree olddecl) /* One of the declarations is a template instantiation, and the other is not a template at all. That's OK. */ return NULL_TREE; - else if (TREE_CODE (newdecl) == NAMESPACE_DECL - && DECL_NAMESPACE_ALIAS (newdecl) - && DECL_NAMESPACE_ALIAS (newdecl) == DECL_NAMESPACE_ALIAS (olddecl)) - /* In [namespace.alias] we have: - - In a declarative region, a namespace-alias-definition can be - used to redefine a namespace-alias declared in that declarative - region to refer only to the namespace to which it already - refers. - - Therefore, if we encounter a second alias directive for the same - alias, we can just ignore the second directive. */ - return olddecl; + else if (TREE_CODE (newdecl) == NAMESPACE_DECL) + { + /* In [namespace.alias] we have: + + In a declarative region, a namespace-alias-definition can be + used to redefine a namespace-alias declared in that declarative + region to refer only to the namespace to which it already + refers. + + Therefore, if we encounter a second alias directive for the same + alias, we can just ignore the second directive. */ + if (DECL_NAMESPACE_ALIAS (newdecl) + && (DECL_NAMESPACE_ALIAS (newdecl) + == DECL_NAMESPACE_ALIAS (olddecl))) + return olddecl; + /* [namespace.alias] + + A namespace-name or namespace-alias shall not be declared as + the name of any other entity in the same declarative region. + A namespace-name defined at global scope shall not be + declared as the name of any other entity in any glogal scope + of the program. */ + error ("declaration of `namespace %D' conflicts with", newdecl); + cp_error_at ("previous declaration of `namespace %D' here", olddecl); + return error_mark_node; + } else { const char *errmsg = redeclaration_error_message (newdecl, olddecl); @@ -2009,7 +2029,8 @@ redeclaration_error_message (tree newdecl, tree olddecl) /* If both functions come from different namespaces, this is not a redeclaration - this is a conflict with a used function. */ if (DECL_NAMESPACE_SCOPE_P (olddecl) - && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)) + && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl) + && ! decls_match (olddecl, newdecl)) return "`%D' conflicts with used function"; /* We'll complain about linkage mismatches in @@ -3690,12 +3711,12 @@ start_decl (tree declarator, deprecated_state = DEPRECATED_NORMAL; if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE) - return NULL_TREE; + return error_mark_node; type = TREE_TYPE (decl); if (type == error_mark_node) - return NULL_TREE; + return error_mark_node; context = DECL_CONTEXT (decl); @@ -4183,6 +4204,62 @@ next_initializable_field (tree field) return field; } +/* Subroutine of reshape_init. Reshape the constructor for an array. INITP + is the pointer to the old constructor list (to the CONSTRUCTOR_ELTS of + the CONSTRUCTOR we are processing), while NEW_INIT is the CONSTRUCTOR we + are building. + ELT_TYPE is the element type of the array. MAX_INDEX is an INTEGER_CST + representing the size of the array minus one (the maximum index), or + NULL_TREE if the array was declared without specifying the size. */ + +static bool +reshape_init_array (tree elt_type, tree max_index, + tree *initp, tree new_init) +{ + bool sized_array_p = (max_index != NULL_TREE); + unsigned HOST_WIDE_INT max_index_cst = 0; + unsigned HOST_WIDE_INT index; + + if (sized_array_p) + { + if (host_integerp (max_index, 1)) + max_index_cst = tree_low_cst (max_index, 1); + /* sizetype is sign extended, not zero extended. */ + else + max_index_cst = tree_low_cst (convert (size_type_node, max_index), 1); + } + + /* Loop until there are no more initializers. */ + for (index = 0; + *initp && (!sized_array_p || index <= max_index_cst); + ++index) + { + tree element_init; + tree designated_index; + + element_init = reshape_init (elt_type, initp); + if (element_init == error_mark_node) + return false; + TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init); + CONSTRUCTOR_ELTS (new_init) = element_init; + designated_index = TREE_PURPOSE (element_init); + if (designated_index) + { + /* Handle array designated initializers (GNU extension). */ + if (TREE_CODE (designated_index) == IDENTIFIER_NODE) + { + error ("name `%D' used in a GNU-style designated " + "initializer for an array", designated_index); + TREE_PURPOSE (element_init) = NULL_TREE; + } + else + abort (); + } + } + + return true; +} + /* Undo the brace-elision allowed by [dcl.init.aggr] in a brace-enclosed aggregate initializer. @@ -4206,6 +4283,7 @@ reshape_init (tree type, tree *initp) tree old_init_value; tree new_init; bool brace_enclosed_p; + bool string_init_p; old_init = *initp; old_init_value = (TREE_CODE (*initp) == TREE_LIST @@ -4270,6 +4348,7 @@ reshape_init (tree type, tree *initp) return old_init; } + string_init_p = false; if (TREE_CODE (old_init_value) == STRING_CST && TREE_CODE (type) == ARRAY_TYPE && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type)))) @@ -4284,6 +4363,7 @@ reshape_init (tree type, tree *initp) /* Move past the initializer. */ *initp = TREE_CHAIN (old_init); TREE_CHAIN (old_init) = NULL_TREE; + string_init_p = true; } else { @@ -4351,38 +4431,15 @@ reshape_init (tree type, tree *initp) } else if ((TREE_CODE (type) == ARRAY_TYPE)|| (TREE_CODE (type) == VECTOR_TYPE)) { - tree index; tree max_index; /* If the bound of the array is known, take no more initializers than are allowed. */ max_index = ((TYPE_DOMAIN (type) && (TREE_CODE (type) == ARRAY_TYPE)) ? array_type_nelts (type) : NULL_TREE); - /* Loop through the array elements, gathering initializers. */ - for (index = size_zero_node; - *initp && (!max_index || !tree_int_cst_lt (max_index, index)); - index = size_binop (PLUS_EXPR, index, size_one_node)) - { - tree element_init; - - element_init = reshape_init (TREE_TYPE (type), initp); - if (element_init == error_mark_node) - return error_mark_node; - TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init); - CONSTRUCTOR_ELTS (new_init) = element_init; - if (TREE_PURPOSE (element_init)) - { - tree next_index = TREE_PURPOSE (element_init); - if (TREE_CODE (next_index) == IDENTIFIER_NODE) - { - error ("name `%D' used in a GNU-style designated " - "initializer for an array", next_index); - TREE_PURPOSE (element_init) = NULL_TREE; - } - else - index = next_index; - } - } + if (!reshape_init_array (TREE_TYPE (type), max_index, + initp, new_init)) + return error_mark_node; } else abort (); @@ -4395,10 +4452,15 @@ reshape_init (tree type, tree *initp) new_init = build_tree_list (TREE_PURPOSE (old_init), new_init); } - /* If this was a brace-enclosed initializer and all of the - initializers were not used up, there is a problem. */ - if (brace_enclosed_p && *initp) - error ("too many initializers for `%T'", type); + /* If there are more initializers than necessary, issue a + diagnostic. */ + if (*initp) + { + if (brace_enclosed_p) + error ("too many initializers for `%T'", type); + else if (warn_missing_braces && !string_init_p) + warning ("missing braces around initializer"); + } return new_init; } @@ -4723,6 +4785,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) tree cleanup; const char *asmspec = NULL; int was_readonly = 0; + bool var_definition_p = false; if (decl == error_mark_node) return; @@ -4875,6 +4938,11 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) /* Remember that the initialization for this variable has taken place. */ DECL_INITIALIZED_P (decl) = 1; + /* This declaration is the definition of this variable, + unless we are initializing a static data member within + the class specifier. */ + if (!DECL_EXTERNAL (decl)) + var_definition_p = true; } /* If the variable has an array type, lay out the type, even if there is no initializer. It is valid to index through the @@ -4949,8 +5017,16 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) initialize_local_var (decl, init); } - if (TREE_STATIC (decl)) - expand_static_init (decl, init); + /* If a variable is defined, and then a subsequent + definintion with external linkage is encountered, we will + get here twice for the same variable. We want to avoid + calling expand_static_init more than once. For variables + that are not static data members, we can call + expand_static_init only when we actually process the + initializer. It is not legal to redeclare a static data + member, so this issue does not arise in that case. */ + if (var_definition_p && TREE_STATIC (decl)) + expand_static_init (decl, init); } finish_end0: @@ -6317,6 +6393,32 @@ check_special_function_return_type (special_function_kind sfk, return type; } +/* A variable or data member (whose unqualified name is IDENTIFIER) + has been declared with the indicated TYPE. If the TYPE is not + acceptable, issue an error message and return a type to use for + error-recovery purposes. */ + +tree +check_var_type (tree identifier, tree type) +{ + if (VOID_TYPE_P (type)) + { + if (!identifier) + error ("unnamed variable or field declared void"); + else if (TREE_CODE (identifier) == IDENTIFIER_NODE) + { + if (IDENTIFIER_OPNAME_P (identifier)) + abort (); + error ("variable or field `%E' declared void", identifier); + } + else + error ("variable or field declared void"); + type = integer_type_node; + } + + return type; +} + /* Given declspecs and a declarator (abstract or otherwise), determine the name and type of the object declared and construct a DECL node for it. @@ -8016,30 +8118,25 @@ grokdeclarator (tree declarator, && ! bitfield) { error ("abstract declarator `%T' used as declaration", type); - declarator = make_anon_name (); + return error_mark_node; } - /* `void' at top level (not within pointer) - is allowed only in typedefs or type names. - We don't complain about parms either, but that is because - a better error message can be made later. */ - - if (TREE_CODE (type) == VOID_TYPE && decl_context != PARM) + /* Only functions may be declared using an operator-function-id. */ + if (declarator + && TREE_CODE (declarator) == IDENTIFIER_NODE + && IDENTIFIER_OPNAME_P (declarator) + && TREE_CODE (type) != FUNCTION_TYPE + && TREE_CODE (type) != METHOD_TYPE) { - if (! declarator) - error ("unnamed variable or field declared void"); - else if (TREE_CODE (declarator) == IDENTIFIER_NODE) - { - if (IDENTIFIER_OPNAME_P (declarator)) - abort (); - else - error ("variable or field `%s' declared void", name); - } - else - error ("variable or field declared void"); - type = integer_type_node; + error ("declaration of `%D' as non-function", declarator); + return error_mark_node; } + /* We don't check parameter types here because we can emit a better + error message later. */ + if (decl_context != PARM) + type = check_var_type (declarator, type); + /* Now create the decl, which may be a VAR_DECL, a PARM_DECL or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE. */ @@ -9848,7 +9945,14 @@ finish_enum (tree enumtype) underlying type in the range bmin to bmax, where bmin and bmax are, respectively, the smallest and largest values of the smallest bit- field that can store emin and emax. */ - TYPE_PRECISION (enumtype) = precision; + + /* The middle-end currently assumes that types with TYPE_PRECISION + narrower than their underlying type are suitably zero or sign + extended to fill their mode. g++ doesn't make these guarantees. + Until the middle-end can represent such paradoxical types, we + set the TYPE_PRECISON to the width of the underlying type. */ + TYPE_PRECISION (enumtype) = TYPE_PRECISION (underlying_type); + set_min_and_max_values_for_integral_type (enumtype, precision, unsignedp); /* [dcl.enum] diff --git a/contrib/gcc/cp/decl2.c b/contrib/gcc/cp/decl2.c index 4e8c2f8..09fe5dd 100644 --- a/contrib/gcc/cp/decl2.c +++ b/contrib/gcc/cp/decl2.c @@ -1203,9 +1203,15 @@ build_anon_union_vars (tree object) void finish_anon_union (tree anon_union_decl) { - tree type = TREE_TYPE (anon_union_decl); + tree type; tree main_decl; - bool public_p = TREE_PUBLIC (anon_union_decl); + bool public_p; + + if (anon_union_decl == error_mark_node) + return; + + type = TREE_TYPE (anon_union_decl); + public_p = TREE_PUBLIC (anon_union_decl); /* The VAR_DECL's context is the same as the TYPE's context. */ DECL_CONTEXT (anon_union_decl) = DECL_CONTEXT (TYPE_NAME (type)); diff --git a/contrib/gcc/cp/error.c b/contrib/gcc/cp/error.c index 9c9561f..5b83c60 100644 --- a/contrib/gcc/cp/error.c +++ b/contrib/gcc/cp/error.c @@ -815,9 +815,7 @@ dump_decl (tree t, int flags) break; case SCOPE_REF: - dump_decl (TREE_OPERAND (t, 0), flags & ~TFF_DECL_SPECIFIERS); - pp_colon_colon (cxx_pp); - dump_decl (TREE_OPERAND (t, 1), flags); + pp_expression (cxx_pp, t); break; case ARRAY_REF: @@ -1489,6 +1487,7 @@ dump_expr (tree t, int flags) case CEIL_DIV_EXPR: case FLOOR_DIV_EXPR: case ROUND_DIV_EXPR: + case RDIV_EXPR: dump_binary_op ("/", t, flags); break; @@ -1736,9 +1735,7 @@ dump_expr (tree t, int flags) break; case SCOPE_REF: - dump_type (TREE_OPERAND (t, 0), flags); - pp_colon_colon (cxx_pp); - dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); + pp_expression (cxx_pp, t); break; case CAST_EXPR: @@ -2410,6 +2407,9 @@ cp_error_at (const char *msgid, ...) va_start (ap, msgid); diagnostic_set_info (&diagnostic, msgid, &ap, + input_location, DK_ERROR); + cp_diagnostic_starter (global_dc, &diagnostic); + diagnostic_set_info (&diagnostic, msgid, &ap, location_of (here), DK_ERROR); report_diagnostic (&diagnostic); va_end (ap); diff --git a/contrib/gcc/cp/except.c b/contrib/gcc/cp/except.c index c8112d1..e61e652 100644 --- a/contrib/gcc/cp/except.c +++ b/contrib/gcc/cp/except.c @@ -594,9 +594,9 @@ build_throw (tree exp) fn = push_throw_library_fn (fn, tmp); } else if (really_overloaded_fn (fn)) - {
+ { error ("`%D' should never be overloaded", fn); - return error_mark_node;
+ return error_mark_node; } fn = OVL_CURRENT (fn); exp = build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE)); @@ -610,18 +610,18 @@ build_throw (tree exp) tree temp_expr, allocate_expr; bool elided; + /* The CLEANUP_TYPE is the internal type of a destructor. */ + if (!cleanup_type) + { + tmp = void_list_node; + tmp = tree_cons (NULL_TREE, ptr_type_node, tmp); + tmp = build_function_type (void_type_node, tmp); + cleanup_type = build_pointer_type (tmp); + } + fn = get_identifier ("__cxa_throw"); if (!get_global_value_if_present (fn, &fn)) { - /* The CLEANUP_TYPE is the internal type of a destructor. */ - if (cleanup_type == NULL_TREE) - { - tmp = void_list_node; - tmp = tree_cons (NULL_TREE, ptr_type_node, tmp); - tmp = build_function_type (void_type_node, tmp); - cleanup_type = build_pointer_type (tmp); - } - /* Declare void __cxa_throw (void*, void*, void (*)(void*)). */ /* ??? Second argument is supposed to be "std::type_info*". */ tmp = void_list_node; @@ -631,7 +631,7 @@ build_throw (tree exp) tmp = build_function_type (void_type_node, tmp); fn = push_throw_library_fn (fn, tmp); } - + /* throw expression */ /* First, decay it. */ exp = decay_conversion (exp); diff --git a/contrib/gcc/cp/g++spec.c b/contrib/gcc/cp/g++spec.c index e6c9ee6..22dffb1 100644 --- a/contrib/gcc/cp/g++spec.c +++ b/contrib/gcc/cp/g++spec.c @@ -167,6 +167,9 @@ lang_specific_driver (int *in_argc, const char *const **in_argv, } saw_speclang = 1; } + /* Unrecognized libraries (e.g. -lfoo) may require libstdc++. */ + else if (strncmp (argv[i], "-l", 2) == 0) + library = (library == 0) ? 1 : library; else if (((argv[i][2] == '\0' && strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL) || strcmp (argv[i], "-Xlinker") == 0 diff --git a/contrib/gcc/cp/init.c b/contrib/gcc/cp/init.c index c81736c..732d4a0 100644 --- a/contrib/gcc/cp/init.c +++ b/contrib/gcc/cp/init.c @@ -217,7 +217,6 @@ build_zero_init (tree type, tree nelts, bool static_storage_p) } else if (TREE_CODE (type) == ARRAY_TYPE) { - tree index; tree max_index; tree inits; @@ -231,14 +230,16 @@ build_zero_init (tree type, tree nelts, bool static_storage_p) /* A zero-sized array, which is accepted as an extension, will have an upper bound of -1. */ if (!tree_int_cst_equal (max_index, integer_minus_one_node)) - for (index = size_zero_node; - !tree_int_cst_lt (max_index, index); - index = size_binop (PLUS_EXPR, index, size_one_node)) - inits = tree_cons (index, - build_zero_init (TREE_TYPE (type), - /*nelts=*/NULL_TREE, - static_storage_p), - inits); + { + tree elt_init = build_zero_init (TREE_TYPE (type), + /*nelts=*/NULL_TREE, + static_storage_p); + tree range = build (RANGE_EXPR, + sizetype, size_zero_node, max_index); + + inits = tree_cons (range, elt_init, inits); + } + CONSTRUCTOR_ELTS (init) = nreverse (inits); } else if (TREE_CODE (type) == REFERENCE_TYPE) @@ -1378,7 +1379,7 @@ build_offset_ref (tree type, tree name, bool address_p) if (TREE_CODE (name) == TEMPLATE_DECL) return name; - if (processing_template_decl || uses_template_parms (type)) + if (dependent_type_p (type) || type_dependent_expression_p (name)) return build_min_nt (SCOPE_REF, type, name); if (TREE_CODE (name) == TEMPLATE_ID_EXPR) @@ -1442,6 +1443,7 @@ build_offset_ref (tree type, tree name, bool address_p) return error_mark_node; } + /* Set up BASEBINFO for member lookup. */ decl = maybe_dummy_object (type, &basebinfo); if (BASELINK_P (name) || DECL_P (name)) @@ -1621,21 +1623,23 @@ decl_constant_value (tree decl) TREE_OPERAND (decl, 0), d1, d2); } - if (DECL_P (decl) - && (/* Enumeration constants are constant. */ - TREE_CODE (decl) == CONST_DECL - /* And so are variables with a 'const' type -- unless they - are also 'volatile'. */ - || CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl))) - && DECL_INITIAL (decl) - && DECL_INITIAL (decl) != error_mark_node - /* This is invalid if initial value is not constant. - If it has either a function call, a memory reference, - or a variable, then re-evaluating it could give different results. */ - && TREE_CONSTANT (DECL_INITIAL (decl)) - /* Check for cases where this is sub-optimal, even though valid. */ - && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR) - return DECL_INITIAL (decl); + while (DECL_P (decl) + && (/* Enumeration constants are constant. */ + TREE_CODE (decl) == CONST_DECL + /* And so are variables with a 'const' type -- unless they + are also 'volatile'. */ + || CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl))) + && DECL_INITIAL (decl) + && DECL_INITIAL (decl) != error_mark_node + /* This is invalid if initial value is not constant. If it + has either a function call, a memory reference, or a + variable, then re-evaluating it could give different + results. */ + && TREE_CONSTANT (DECL_INITIAL (decl)) + /* Check for cases where this is sub-optimal, even though + valid. */ + && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR) + decl = DECL_INITIAL (decl); return decl; } @@ -2540,6 +2544,9 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) tree atype = TREE_TYPE (base); /* The type of an element in the array. */ tree type = TREE_TYPE (atype); + /* The element type reached after removing all outer array + types. */ + tree inner_elt_type; /* The type of a pointer to an element in the array. */ tree ptype; tree stmt_expr; @@ -2556,15 +2563,17 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) if (maxindex == NULL_TREE || maxindex == error_mark_node) return error_mark_node; + inner_elt_type = strip_array_types (atype); if (init && (from_array == 2 - ? (!CLASS_TYPE_P (type) || !TYPE_HAS_COMPLEX_ASSIGN_REF (type)) + ? (!CLASS_TYPE_P (inner_elt_type) + || !TYPE_HAS_COMPLEX_ASSIGN_REF (inner_elt_type)) : !TYPE_NEEDS_CONSTRUCTING (type)) && ((TREE_CODE (init) == CONSTRUCTOR /* Don't do this if the CONSTRUCTOR might contain something that might throw and require us to clean up. */ && (CONSTRUCTOR_ELTS (init) == NULL_TREE - || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (target_type (type)))) + || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_elt_type))) || from_array)) { /* Do non-default initialization of POD arrays resulting from diff --git a/contrib/gcc/cp/mangle.c b/contrib/gcc/cp/mangle.c index 760d8b3..a92f2b4 100644 --- a/contrib/gcc/cp/mangle.c +++ b/contrib/gcc/cp/mangle.c @@ -59,6 +59,7 @@ #include "toplev.h" #include "varray.h" #include "flags.h" +#include "target.h" /* Debugging support. */ @@ -1497,12 +1498,24 @@ write_type (tree type) case BOOLEAN_TYPE: case INTEGER_TYPE: /* Includes wchar_t. */ case REAL_TYPE: + { + /* Handle any target-specific fundamental types. */ + const char *target_mangling + = targetm.mangle_fundamental_type (type); + + if (target_mangling) + { + write_string (target_mangling); + return; + } + /* If this is a typedef, TYPE may not be one of the standard builtin type nodes, but an alias of one. Use TYPE_MAIN_VARIANT to get to the underlying builtin type. */ write_builtin_type (TYPE_MAIN_VARIANT (type)); ++is_builtin_type; break; + } case COMPLEX_TYPE: write_char ('C'); diff --git a/contrib/gcc/cp/method.c b/contrib/gcc/cp/method.c index 0f72dc7..ef69c37 100644 --- a/contrib/gcc/cp/method.c +++ b/contrib/gcc/cp/method.c @@ -357,6 +357,10 @@ use_thunk (tree thunk_fndecl, bool emit_p) There's no need to process this thunk again. */ return; + if (DECL_THUNK_P (function)) + /* The target is itself a thunk, process it now. */ + use_thunk (function, emit_p); + /* Thunks are always addressable; they only appear in vtables. */ TREE_ADDRESSABLE (thunk_fndecl) = 1; @@ -583,14 +587,14 @@ do_build_copy_constructor (tree fndecl) for (; fields; fields = TREE_CHAIN (fields)) { - tree init; + tree init = parm; tree field = fields; tree expr_type; if (TREE_CODE (field) != FIELD_DECL) continue; - init = parm; + expr_type = TREE_TYPE (field); if (DECL_NAME (field)) { if (VFIELD_NAME_P (DECL_NAME (field))) @@ -600,9 +604,7 @@ do_build_copy_constructor (tree fndecl) if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field) continue; } - else if ((t = TREE_TYPE (field)) != NULL_TREE - && ANON_AGGR_TYPE_P (t) - && TYPE_FIELDS (t) != NULL_TREE) + else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type)) /* Just use the field; anonymous types can't have nontrivial copy ctors or assignment ops. */; else @@ -613,14 +615,19 @@ do_build_copy_constructor (tree fndecl) the field is "T", then the type will usually be "const T". (There are no cv-qualified variants of reference types.) */ - expr_type = TREE_TYPE (field); if (TREE_CODE (expr_type) != REFERENCE_TYPE) - expr_type = cp_build_qualified_type (expr_type, cvquals); + { + int quals = cvquals; + + if (DECL_MUTABLE_P (field)) + quals &= ~TYPE_QUAL_CONST; + expr_type = cp_build_qualified_type (expr_type, quals); + } + init = build (COMPONENT_REF, expr_type, init, field); init = build_tree_list (NULL_TREE, init); - member_init_list - = tree_cons (field, init, member_init_list); + member_init_list = tree_cons (field, init, member_init_list); } finish_mem_initializers (member_init_list); } @@ -675,26 +682,27 @@ do_build_assign_ref (tree fndecl) fields; fields = TREE_CHAIN (fields)) { - tree comp, init, t; + tree comp = current_class_ref; + tree init = parm; tree field = fields; + tree expr_type; + int quals; if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field)) continue; - if (CP_TYPE_CONST_P (TREE_TYPE (field))) + expr_type = TREE_TYPE (field); + if (CP_TYPE_CONST_P (expr_type)) { error ("non-static const member `%#D', can't use default assignment operator", field); continue; } - else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE) + else if (TREE_CODE (expr_type) == REFERENCE_TYPE) { error ("non-static reference member `%#D', can't use default assignment operator", field); continue; } - comp = current_class_ref; - init = parm; - if (DECL_NAME (field)) { if (VFIELD_NAME_P (DECL_NAME (field))) @@ -704,24 +712,27 @@ do_build_assign_ref (tree fndecl) if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field) continue; } - else if ((t = TREE_TYPE (field)) != NULL_TREE - && ANON_AGGR_TYPE_P (t) - && TYPE_FIELDS (t) != NULL_TREE) + else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type)) /* Just use the field; anonymous types can't have nontrivial copy ctors or assignment ops. */; else continue; comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field); - init = build (COMPONENT_REF, - cp_build_qualified_type (TREE_TYPE (field), cvquals), - init, field); + + /* Compute the type of init->field */ + quals = cvquals; + if (DECL_MUTABLE_P (field)) + quals &= ~TYPE_QUAL_CONST; + expr_type = cp_build_qualified_type (expr_type, quals); + + init = build (COMPONENT_REF, expr_type, init, field); if (DECL_NAME (field)) - finish_expr_stmt (build_modify_expr (comp, NOP_EXPR, init)); + init = build_modify_expr (comp, NOP_EXPR, init); else - finish_expr_stmt (build (MODIFY_EXPR, TREE_TYPE (comp), comp, - init)); + init = build (MODIFY_EXPR, TREE_TYPE (comp), comp, init); + finish_expr_stmt (init); } } finish_return_stmt (current_class_ref); diff --git a/contrib/gcc/cp/name-lookup.c b/contrib/gcc/cp/name-lookup.c index a4e996f..3e79d3e 100644 --- a/contrib/gcc/cp/name-lookup.c +++ b/contrib/gcc/cp/name-lookup.c @@ -1,5 +1,5 @@ /* Definitions for C++ name lookup routines. - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> This file is part of GCC. @@ -2018,7 +2018,8 @@ push_overloaded_decl (tree decl, int flags) if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp) && !(flags & PUSH_USING) && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), - TYPE_ARG_TYPES (TREE_TYPE (decl)))) + TYPE_ARG_TYPES (TREE_TYPE (decl))) + && ! decls_match (fn, decl)) error ("`%#D' conflicts with previous using declaration `%#D'", decl, fn); @@ -2804,6 +2805,7 @@ push_class_level_binding (tree name, tree x) || TREE_CODE (x) == CONST_DECL || (TREE_CODE (x) == TYPE_DECL && !DECL_SELF_REFERENCE_P (x)) + || DECL_CLASS_TEMPLATE_P (x) /* A data member of an anonymous union. */ || (TREE_CODE (x) == FIELD_DECL && DECL_CONTEXT (x) != current_class_type)) @@ -2968,27 +2970,6 @@ set_namespace_binding (tree name, tree scope, tree val) timevar_pop (TV_NAME_LOOKUP); } -/* Compute the namespace where a declaration is defined. */ - -static tree -decl_namespace (tree decl) -{ - timevar_push (TV_NAME_LOOKUP); - if (TYPE_P (decl)) - decl = TYPE_STUB_DECL (decl); - while (DECL_CONTEXT (decl)) - { - decl = DECL_CONTEXT (decl); - if (TREE_CODE (decl) == NAMESPACE_DECL) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); - if (TYPE_P (decl)) - decl = TYPE_STUB_DECL (decl); - my_friendly_assert (DECL_P (decl), 390); - } - - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, global_namespace); -} - /* Set the context of a declaration to scope. Complain if we are not outside scope. */ @@ -3057,9 +3038,9 @@ current_decl_namespace (void) return TREE_PURPOSE (decl_namespace_list); if (current_class_type) - result = decl_namespace (TYPE_STUB_DECL (current_class_type)); + result = decl_namespace_context (current_class_type); else if (current_function_decl) - result = decl_namespace (current_function_decl); + result = decl_namespace_context (current_function_decl); else result = current_namespace; return result; @@ -3187,7 +3168,7 @@ void push_decl_namespace (tree decl) { if (TREE_CODE (decl) != NAMESPACE_DECL) - decl = decl_namespace (decl); + decl = decl_namespace_context (decl); decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl), NULL_TREE, decl_namespace_list); } @@ -3231,6 +3212,9 @@ do_namespace_alias (tree alias, tree namespace) alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node); DECL_NAMESPACE_ALIAS (alias) = namespace; DECL_EXTERNAL (alias) = 1; + DECL_CONTEXT (alias) = current_scope (); + if (!DECL_CONTEXT (alias)) + DECL_CONTEXT (alias) = FROB_CONTEXT (current_namespace); pushdecl (alias); } @@ -3405,7 +3389,7 @@ parse_using_directive (tree namespace, tree attribs) { if (!toplevel_bindings_p ()) error ("strong using only meaningful at namespace scope"); - else + else if (namespace != error_mark_node) DECL_NAMESPACE_ASSOCIATIONS (namespace) = tree_cons (current_namespace, 0, DECL_NAMESPACE_ASSOCIATIONS (namespace)); @@ -4275,7 +4259,7 @@ arg_assoc_class (struct arg_lookup *k, tree type) return false; k->classes = tree_cons (type, NULL_TREE, k->classes); - context = decl_namespace (TYPE_MAIN_DECL (type)); + context = decl_namespace_context (type); if (arg_assoc_namespace (k, context)) return true; @@ -4357,7 +4341,7 @@ arg_assoc_type (struct arg_lookup *k, tree type) return arg_assoc_type (k, TREE_TYPE (type)); case UNION_TYPE: case ENUMERAL_TYPE: - return arg_assoc_namespace (k, decl_namespace (TYPE_MAIN_DECL (type))); + return arg_assoc_namespace (k, decl_namespace_context (type)); case METHOD_TYPE: /* The basetype is referenced in the first arg type, so just fall through. */ @@ -4559,12 +4543,9 @@ maybe_process_template_type_declaration (tree type, int globalize, ; else { - maybe_check_template_type (type); - my_friendly_assert (IS_AGGR_TYPE (type) || TREE_CODE (type) == ENUMERAL_TYPE, 0); - if (processing_template_decl) { /* This may change after the call to diff --git a/contrib/gcc/cp/parser.c b/contrib/gcc/cp/parser.c index 344a8f5..fb0d1e3 100644 --- a/contrib/gcc/cp/parser.c +++ b/contrib/gcc/cp/parser.c @@ -1,5 +1,6 @@ /* C++ Parser. - Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2003, 2004, + 2005 Free Software Foundation, Inc. Written by Mark Mitchell <mark@codesourcery.com>. This file is part of GCC. @@ -1483,9 +1484,9 @@ static void cp_parser_linkage_specification static tree cp_parser_init_declarator (cp_parser *, tree, tree, bool, bool, int, bool *); static tree cp_parser_declarator - (cp_parser *, cp_parser_declarator_kind, int *, bool *); + (cp_parser *, cp_parser_declarator_kind, int *, bool *, bool); static tree cp_parser_direct_declarator - (cp_parser *, cp_parser_declarator_kind, int *); + (cp_parser *, cp_parser_declarator_kind, int *, bool); static enum tree_code cp_parser_ptr_operator (cp_parser *, tree *, tree *); static tree cp_parser_cv_qualifier_seq_opt @@ -2701,7 +2702,7 @@ cp_parser_id_expression (cp_parser *parser, /*typename_keyword_p=*/false, check_dependency_p, /*type_p=*/false, - /*is_declarator=*/false) + declarator_p) != NULL_TREE); /* If there is a nested-name-specifier, then we are looking at the first qualified-id production. */ @@ -2850,6 +2851,7 @@ cp_parser_unqualified_id (cp_parser* parser, tree qualifying_scope; tree object_scope; tree scope; + bool done; /* Consume the `~' token. */ cp_lexer_consume_token (parser->lexer); @@ -2906,6 +2908,8 @@ cp_parser_unqualified_id (cp_parser* parser, /* If there was an explicit qualification (S::~T), first look in the scope given by the qualification (i.e., S). */ + done = false; + type_decl = NULL_TREE; if (scope) { cp_parser_parse_tentatively (parser); @@ -2917,10 +2921,10 @@ cp_parser_unqualified_id (cp_parser* parser, /*class_head_p=*/false, declarator_p); if (cp_parser_parse_definitely (parser)) - return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl)); + done = true; } /* In "N::S::~S", look in "N" as well. */ - if (scope && qualifying_scope) + if (!done && scope && qualifying_scope) { cp_parser_parse_tentatively (parser); parser->scope = qualifying_scope; @@ -2935,10 +2939,10 @@ cp_parser_unqualified_id (cp_parser* parser, /*class_head_p=*/false, declarator_p); if (cp_parser_parse_definitely (parser)) - return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl)); + done = true; } /* In "p->S::~T", look in the scope given by "*p" as well. */ - else if (object_scope) + else if (!done && object_scope) { cp_parser_parse_tentatively (parser); parser->scope = object_scope; @@ -2953,20 +2957,23 @@ cp_parser_unqualified_id (cp_parser* parser, /*class_head_p=*/false, declarator_p); if (cp_parser_parse_definitely (parser)) - return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl)); + done = true; } /* Look in the surrounding context. */ - parser->scope = NULL_TREE; - parser->object_scope = NULL_TREE; - parser->qualifying_scope = NULL_TREE; - type_decl - = cp_parser_class_name (parser, - /*typename_keyword_p=*/false, - /*template_keyword_p=*/false, - /*type_p=*/false, - /*check_dependency=*/false, - /*class_head_p=*/false, - declarator_p); + if (!done) + { + parser->scope = NULL_TREE; + parser->object_scope = NULL_TREE; + parser->qualifying_scope = NULL_TREE; + type_decl + = cp_parser_class_name (parser, + /*typename_keyword_p=*/false, + /*template_keyword_p=*/false, + /*type_p=*/false, + /*check_dependency=*/false, + /*class_head_p=*/false, + declarator_p); + } /* If an error occurred, assume that the name of the destructor is the same as the name of the qualifying class. That allows us to keep parsing after running @@ -3141,6 +3148,16 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, might destroy it. */ old_scope = parser->scope; saved_qualifying_scope = parser->qualifying_scope; + /* In a declarator-id like "X<T>::I::Y<T>" we must be able to + look up names in "X<T>::I" in order to determine that "Y" is + a template. So, if we have a typename at this point, we make + an effort to look through it. */ + if (is_declaration + && !typename_keyword_p + && parser->scope + && TREE_CODE (parser->scope) == TYPENAME_TYPE) + parser->scope = resolve_typename_type (parser->scope, + /*only_current_p=*/false); /* Parse the qualifying entity. */ new_scope = cp_parser_class_or_namespace_name (parser, @@ -3534,18 +3551,22 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) bool template_p = false; tree id; tree type; + tree scope; /* Consume the `typename' token. */ cp_lexer_consume_token (parser->lexer); /* Look for the optional `::' operator. */ cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false); - /* Look for the nested-name-specifier. */ - cp_parser_nested_name_specifier (parser, - /*typename_keyword_p=*/true, - /*check_dependency_p=*/true, - /*type_p=*/true, - /*is_declaration=*/true); + /* Look for the nested-name-specifier. In case of error here, + consume the trailing id to avoid subsequent error messages + for usual cases. */ + scope = cp_parser_nested_name_specifier (parser, + /*typename_keyword_p=*/true, + /*check_dependency_p=*/true, + /*type_p=*/true, + /*is_declaration=*/true); + /* Look for the optional `template' keyword. */ template_p = cp_parser_optional_template_keyword (parser); /* We don't know whether we're looking at a template-id or an @@ -3558,9 +3579,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) /* If that didn't work, try an identifier. */ if (!cp_parser_parse_definitely (parser)) id = cp_parser_identifier (parser); + + /* Don't process id if nested name specifier is invalid. */ + if (scope == error_mark_node) + return error_mark_node; /* If we look up a template-id in a non-dependent qualifying scope, there's no need to create a dependent type. */ - if (TREE_CODE (id) == TYPE_DECL + else if (TREE_CODE (id) == TYPE_DECL && !dependent_type_p (parser->scope)) type = TREE_TYPE (id); /* Create a TYPENAME_TYPE to represent the type to which the @@ -3741,20 +3766,36 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) koenig_p = false; if (idk == CP_ID_KIND_UNQUALIFIED) { + if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE) + { + if (args) + { + koenig_p = true; + postfix_expression + = perform_koenig_lookup (postfix_expression, args); + } + else + postfix_expression + = unqualified_fn_lookup_error (postfix_expression); + } /* We do not perform argument-dependent lookup if normal lookup finds a non-function, in accordance with the expected resolution of DR 218. */ - if (args - && (is_overloaded_fn (postfix_expression) - || TREE_CODE (postfix_expression) == IDENTIFIER_NODE)) + else if (args && is_overloaded_fn (postfix_expression)) { - koenig_p = true; - postfix_expression - = perform_koenig_lookup (postfix_expression, args); + tree fn = get_first_fn (postfix_expression); + if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) + fn = OVL_CURRENT (TREE_OPERAND (fn, 0)); + /* Only do argument dependent lookup if regular + lookup does not find a set of member functions. + [basic.lookup.koenig]/2a */ + if (!DECL_FUNCTION_MEMBER_P (fn)) + { + koenig_p = true; + postfix_expression + = perform_koenig_lookup (postfix_expression, args); + } } - else if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE) - postfix_expression - = unqualified_fn_lookup_error (postfix_expression); } if (TREE_CODE (postfix_expression) == COMPONENT_REF) @@ -3820,6 +3861,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) tree name; bool dependent_p; bool template_p; + bool pseudo_destructor_p; tree scope = NULL_TREE; enum cpp_ttype token_type = token->type; @@ -3870,11 +3912,34 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) /* Consume the `.' or `->' operator. */ cp_lexer_consume_token (parser->lexer); - /* If the SCOPE is not a scalar type, we are looking at an - ordinary class member access expression, rather than a - pseudo-destructor-name. */ - if (!scope || !SCALAR_TYPE_P (scope)) + + /* Assume this expression is not a pseudo-destructor access. */ + pseudo_destructor_p = false; + + /* If the SCOPE is a scalar type, then, if this is a valid program, + we must be looking at a pseudo-destructor-name. */ + if (scope && SCALAR_TYPE_P (scope)) { + tree s = NULL_TREE; + tree type; + + cp_parser_parse_tentatively (parser); + /* Parse the pseudo-destructor-name. */ + cp_parser_pseudo_destructor_name (parser, &s, &type); + if (cp_parser_parse_definitely (parser)) + { + pseudo_destructor_p = true; + postfix_expression + = finish_pseudo_destructor_expr (postfix_expression, + s, TREE_TYPE (type)); + } + } + + if (!pseudo_destructor_p) + { + /* If the SCOPE is not a scalar type, we are looking + at an ordinary class member access expression, + rather than a pseudo-destructor-name. */ template_p = cp_parser_optional_template_keyword (parser); /* Parse the id-expression. */ name = cp_parser_id_expression (parser, @@ -3914,19 +3979,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) postfix_expression = finish_class_member_access_expr (postfix_expression, name); } - /* Otherwise, try the pseudo-destructor-name production. */ - else - { - tree s = NULL_TREE; - tree type; - - /* Parse the pseudo-destructor-name. */ - cp_parser_pseudo_destructor_name (parser, &s, &type); - /* Form the call. */ - postfix_expression - = finish_pseudo_destructor_expr (postfix_expression, - s, TREE_TYPE (type)); - } /* We no longer need to look up names in the scope of the object on the left-hand side of the `.' or `->' @@ -5811,7 +5863,8 @@ cp_parser_condition (cp_parser* parser) /* Parse the declarator. */ declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, /*ctor_dtor_or_conv_p=*/NULL, - /*parenthesized_p=*/NULL); + /*parenthesized_p=*/NULL, + /*member_p=*/false); /* Parse the attributes. */ attributes = cp_parser_attributes_opt (parser); /* Parse the asm-specification. */ @@ -7992,6 +8045,13 @@ cp_parser_template_id (cp_parser *parser, token->keyword = RID_MAX; /* Purge all subsequent tokens. */ cp_lexer_purge_tokens_after (parser->lexer, token); + + /* ??? Can we actually assume that, if template_id == + error_mark_node, we will have issued a diagnostic to the + user, as opposed to simply marking the tentative parse as + failed? */ + if (cp_parser_error_occurred (parser) && template_id != error_mark_node) + error ("parse error in template argument list"); } pop_deferring_access_checks (); @@ -8095,6 +8155,7 @@ cp_parser_template_name (cp_parser* parser, if (is_declaration && !template_keyword_p && parser->scope && TYPE_P (parser->scope) + && check_dependency_p && dependent_type_p (parser->scope) /* Do not do this for dtors (or ctors), since they never need the template keyword before their name. */ @@ -8170,6 +8231,8 @@ cp_parser_template_name (cp_parser* parser, ; else { + tree fn = NULL_TREE; + /* The standard does not explicitly indicate whether a name that names a set of overloaded declarations, some of which are templates, is a template-name. However, such a name should @@ -8177,14 +8240,11 @@ cp_parser_template_name (cp_parser* parser, template-id for the overloaded templates. */ fns = BASELINK_P (decl) ? BASELINK_FUNCTIONS (decl) : decl; if (TREE_CODE (fns) == OVERLOAD) - { - tree fn; - - for (fn = fns; fn; fn = OVL_NEXT (fn)) - if (TREE_CODE (OVL_CURRENT (fn)) == TEMPLATE_DECL) - break; - } - else + for (fn = fns; fn; fn = OVL_NEXT (fn)) + if (TREE_CODE (OVL_CURRENT (fn)) == TEMPLATE_DECL) + break; + + if (!fn) { /* Otherwise, the name does not name a template. */ cp_parser_error (parser, "expected template-name"); @@ -8548,7 +8608,8 @@ cp_parser_explicit_instantiation (cp_parser* parser) declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, /*ctor_dtor_or_conv_p=*/NULL, - /*parenthesized_p=*/NULL); + /*parenthesized_p=*/NULL, + /*member_p=*/false); cp_parser_check_for_definition_in_return_type (declarator, declares_class_or_enum); if (declarator != error_mark_node) @@ -8684,21 +8745,40 @@ cp_parser_type_specifier (cp_parser* parser, keyword = token->keyword; switch (keyword) { + case RID_ENUM: + /* 'enum' [identifier] '{' introduces an enum-specifier; + 'enum' <anything else> introduces an elaborated-type-specifier. */ + if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_BRACE + || (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME + && cp_lexer_peek_nth_token (parser->lexer, 3)->type + == CPP_OPEN_BRACE)) + { + if (parser->num_template_parameter_lists) + { + error ("template declaration of `enum'"); + cp_parser_skip_to_end_of_block_or_statement (parser); + type_spec = error_mark_node; + } + else + type_spec = cp_parser_enum_specifier (parser); + + if (declares_class_or_enum) + *declares_class_or_enum = 2; + return type_spec; + } + else + goto elaborated_type_specifier; + /* Any of these indicate either a class-specifier, or an elaborated-type-specifier. */ case RID_CLASS: case RID_STRUCT: case RID_UNION: - case RID_ENUM: /* Parse tentatively so that we can back up if we don't find a class-specifier or enum-specifier. */ cp_parser_parse_tentatively (parser); - /* Look for the class-specifier or enum-specifier. */ - if (keyword == RID_ENUM) - type_spec = cp_parser_enum_specifier (parser); - else - type_spec = cp_parser_class_specifier (parser); - + /* Look for the class-specifier. */ + type_spec = cp_parser_class_specifier (parser); /* If that worked, we're done. */ if (cp_parser_parse_definitely (parser)) { @@ -8710,6 +8790,7 @@ cp_parser_type_specifier (cp_parser* parser, /* Fall through. */ case RID_TYPENAME: + elaborated_type_specifier: /* Look for an elaborated-type-specifier. */ type_spec = cp_parser_elaborated_type_specifier (parser, is_friend, @@ -9765,26 +9846,19 @@ cp_parser_asm_definition (cp_parser* parser) /* If the next token is `::', there are no outputs, and the next token is the beginning of the inputs. */ else if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)) - { - /* Consume the `::' token. */ - cp_lexer_consume_token (parser->lexer); - /* The inputs are coming next. */ - inputs_p = true; - } + /* The inputs are coming next. */ + inputs_p = true; /* Look for inputs. */ if (inputs_p || cp_lexer_next_token_is (parser->lexer, CPP_COLON)) { - if (!inputs_p) - /* Consume the `:'. */ - cp_lexer_consume_token (parser->lexer); + /* Consume the `:' or `::'. */ + cp_lexer_consume_token (parser->lexer); /* Parse the output-operands. */ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON) && cp_lexer_next_token_is_not (parser->lexer, - CPP_SCOPE) - && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) inputs = cp_parser_asm_operand_list (parser); } @@ -9796,9 +9870,8 @@ cp_parser_asm_definition (cp_parser* parser) if (clobbers_p || cp_lexer_next_token_is (parser->lexer, CPP_COLON)) { - if (!clobbers_p) - /* Consume the `:'. */ - cp_lexer_consume_token (parser->lexer); + /* Consume the `:' or `::'. */ + cp_lexer_consume_token (parser->lexer); /* Parse the clobbers. */ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) @@ -9899,7 +9972,8 @@ cp_parser_init_declarator (cp_parser* parser, declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, &ctor_dtor_or_conv_p, - /*parenthesized_p=*/NULL); + /*parenthesized_p=*/NULL, + /*member_p=*/false); /* Gather up the deferred checks. */ stop_deferring_access_checks (); @@ -10182,13 +10256,16 @@ cp_parser_init_declarator (cp_parser* parser, expression, not a declaration.) If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff - the declarator is a direct-declarator of the form "(...)". */ + the declarator is a direct-declarator of the form "(...)". + + MEMBER_P is true iff this declarator is a member-declarator. */ static tree cp_parser_declarator (cp_parser* parser, cp_parser_declarator_kind dcl_kind, int* ctor_dtor_or_conv_p, - bool* parenthesized_p) + bool* parenthesized_p, + bool member_p) { cp_token *token; tree declarator; @@ -10229,7 +10306,8 @@ cp_parser_declarator (cp_parser* parser, /* Parse the dependent declarator. */ declarator = cp_parser_declarator (parser, dcl_kind, /*ctor_dtor_or_conv_p=*/NULL, - /*parenthesized_p=*/NULL); + /*parenthesized_p=*/NULL, + /*member_p=*/false); /* If we are parsing an abstract-declarator, we must handle the case where the dependent declarator is absent. */ @@ -10255,7 +10333,8 @@ cp_parser_declarator (cp_parser* parser, *parenthesized_p = cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN); declarator = cp_parser_direct_declarator (parser, dcl_kind, - ctor_dtor_or_conv_p); + ctor_dtor_or_conv_p, + member_p); } if (attributes && declarator != error_mark_node) @@ -10303,7 +10382,8 @@ cp_parser_declarator (cp_parser* parser, static tree cp_parser_direct_declarator (cp_parser* parser, cp_parser_declarator_kind dcl_kind, - int* ctor_dtor_or_conv_p) + int* ctor_dtor_or_conv_p, + bool member_p) { cp_token *token; tree declarator = NULL_TREE; @@ -10362,7 +10442,14 @@ cp_parser_direct_declarator (cp_parser* parser, tree params; unsigned saved_num_template_parameter_lists; - cp_parser_parse_tentatively (parser); + /* In a member-declarator, the only valid interpretation + of a parenthesis is the start of a + parameter-declaration-clause. (It is invalid to + initialize a static data member with a parenthesized + initializer; only the "=" form of initialization is + permitted.) */ + if (!member_p) + cp_parser_parse_tentatively (parser); /* Consume the `('. */ cp_lexer_consume_token (parser->lexer); @@ -10388,7 +10475,7 @@ cp_parser_direct_declarator (cp_parser* parser, /* If all went well, parse the cv-qualifier-seq and the exception-specification. */ - if (cp_parser_parse_definitely (parser)) + if (member_p || cp_parser_parse_definitely (parser)) { tree cv_qualifiers; tree exception_specification; @@ -10436,7 +10523,8 @@ cp_parser_direct_declarator (cp_parser* parser, parser->in_type_id_in_expr_p = true; declarator = cp_parser_declarator (parser, dcl_kind, ctor_dtor_or_conv_p, - /*parenthesized_p=*/NULL); + /*parenthesized_p=*/NULL, + member_p); parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p; first = false; /* Expect a `)'. */ @@ -10854,7 +10942,8 @@ cp_parser_type_id (cp_parser* parser) /* Look for the declarator. */ abstract_declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_ABSTRACT, NULL, - /*parenthesized_p=*/NULL); + /*parenthesized_p=*/NULL, + /*member_p=*/false); /* Check to see if there really was a declarator. */ if (!cp_parser_parse_definitely (parser)) abstract_declarator = NULL_TREE; @@ -11212,7 +11301,8 @@ cp_parser_parameter_declaration (cp_parser *parser, declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER, /*ctor_dtor_or_conv_p=*/NULL, - parenthesized_p); + parenthesized_p, + /*member_p=*/false); parser->default_arg_ok_p = saved_default_arg_ok_p; /* After the declarator, allow more attributes. */ attributes = chainon (attributes, cp_parser_attributes_opt (parser)); @@ -11471,18 +11561,52 @@ cp_parser_initializer (cp_parser* parser, bool* is_parenthesized_init, static tree cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p) { - tree initializer; + tree initializer = NULL_TREE; + + /* Assume the expression is constant. */ + *non_constant_p = false; /* If it is not a `{', then we are looking at an assignment-expression. */ if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)) { - initializer - = cp_parser_constant_expression (parser, - /*allow_non_constant_p=*/true, - non_constant_p); - if (!*non_constant_p) - initializer = fold_non_dependent_expr (initializer); + /* Speed up common initializers (simply a literal). */ + cp_token* token = cp_lexer_peek_token (parser->lexer); + cp_token* token2 = cp_lexer_peek_nth_token (parser->lexer, 2); + + if (token2->type == CPP_COMMA) + switch (token->type) + { + case CPP_CHAR: + case CPP_WCHAR: + case CPP_NUMBER: + token = cp_lexer_consume_token (parser->lexer); + initializer = token->value; + break; + + case CPP_STRING: + case CPP_WSTRING: + token = cp_lexer_consume_token (parser->lexer); + if (TREE_CHAIN (token->value)) + initializer = TREE_CHAIN (token->value); + else + initializer = token->value; + break; + + default: + break; + } + + /* Otherwise, fall back to the generic assignment expression. */ + if (!initializer) + { + initializer + = cp_parser_constant_expression (parser, + /*allow_non_constant_p=*/true, + non_constant_p); + if (!*non_constant_p) + initializer = fold_non_dependent_expr (initializer); + } } else { @@ -11742,6 +11866,7 @@ cp_parser_class_specifier (cp_parser* parser) bool nested_name_specifier_p; unsigned saved_num_template_parameter_lists; bool pop_p = false; + tree scope = NULL_TREE; push_deferring_access_checks (dk_no_deferred); @@ -11777,7 +11902,10 @@ cp_parser_class_specifier (cp_parser* parser) /* Start the class. */ if (nested_name_specifier_p) - pop_p = push_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type))); + { + scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)); + pop_p = push_scope (scope); + } type = begin_class_definition (type); if (type == error_mark_node) /* If the type is erroneous, skip the entire body of the class. */ @@ -11800,7 +11928,7 @@ cp_parser_class_specifier (cp_parser* parser) if (type != error_mark_node) type = finish_struct (type, attributes); if (pop_p) - pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type))); + pop_scope (scope); /* If this class is not itself within the scope of another class, then we need to parse the bodies of all of the queued function definitions. Note that the queued functions defined in a class @@ -12071,6 +12199,15 @@ cp_parser_class_head (cp_parser* parser, else if (nested_name_specifier) { tree scope; + + /* Reject typedef-names in class heads. */ + if (!DECL_IMPLICIT_TYPEDEF_P (type)) + { + error ("invalid class name in declaration of `%D'", type); + type = NULL_TREE; + goto done; + } + /* Figure out in what scope the declaration is being placed. */ scope = current_scope (); if (!scope) @@ -12528,7 +12665,8 @@ cp_parser_member_declaration (cp_parser* parser) declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, &ctor_dtor_or_conv_p, - /*parenthesized_p=*/NULL); + /*parenthesized_p=*/NULL, + /*member_p=*/true); /* If something went wrong parsing the declarator, make sure that we at least consume some tokens. */ @@ -13144,7 +13282,8 @@ cp_parser_exception_declaration (cp_parser* parser) else declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER, /*ctor_dtor_or_conv_p=*/NULL, - /*parenthesized_p=*/NULL); + /*parenthesized_p=*/NULL, + /*member_p=*/false); /* Restore the saved message. */ parser->type_definition_forbidden_message = saved_message; @@ -13409,36 +13548,39 @@ cp_parser_attribute_list (cp_parser* parser) /* Look for the identifier. We also allow keywords here; for example `__attribute__ ((const))' is legal. */ token = cp_lexer_peek_token (parser->lexer); - if (token->type != CPP_NAME - && token->type != CPP_KEYWORD) - return error_mark_node; - /* Consume the token. */ - token = cp_lexer_consume_token (parser->lexer); - - /* Save away the identifier that indicates which attribute this is. */ - identifier = token->value; - attribute = build_tree_list (identifier, NULL_TREE); - - /* Peek at the next token. */ - token = cp_lexer_peek_token (parser->lexer); - /* If it's an `(', then parse the attribute arguments. */ - if (token->type == CPP_OPEN_PAREN) + if (token->type == CPP_NAME + || token->type == CPP_KEYWORD) { - tree arguments; + /* Consume the token. */ + token = cp_lexer_consume_token (parser->lexer); - arguments = (cp_parser_parenthesized_expression_list - (parser, true, /*non_constant_p=*/NULL)); - /* Save the identifier and arguments away. */ - TREE_VALUE (attribute) = arguments; - } + /* Save away the identifier that indicates which attribute + this is. */ + identifier = token->value; + attribute = build_tree_list (identifier, NULL_TREE); + + /* Peek at the next token. */ + token = cp_lexer_peek_token (parser->lexer); + /* 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, /*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; + /* Add this attribute to the list. */ + TREE_CHAIN (attribute) = attribute_list; + attribute_list = attribute; - /* Now, look for more attributes. */ - token = cp_lexer_peek_token (parser->lexer); - /* If the next token isn't a `,', we're done. */ + /* Now, look for more attributes. */ + token = cp_lexer_peek_token (parser->lexer); + } + /* Now, look for more attributes. If the next token isn't a + `,', we're done. */ if (token->type != CPP_COMMA) break; @@ -14728,10 +14870,12 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) saved_local_variables_forbidden_p = parser->local_variables_forbidden_p; parser->local_variables_forbidden_p = true; /* Parse the assignment-expression. */ - if (DECL_CLASS_SCOPE_P (fn)) + if (DECL_FRIEND_CONTEXT (fn)) + push_nested_class (DECL_FRIEND_CONTEXT (fn)); + else if (DECL_CLASS_SCOPE_P (fn)) push_nested_class (DECL_CONTEXT (fn)); TREE_PURPOSE (parameters) = cp_parser_assignment_expression (parser); - if (DECL_CLASS_SCOPE_P (fn)) + if (DECL_FRIEND_CONTEXT (fn) || DECL_CLASS_SCOPE_P (fn)) pop_nested_class (); /* If the token stream has not been completely used up, then @@ -14998,9 +15142,7 @@ cp_parser_next_token_starts_class_definition_p (cp_parser *parser) } /* Returns TRUE iff the next token is the "," or ">" ending a - template-argument. ">>" is also accepted (after the full - argument was parsed) because it's probably a typo for "> >", - and there is a specific diagnostic for this. */ + template-argument. */ static bool cp_parser_next_token_ends_template_argument_p (cp_parser *parser) @@ -15008,8 +15150,7 @@ cp_parser_next_token_ends_template_argument_p (cp_parser *parser) cp_token *token; token = cp_lexer_peek_token (parser->lexer); - return (token->type == CPP_COMMA || token->type == CPP_GREATER - || token->type == CPP_RSHIFT); + return (token->type == CPP_COMMA || token->type == CPP_GREATER); } /* Returns TRUE iff the n-th token is a ">", or the n-th is a "[" and the diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c index c5c8e32..e5aadc1 100644 --- a/contrib/gcc/cp/pt.c +++ b/contrib/gcc/cp/pt.c @@ -1,6 +1,6 @@ /* Handle parameterized types (templates) for GNU C++. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. Rewritten by Jason Merrill (jason@cygnus.com). @@ -180,7 +180,9 @@ push_access_scope (tree t) || TREE_CODE (t) == VAR_DECL, 0); - if (DECL_CLASS_SCOPE_P (t)) + if (DECL_FRIEND_CONTEXT (t)) + push_nested_class (DECL_FRIEND_CONTEXT (t)); + else if (DECL_CLASS_SCOPE_P (t)) push_nested_class (DECL_CONTEXT (t)); else push_to_top_level (); @@ -205,7 +207,7 @@ pop_access_scope (tree t) saved_access_scope = TREE_CHAIN (saved_access_scope); } - if (DECL_CLASS_SCOPE_P (t)) + if (DECL_FRIEND_CONTEXT (t) || DECL_CLASS_SCOPE_P (t)) pop_nested_class (); else pop_from_top_level (); @@ -706,6 +708,36 @@ end_explicit_instantiation (void) processing_explicit_instantiation = false; } +/* A explicit specialization or partial specialization TMPL is being + declared. Check that the namespace in which the specialization is + occurring is permissible. Returns false iff it is invalid to + specialize TMPL in the current namespace. */ + +static bool +check_specialization_namespace (tree tmpl) +{ + tree tpl_ns = decl_namespace_context (tmpl); + + /* [tmpl.expl.spec] + + An explicit specialization shall be declared in the namespace of + which the template is a member, or, for member templates, in the + namespace of which the enclosing class or enclosing class + template is a member. An explicit specialization of a member + function, member class or static data member of a class template + shall be declared in the namespace of which the class template is + a member. */ + if (is_associated_namespace (current_namespace, tpl_ns)) + /* Same or super-using namespace. */ + return true; + else + { + pedwarn ("specialization of `%D' in different namespace", tmpl); + cp_pedwarn_at (" from definition of `%#D'", tmpl); + return false; + } +} + /* The TYPE is being declared. If it is a template type, that means it is a partial specialization. Do appropriate error-checking. */ @@ -731,15 +763,7 @@ maybe_process_partial_specialization (tree type) if (CLASSTYPE_IMPLICIT_INSTANTIATION (type) && !COMPLETE_TYPE_P (type)) { - tree tpl_ns = decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)); - if (is_associated_namespace (current_namespace, tpl_ns)) - /* Same or super-using namespace. */; - else - { - pedwarn ("specializing `%#T' in different namespace", type); - cp_pedwarn_at (" from definition of `%#D'", - CLASSTYPE_TI_TEMPLATE (type)); - } + check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (type)); SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type); if (processing_template_decl) push_template_decl (TYPE_MAIN_DECL (type)); @@ -1114,6 +1138,12 @@ register_specialization (tree spec, tree tmpl, tree args) } } + /* A specialization must be declared in the same namespace as the + template it is specializing. */ + if (DECL_TEMPLATE_SPECIALIZATION (spec) + && !check_specialization_namespace (tmpl)) + DECL_CONTEXT (spec) = decl_namespace_context (tmpl); + DECL_TEMPLATE_SPECIALIZATIONS (tmpl) = tree_cons (args, spec, DECL_TEMPLATE_SPECIALIZATIONS (tmpl)); @@ -1927,6 +1957,10 @@ check_explicit_specialization (tree declarator, DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl); DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (tmpl)) = DECL_SOURCE_LOCATION (decl); + /* We want to use the argument list specified in the + definition, not in the original declaration. */ + DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (tmpl)) + = DECL_ARGUMENTS (decl); } return tmpl; } @@ -1963,49 +1997,6 @@ check_explicit_specialization (tree declarator, return decl; } -/* TYPE is being declared. Verify that the use of template headers - and such is reasonable. Issue error messages if not. */ - -void -maybe_check_template_type (tree type) -{ - if (template_header_count) - { - /* We are in the scope of some `template <...>' header. */ - - int context_depth - = template_class_depth_real (TYPE_CONTEXT (type), - /*count_specializations=*/1); - - if (template_header_count <= context_depth) - /* This is OK; the template headers are for the context. We - are actually too lenient here; like - check_explicit_specialization we should consider the number - of template types included in the actual declaration. For - example, - - template <class T> struct S { - template <class U> template <class V> - struct I {}; - }; - - is invalid, but: - - template <class T> struct S { - template <class U> struct I; - }; - - template <class T> template <class U. - struct S<T>::I {}; - - is not. */ - ; - else if (template_header_count > context_depth + 1) - /* There are two many template parameter lists. */ - error ("too many template parameter lists in declaration of `%T'", type); - } -} - /* Returns 1 iff PARMS1 and PARMS2 are identical sets of template parameters. These are represented in the same format used for DECL_TEMPLATE_PARMS. */ @@ -2815,19 +2806,35 @@ push_template_decl_real (tree decl, int is_friend) else if (TREE_CODE (decl) == TYPE_DECL && ANON_AGGRNAME_P (DECL_NAME (decl))) error ("template class without a name"); - else if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_DESTRUCTOR_P (decl)) + else if (TREE_CODE (decl) == FUNCTION_DECL) { - /* [temp.mem] - - A destructor shall not be a member template. */ - error ("destructor `%D' declared as member template", decl); - return error_mark_node; + if (DECL_DESTRUCTOR_P (decl)) + { + /* [temp.mem] + + A destructor shall not be a member template. */ + error ("destructor `%D' declared as member template", decl); + return error_mark_node; + } + if (NEW_DELETE_OPNAME_P (DECL_NAME (decl)) + && (!TYPE_ARG_TYPES (TREE_TYPE (decl)) + || TYPE_ARG_TYPES (TREE_TYPE (decl)) == void_list_node + || !TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl))) + || (TREE_CHAIN (TYPE_ARG_TYPES ((TREE_TYPE (decl)))) + == void_list_node))) + { + /* [basic.stc.dynamic.allocation] + + An allocation function can be a function + template. ... Template allocation functions shall + have two or more parameters. */ + error ("invalid template declaration of `%D'", decl); + return decl; + } } else if ((DECL_IMPLICIT_TYPEDEF_P (decl) && CLASS_TYPE_P (TREE_TYPE (decl))) - || (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx)) - || TREE_CODE (decl) == FUNCTION_DECL) + || (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx))) /* OK */; else { @@ -3199,9 +3206,7 @@ convert_nontype_argument (tree type, tree expr) will not return the initializer. Handle that special case here. */ if (expr == const_expr - && TREE_CODE (expr) == VAR_DECL - && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (expr) - && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (expr)) + && DECL_INTEGRAL_CONSTANT_VAR_P (expr) /* DECL_INITIAL can be NULL if we are processing a variable initialized to an expression involving itself. We know it is initialized to a constant -- but not what @@ -5470,14 +5475,28 @@ instantiate_class_template (tree type) tree tag = t; tree name = TYPE_IDENTIFIER (tag); tree newtag; - + bool class_template_p; + + class_template_p = (TREE_CODE (tag) != ENUMERAL_TYPE + && TYPE_LANG_SPECIFIC (tag) + && CLASSTYPE_IS_TEMPLATE (tag)); + /* If the member is a class template, then -- even after + substituition -- there may be dependent types in the + template argument list for the class. We increment + PROCESSING_TEMPLATE_DECL so that dependent_type_p, as + that function will assume that no types are dependent + when outside of a template. */ + if (class_template_p) + ++processing_template_decl; newtag = tsubst (tag, args, tf_error, NULL_TREE); + if (class_template_p) + --processing_template_decl; if (newtag == error_mark_node) continue; if (TREE_CODE (newtag) != ENUMERAL_TYPE) { - if (TYPE_LANG_SPECIFIC (tag) && CLASSTYPE_IS_TEMPLATE (tag)) + if (class_template_p) /* Unfortunately, lookup_template_class sets CLASSTYPE_IMPLICIT_INSTANTIATION for a partial instantiation (i.e., for the type of a member @@ -5872,6 +5891,9 @@ tsubst_aggr_type (tree t, tree tsubst_default_argument (tree fn, tree type, tree arg) { + tree saved_class_ptr = NULL_TREE; + tree saved_class_ref = NULL_TREE; + /* This default argument came from a template. Instantiate the default argument here, not in tsubst. In the case of something like: @@ -5889,12 +5911,27 @@ tsubst_default_argument (tree fn, tree type, tree arg) within the scope of FN. Since push_access_scope sets current_function_decl, we must explicitly clear it here. */ current_function_decl = NULL_TREE; + /* The "this" pointer is not valid in a default argument. */ + if (cfun) + { + saved_class_ptr = current_class_ptr; + cp_function_chain->x_current_class_ptr = NULL_TREE; + saved_class_ref = current_class_ref; + cp_function_chain->x_current_class_ref = NULL_TREE; + } push_deferring_access_checks(dk_no_deferred); arg = tsubst_expr (arg, DECL_TI_ARGS (fn), tf_error | tf_warning, NULL_TREE); pop_deferring_access_checks(); + /* Restore the "this" pointer. */ + if (cfun) + { + cp_function_chain->x_current_class_ptr = saved_class_ptr; + cp_function_chain->x_current_class_ref = saved_class_ref; + } + pop_access_scope (fn); /* Make sure the default argument is reasonable. */ @@ -6384,6 +6421,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) type = complete_type (type); DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r) = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t); + type = check_var_type (DECL_NAME (r), type); } else if (DECL_SELF_REFERENCE_P (t)) SET_DECL_SELF_REFERENCE_P (r); @@ -6424,9 +6462,6 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) register_local_specialization (r, t); TREE_CHAIN (r) = NULL_TREE; - if (TREE_CODE (r) == VAR_DECL && VOID_TYPE_P (type)) - cp_error_at ("instantiation of `%D' as type `%T'", r, type); - /* Compute the size, alignment, etc. of R. */ layout_decl (r, 0); } break; @@ -6618,6 +6653,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) || t == integer_type_node || t == void_type_node || t == char_type_node + || t == unknown_type_node || TREE_CODE (t) == NAMESPACE_DECL) return t; @@ -7446,7 +7482,16 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, in_decl, /*entering_scope=*/1); if (ctx != DECL_CONTEXT (t)) - return lookup_field (ctx, DECL_NAME (t), 0, false); + { + tree r = lookup_field (ctx, DECL_NAME (t), 0, false); + if (!r) + { + if (complain & tf_error) + error ("using invalid field `%D'", t); + return error_mark_node; + } + return r; + } } return t; @@ -8381,7 +8426,11 @@ tsubst_copy_and_build (tree t, lookup finds a non-function, in accordance with the expected resolution of DR 218. */ if (koenig_p - && (is_overloaded_fn (function) + && ((is_overloaded_fn (function) + /* If lookup found a member function, the Koenig lookup is + not appropriate, even if an unqualified-name was used + to denote the function. */ + && !DECL_FUNCTION_MEMBER_P (get_first_fn (function))) || TREE_CODE (function) == IDENTIFIER_NODE)) function = perform_koenig_lookup (function, call_args); @@ -8471,7 +8520,9 @@ tsubst_copy_and_build (tree t, else member = tsubst_copy (member, args, complain, in_decl); - if (!CLASS_TYPE_P (TREE_TYPE (object))) + if (member == error_mark_node) + return error_mark_node; + else if (!CLASS_TYPE_P (TREE_TYPE (object))) { if (TREE_CODE (member) == BIT_NOT_EXPR) return finish_pseudo_destructor_expr (object, @@ -8497,15 +8548,35 @@ tsubst_copy_and_build (tree t, /*is_type_p=*/false, /*complain=*/false); if (BASELINK_P (member)) - BASELINK_FUNCTIONS (member) - = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member), - args); + { + BASELINK_FUNCTIONS (member) + = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member), + args); + member = (adjust_result_of_qualified_name_lookup + (member, BINFO_TYPE (BASELINK_BINFO (member)), + TREE_TYPE (object))); + } else { qualified_name_lookup_error (TREE_TYPE (object), tmpl); return error_mark_node; } } + else if (TREE_CODE (member) == SCOPE_REF + && !CLASS_TYPE_P (TREE_OPERAND (member, 0)) + && TREE_CODE (TREE_OPERAND (member, 0)) != NAMESPACE_DECL) + { + if (complain & tf_error) + { + if (TYPE_P (TREE_OPERAND (member, 0))) + error ("`%T' is not a class or namespace", + TREE_OPERAND (member, 0)); + else + error ("`%D' is not a class or namespace", + TREE_OPERAND (member, 0)); + } + return error_mark_node; + } else if (TREE_CODE (member) == FIELD_DECL) return finish_non_static_data_member (member, object, NULL_TREE); @@ -8574,6 +8645,14 @@ tsubst_copy_and_build (tree t, tsubst_copy (TREE_TYPE (t), args, complain, in_decl)); + case CONST_DECL: + t = tsubst_copy (t, args, complain, in_decl); + /* As in finish_id_expression, we resolve enumeration constants + to their underlying values. */ + if (TREE_CODE (t) == CONST_DECL) + return DECL_INITIAL (t); + return t; + default: return tsubst_copy (t, args, complain, in_decl); } @@ -8813,6 +8892,9 @@ fn_type_unification (tree fn, tree converted_args; bool incomplete; + if (explicit_targs == error_mark_node) + return 1; + converted_args = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn), explicit_targs, NULL_TREE, tf_none, @@ -9833,7 +9915,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) else if ((strict & UNIFY_ALLOW_INTEGER) && (TREE_CODE (tparm) == INTEGER_TYPE || TREE_CODE (tparm) == BOOLEAN_TYPE)) - /* OK */; + /* Convert the ARG to the type of PARM; the deduced non-type + template argument must exactly match the types of the + corresponding parameter. */ + arg = fold (build_nop (TREE_TYPE (parm), arg)); else if (uses_template_parms (tparm)) /* We haven't deduced the type of this parameter yet. Try again later. */ @@ -9913,6 +9998,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) case VECTOR_TYPE: case INTEGER_TYPE: case BOOLEAN_TYPE: + case ENUMERAL_TYPE: case VOID_TYPE: if (TREE_CODE (arg) != TREE_CODE (parm)) return 1; @@ -10108,10 +10194,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) else return 0; } - else - sorry ("use of `%s' in template type unification", - tree_code_name [(int) TREE_CODE (parm)]); - + sorry ("use of `%s' in template type unification", + tree_code_name [(int) TREE_CODE (parm)]); return 1; } } @@ -11927,6 +12011,9 @@ type_dependent_expression_p (tree expression) if (TREE_CODE (expression) == IDENTIFIER_NODE) return false; } + /* SCOPE_REF with non-null TREE_TYPE is always non-dependent. */ + if (TREE_CODE (expression) == SCOPE_REF) + return false; if (TREE_CODE (expression) == BASELINK) expression = BASELINK_FUNCTIONS (expression); @@ -12031,8 +12118,9 @@ dependent_template_p (tree tmpl) if (DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl) || TREE_CODE (tmpl) == TEMPLATE_TEMPLATE_PARM) return true; - /* So are qualified names that have not been looked up. */ - if (TREE_CODE (tmpl) == SCOPE_REF) + /* So arenames that have not been looked up. */ + if (TREE_CODE (tmpl) == SCOPE_REF + || TREE_CODE (tmpl) == IDENTIFIER_NODE) return true; /* So are member templates of dependent classes. */ if (TYPE_P (CP_DECL_CONTEXT (tmpl))) @@ -12148,7 +12236,8 @@ build_non_dependent_expr (tree expr) if (TREE_CODE (inner_expr) == OVERLOAD || TREE_CODE (inner_expr) == FUNCTION_DECL || TREE_CODE (inner_expr) == TEMPLATE_DECL - || TREE_CODE (inner_expr) == TEMPLATE_ID_EXPR) + || TREE_CODE (inner_expr) == TEMPLATE_ID_EXPR + || TREE_CODE (inner_expr) == OFFSET_REF) return expr; /* Preserve string constants; conversions from string constants to "char *" are allowed, even though normally a "const char *" diff --git a/contrib/gcc/cp/search.c b/contrib/gcc/cp/search.c index 65ed660..0dfdb92 100644 --- a/contrib/gcc/cp/search.c +++ b/contrib/gcc/cp/search.c @@ -78,6 +78,7 @@ struct vbase_info tree inits; }; +static int is_subobject_of_p (tree, tree); static tree dfs_check_overlap (tree, void *); static tree dfs_no_overlap_yet (tree, int, void *); static base_kind lookup_base_r (tree, tree, base_access, bool, tree *); @@ -97,7 +98,6 @@ static struct search_level *pop_search_level (struct stack_level *); static tree bfs_walk (tree, tree (*) (tree, void *), tree (*) (tree, int, void *), void *); static tree lookup_field_queue_p (tree, int, void *); -static int shared_member_p (tree); static tree lookup_field_r (tree, void *); static tree dfs_accessible_queue_p (tree, int, void *); static tree dfs_accessible_p (tree, void *); @@ -891,10 +891,26 @@ friend_accessible_p (tree scope, tree decl, tree binfo) /* Or an instantiation of something which is a friend. */ if (DECL_TEMPLATE_INFO (scope)) - return friend_accessible_p (DECL_TI_TEMPLATE (scope), decl, binfo); + { + int ret; + /* Increment processing_template_decl to make sure that + dependent_type_p works correctly. */ + ++processing_template_decl; + ret = friend_accessible_p (DECL_TI_TEMPLATE (scope), decl, binfo); + --processing_template_decl; + return ret; + } } else if (CLASSTYPE_TEMPLATE_INFO (scope)) - return friend_accessible_p (CLASSTYPE_TI_TEMPLATE (scope), decl, binfo); + { + int ret; + /* Increment processing_template_decl to make sure that + dependent_type_p works correctly. */ + ++processing_template_decl; + ret = friend_accessible_p (CLASSTYPE_TI_TEMPLATE (scope), decl, binfo); + --processing_template_decl; + return ret; + } return 0; } @@ -1058,7 +1074,6 @@ template_self_reference_p (tree type, tree decl) && DECL_NAME (decl) == constructor_name (type)); } - /* Nonzero for a class member means that it is shared between all objects of that class. @@ -1069,7 +1084,7 @@ template_self_reference_p (tree type, tree decl) This function checks that T contains no nonstatic members. */ -static int +int shared_member_p (tree t) { if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == TYPE_DECL \ @@ -1088,6 +1103,27 @@ shared_member_p (tree t) return 0; } +/* Routine to see if the sub-object denoted by the binfo PARENT can be + found as a base class and sub-object of the object denoted by + BINFO. */ + +static int +is_subobject_of_p (tree parent, tree binfo) +{ + tree probe; + + for (probe = parent; probe; probe = BINFO_INHERITANCE_CHAIN (probe)) + { + if (probe == binfo) + return 1; + if (TREE_VIA_VIRTUAL (probe)) + return (purpose_member (BINFO_TYPE (probe), + CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo))) + != NULL_TREE); + } + return 0; +} + /* DATA is really a struct lookup_field_info. Look for a field with the name indicated there in BINFO. If this function returns a non-NULL value it is the result of the lookup. Called from @@ -1155,12 +1191,14 @@ lookup_field_r (tree binfo, void *data) /* If the lookup already found a match, and the new value doesn't hide the old one, we might have an ambiguity. */ - if (lfi->rval_binfo && !original_binfo (lfi->rval_binfo, binfo)) + if (lfi->rval_binfo + && !is_subobject_of_p (lfi->rval_binfo, binfo)) + { if (nval == lfi->rval && shared_member_p (nval)) /* The two things are really the same. */ ; - else if (original_binfo (binfo, lfi->rval_binfo)) + else if (is_subobject_of_p (binfo, lfi->rval_binfo)) /* The previous value hides the new one. */ ; else diff --git a/contrib/gcc/cp/semantics.c b/contrib/gcc/cp/semantics.c index 966b004..bb2f3c9 100644 --- a/contrib/gcc/cp/semantics.c +++ b/contrib/gcc/cp/semantics.c @@ -4,7 +4,7 @@ and during the instantiation of template functions. Copyright (C) 1998, 1999, 2000, 2001, 2002, - 2003, 2004 Free Software Foundation, Inc. + 2003, 2004, 2005 Free Software Foundation, Inc. Written by Mark Mitchell (mmitchell@usa.net) based on code found formerly in parse.y and pt.c. @@ -1388,19 +1388,16 @@ finish_qualified_id_expr (tree qualifying_class, tree expr, bool done, qualifying_class); else if (BASELINK_P (expr) && !processing_template_decl) { - tree fn; tree fns; /* See if any of the functions are non-static members. */ fns = BASELINK_FUNCTIONS (expr); if (TREE_CODE (fns) == TEMPLATE_ID_EXPR) fns = TREE_OPERAND (fns, 0); - for (fn = fns; fn; fn = OVL_NEXT (fn)) - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) - break; /* If so, the expression may be relative to the current class. */ - if (fn && current_class_type + if (!shared_member_p (fns) + && current_class_type && DERIVED_FROM_P (qualifying_class, current_class_type)) expr = (build_class_member_access_expr (maybe_dummy_object (qualifying_class, NULL), @@ -1446,6 +1443,9 @@ finish_stmt_expr_expr (tree expr) tree result = NULL_TREE; tree type = void_type_node; + if (error_operand_p (expr)) + return error_mark_node; + if (expr) { type = TREE_TYPE (expr); @@ -2561,31 +2561,35 @@ finish_id_expression (tree id_expression, if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) return decl; + /* The same is true for FIELD_DECL, but we also need to + make sure that the syntax is correct. */ + else if (TREE_CODE (decl) == FIELD_DECL) + { + /* Since SCOPE is NULL here, this is an unqualified name. + Access checking has been performed during name lookup + already. Turn off checking to avoid duplicate errors. */ + push_deferring_access_checks (dk_no_check); + decl = finish_non_static_data_member + (decl, current_class_ref, + /*qualifying_scope=*/NULL_TREE); + pop_deferring_access_checks (); + return decl; + } return id_expression; } /* Only certain kinds of names are allowed in constant expression. Enumerators and template parameters have already been handled above. */ - if (integral_constant_expression_p) + if (integral_constant_expression_p + && !DECL_INTEGRAL_CONSTANT_VAR_P (decl)) { - /* Const variables or static data members of integral or - enumeration types initialized with constant expressions - are OK. */ - if (TREE_CODE (decl) == VAR_DECL - && CP_TYPE_CONST_P (TREE_TYPE (decl)) - && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl)) - && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)) - ; - else + if (!allow_non_integral_constant_expression_p) { - if (!allow_non_integral_constant_expression_p) - { - error ("`%D' cannot appear in a constant-expression", decl); - return error_mark_node; - } - *non_integral_constant_expression_p = true; + error ("`%D' cannot appear in a constant-expression", decl); + return error_mark_node; } + *non_integral_constant_expression_p = true; } if (TREE_CODE (decl) == NAMESPACE_DECL) @@ -2630,8 +2634,15 @@ finish_id_expression (tree id_expression, decl = build (SCOPE_REF, TREE_TYPE (decl), scope, decl); } else if (TREE_CODE (decl) == FIELD_DECL) - decl = finish_non_static_data_member (decl, current_class_ref, - /*qualifying_scope=*/NULL_TREE); + { + /* Since SCOPE is NULL here, this is an unqualified name. + Access checking has been performed during name lookup + already. Turn off checking to avoid duplicate errors. */ + push_deferring_access_checks (dk_no_check); + decl = finish_non_static_data_member (decl, current_class_ref, + /*qualifying_scope=*/NULL_TREE); + pop_deferring_access_checks (); + } else if (is_overloaded_fn (decl)) { tree first_fn = OVL_CURRENT (decl); @@ -2643,7 +2654,8 @@ finish_id_expression (tree id_expression, mark_used (first_fn); if (TREE_CODE (first_fn) == FUNCTION_DECL - && DECL_FUNCTION_MEMBER_P (first_fn)) + && DECL_FUNCTION_MEMBER_P (first_fn) + && !shared_member_p (decl)) { /* A set of member functions. */ decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0); @@ -2935,18 +2947,6 @@ expand_body (tree fn) extract_interface_info (); - /* If this function is marked with the constructor attribute, add it - to the list of functions to be called along with constructors - from static duration objects. */ - if (DECL_STATIC_CONSTRUCTOR (fn)) - static_ctors = tree_cons (NULL_TREE, fn, static_ctors); - - /* If this function is marked with the destructor attribute, add it - to the list of functions to be called along with destructors from - static duration objects. */ - if (DECL_STATIC_DESTRUCTOR (fn)) - static_dtors = tree_cons (NULL_TREE, fn, static_dtors); - if (DECL_CLONED_FUNCTION_P (fn)) { /* If this is a clone, go through the other clones now and mark @@ -3009,6 +3009,18 @@ expand_or_defer_fn (tree fn) if (DECL_DECLARED_INLINE_P (fn)) import_export_decl (fn); + /* If this function is marked with the constructor attribute, add it + to the list of functions to be called along with constructors + from static duration objects. */ + if (DECL_STATIC_CONSTRUCTOR (fn)) + static_ctors = tree_cons (NULL_TREE, fn, static_ctors); + + /* If this function is marked with the destructor attribute, add it + to the list of functions to be called along with destructors from + static duration objects. */ + if (DECL_STATIC_DESTRUCTOR (fn)) + static_dtors = tree_cons (NULL_TREE, fn, static_dtors); + function_depth++; /* Expand or defer, at the whim of the compilation unit manager. */ @@ -3035,6 +3047,27 @@ nullify_returns_r (tree* tp, int* walk_subtrees, void* data) else if (TREE_CODE (*tp) == CLEANUP_STMT && CLEANUP_DECL (*tp) == nrv) CLEANUP_EH_ONLY (*tp) = 1; + /* Replace the DECL_STMT for the NRV with an initialization of the + RESULT_DECL, if needed. */ + else if (TREE_CODE (*tp) == DECL_STMT + && DECL_STMT_DECL (*tp) == nrv) + { + tree init; + if (DECL_INITIAL (nrv) + && DECL_INITIAL (nrv) != error_mark_node) + { + init = build (INIT_EXPR, void_type_node, + DECL_RESULT (current_function_decl), + DECL_INITIAL (nrv)); + DECL_INITIAL (nrv) = error_mark_node; + } + else + init = NULL_TREE; + init = build_stmt (EXPR_STMT, init); + TREE_CHAIN (init) = TREE_CHAIN (*tp); + STMT_LINENO (init) = STMT_LINENO (*tp); + *tp = init; + } /* Keep iterating. */ return NULL_TREE; diff --git a/contrib/gcc/cp/tree.c b/contrib/gcc/cp/tree.c index d39ff76..2e41211 100644 --- a/contrib/gcc/cp/tree.c +++ b/contrib/gcc/cp/tree.c @@ -1,6 +1,6 @@ /* Language-dependent node constructors for parse phase of GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -1546,6 +1546,12 @@ cp_tree_equal (tree t1, tree t2) case IDENTIFIER_NODE: return false; + case BASELINK: + return (BASELINK_BINFO (t1) == BASELINK_BINFO (t2) + && BASELINK_ACCESS_BINFO (t1) == BASELINK_ACCESS_BINFO (t2) + && cp_tree_equal (BASELINK_FUNCTIONS (t1), + BASELINK_FUNCTIONS (t2))); + case TEMPLATE_PARM_INDEX: return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2) && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2) @@ -1598,6 +1604,11 @@ cp_tree_equal (tree t1, tree t2) return same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2)); + case OVERLOAD: + if (OVL_FUNCTION (t1) != OVL_FUNCTION (t2)) + return false; + return cp_tree_equal (OVL_CHAIN (t1), OVL_CHAIN (t2)); + default: break; } @@ -1764,6 +1775,8 @@ pod_type_p (tree t) return 1; /* pointer to non-member */ if (TYPE_PTR_TO_MEMBER_P (t)) return 1; /* pointer to member */ + if (TREE_CODE (t) == VECTOR_TYPE) + return 1; /* vectors are (small) arrays of scalars */ if (! CLASS_TYPE_P (t)) return 0; /* other non-class type (reference or function) */ @@ -2494,6 +2507,8 @@ stabilize_init (tree init, tree *initp) 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 && CONSTRUCTOR_ELTS (t) == NULL_TREE) { @@ -2507,12 +2522,28 @@ stabilize_init (tree init, tree *initp) if (TREE_CODE (t) == COND_EXPR) return false; - stabilize_call (t, initp); + /* 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 + body of a template. */ + +tree +fold_if_not_in_template (tree expr) +{ + /* In the body of a template, there is never any need to call + "fold". We will call fold later when actually instantiating the + template. Integral constant expressions in templates will be + evaluated via fold_non_dependent_expr, as necessary. */ + return (processing_template_decl ? expr : fold (expr)); +} + #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) /* Complain that some language-specific thing hanging off a tree diff --git a/contrib/gcc/cp/typeck.c b/contrib/gcc/cp/typeck.c index 5044db4..0c9c6c4 100644 --- a/contrib/gcc/cp/typeck.c +++ b/contrib/gcc/cp/typeck.c @@ -1,6 +1,6 @@ /* Build expressions with type checking for C++ compiler. Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -1216,7 +1216,7 @@ cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain) if (type == error_mark_node) return error_mark_node; - if (processing_template_decl) + if (dependent_type_p (type)) { value = build_min (op, size_type_node, type); TREE_READONLY (value) = 1; @@ -3458,7 +3458,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, tree result = build (resultcode, build_type, op0, op1); tree folded; - folded = fold (result); + folded = fold_if_not_in_template (result); if (folded == result) TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1); if (final_type != 0) @@ -3548,6 +3548,7 @@ build_x_unary_op (enum tree_code code, tree xarg) { if (type_dependent_expression_p (xarg)) return build_min_nt (code, xarg, NULL_TREE); + xarg = build_non_dependent_expr (xarg); } @@ -3609,13 +3610,13 @@ build_x_unary_op (enum tree_code code, tree xarg) else if (TREE_CODE (xarg) == TARGET_EXPR) warning ("taking address of temporary"); exp = build_unary_op (ADDR_EXPR, xarg, 0); - if (TREE_CODE (exp) == ADDR_EXPR) - PTRMEM_OK_P (exp) = ptrmem; } if (processing_template_decl && exp != error_mark_node) - return build_min_non_dep (code, exp, orig_expr, - /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE); + exp = build_min_non_dep (code, exp, orig_expr, + /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE); + if (TREE_CODE (exp) == ADDR_EXPR) + PTRMEM_OK_P (exp) = ptrmem; return exp; } @@ -4077,6 +4078,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert) is an error. */ else if (TREE_CODE (argtype) != FUNCTION_TYPE && TREE_CODE (argtype) != METHOD_TYPE + && TREE_CODE (arg) != OFFSET_REF && !lvalue_or_else (arg, "unary `&'")) return error_mark_node; @@ -4091,7 +4093,11 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert) expression so we can just form an ADDR_EXPR with the correct type. */ || processing_template_decl) - addr = build_address (arg); + { + addr = build_address (arg); + if (TREE_CODE (arg) == OFFSET_REF) + PTRMEM_OK_P (addr) = PTRMEM_OK_P (arg); + } else if (TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK) { tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1)); @@ -4160,7 +4166,8 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert) for certain kinds of expressions which are not really lvalues but which we can accept as lvalues. - If ARG is not a kind of expression we can handle, return zero. */ + If ARG is not a kind of expression we can handle, return + NULL_TREE. */ tree unary_complex_lvalue (enum tree_code code, tree arg) @@ -5509,7 +5516,10 @@ build_ptrmemfunc (tree type, tree pfn, int force) } /* Just adjust the DELTA field. */ - my_friendly_assert (TREE_TYPE (delta) == ptrdiff_type_node, 20030727); + my_friendly_assert + (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (delta), + ptrdiff_type_node), + 20030727); if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta) n = cp_build_binary_op (LSHIFT_EXPR, n, integer_one_node); delta = cp_build_binary_op (PLUS_EXPR, delta, n); diff --git a/contrib/gcc/cp/typeck2.c b/contrib/gcc/cp/typeck2.c index 300e8e6..780c3e7 100644 --- a/contrib/gcc/cp/typeck2.c +++ b/contrib/gcc/cp/typeck2.c @@ -348,9 +348,11 @@ split_nonconstant_init_1 (tree dest, tree init, tree *pcode) case VECTOR_TYPE: if (!initializer_constant_valid_p (init, type)) { + tree cons = copy_node (init); CONSTRUCTOR_ELTS (init) = NULL; - code = build (MODIFY_EXPR, type, dest, init); + code = build (MODIFY_EXPR, type, dest, cons); code = build_stmt (EXPR_STMT, code); + *pcode = code; pcode = &TREE_CHAIN (code); } break; @@ -445,28 +447,18 @@ store_init_value (tree decl, tree init) init = build_x_compound_expr_from_list (init, "initializer"); } - /* End of special C++ code. */ - /* Digest the specified initializer into an expression. */ value = digest_init (type, init, (tree *) 0); - - /* Store the expression if valid; else report error. */ - - if (TREE_CODE (value) == ERROR_MARK) - ; - /* Other code expects that initializers for objects of types that need - constructing never make it into DECL_INITIAL, and passes 'init' to - build_aggr_init without checking DECL_INITIAL. So just return. */ - else if (TYPE_NEEDS_CONSTRUCTING (type)) - return build (INIT_EXPR, type, decl, value); - else if (TREE_STATIC (decl) - && (! TREE_CONSTANT (value) - || ! initializer_constant_valid_p (value, TREE_TYPE (value)))) + /* If the initializer is not a constant, fill in DECL_INITIAL with + the bits that are constant, and then return an expression that + will perform the dynamic initialization. */ + if (value != error_mark_node + && (! TREE_CONSTANT (value) + || ! initializer_constant_valid_p (value, TREE_TYPE (value)))) return split_nonconstant_init (decl, value); - - /* Store the VALUE in DECL_INITIAL. If we're building a - statement-tree we will actually expand the initialization later - when we output this function. */ + /* If the value is a constant, just put it in DECL_INITIAL. If DECL + is an automatic variable, the middle end will turn this into a + dynamic initialization later. */ DECL_INITIAL (decl) = value; return NULL_TREE; } |