diff options
author | kan <kan@FreeBSD.org> | 2006-08-26 21:29:10 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2006-08-26 21:29:10 +0000 |
commit | 5c84bed2e8cff6c766e11d6ea545e97164e691c5 (patch) | |
tree | 7078a2224aa03a9d5caa5d11a9c917980f60fd6a /contrib/gcc/cp | |
parent | 768d4ea5cbe248d3d90adabc5fd80c7c1fa74bcb (diff) | |
parent | ab6c6e434e4ca0bf593007d49dee6eceb73286c0 (diff) | |
download | FreeBSD-src-5c84bed2e8cff6c766e11d6ea545e97164e691c5.zip FreeBSD-src-5c84bed2e8cff6c766e11d6ea545e97164e691c5.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r161651,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib/gcc/cp')
-rw-r--r-- | contrib/gcc/cp/ChangeLog | 463 | ||||
-rw-r--r-- | contrib/gcc/cp/call.c | 21 | ||||
-rw-r--r-- | contrib/gcc/cp/class.c | 36 | ||||
-rw-r--r-- | contrib/gcc/cp/cp-tree.def | 4 | ||||
-rw-r--r-- | contrib/gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | contrib/gcc/cp/cvt.c | 3 | ||||
-rw-r--r-- | contrib/gcc/cp/decl2.c | 28 | ||||
-rw-r--r-- | contrib/gcc/cp/error.c | 3 | ||||
-rw-r--r-- | contrib/gcc/cp/init.c | 11 | ||||
-rw-r--r-- | contrib/gcc/cp/lex.c | 24 | ||||
-rw-r--r-- | contrib/gcc/cp/method.c | 8 | ||||
-rw-r--r-- | contrib/gcc/cp/name-lookup.c | 63 | ||||
-rw-r--r-- | contrib/gcc/cp/name-lookup.h | 1 | ||||
-rw-r--r-- | contrib/gcc/cp/parser.c | 288 | ||||
-rw-r--r-- | contrib/gcc/cp/pt.c | 131 | ||||
-rw-r--r-- | contrib/gcc/cp/search.c | 8 | ||||
-rw-r--r-- | contrib/gcc/cp/semantics.c | 36 | ||||
-rw-r--r-- | contrib/gcc/cp/typeck.c | 74 |
18 files changed, 912 insertions, 292 deletions
diff --git a/contrib/gcc/cp/ChangeLog b/contrib/gcc/cp/ChangeLog index a40a034..198fc90 100644 --- a/contrib/gcc/cp/ChangeLog +++ b/contrib/gcc/cp/ChangeLog @@ -1,3 +1,466 @@ +2006-03-05 Release Manager + + * GCC 3.4.6 released. + +2006-02-23 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/26291 + * decl.c (grok_op_properties): Check for ellipsis in arguments of + operators. + +2006-02-08 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/26070 + * decl.c (grokdeclarator): Clear RID_STATIC together with staticp. + +2006-02-01 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + 2005-12-22 Mark Mitchell <mark@codesourcery.com> + + PR c++/25369 + * pt.c (tsubst_copy): Call mark_used on the member referenced by an + OFFSET_REF. + * decl2.c (mark_used): Accept BASELINKs. + +2006-02-01 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + 2005-12-19 Mark Mitchell <mark@codesourcery.com> + + PR c++/24915 + * class.c (add_method): Do not treat templates as identical unless + their return types are the same. + +2006-02-01 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + 2005-12-19 Mark Mitchell <mark@codesourcery.com> + + PR c++/24278 + * init.c (expand_member_init): Print messages about baseclasses + using %T rather than %D. + +2006-01-24 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/16829 + * decl.c (start_preparsed_function): Check default arguments + unconditionally. + * name-lookup.c (pushdecl_maybe_friend): Check default arguments + of all functions and function templates. + * parser.c (cp_parser_late_parsing_default_args): Check default + arguments. + * decl2.c (check_default_args): Set missing default arguments to + error_mark_node. + +2006-01-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/25854 + * pt.c (maybe_process_partial_specialization): Return early on + error_mark_node. + +2005-12-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/20552 + Backport: + 2004-03-08 Mark Mitchell <mark@codesourcery.com> + + * decl.c (duplicate_decls): Don't check IDENTIFIER_ERROR_LOCUS. + +2005-12-07 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/19397 + PR c++/19762 + PR c++/19764 + * parser.c (cp_parser_declarator_id): Check for error_mark_node + before building a SCOPE_REF. + +2005-12-07 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + 2005-10-20 Mark Mitchell <mark@codesourcery.com> + + PR c++/22618 + * search.c (accessible_p): Check access in the outermost set of + template parameters. + +2005-12-06 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + 2005-10-18 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/21383 + * name-lookup.c (arg_assoc): Template args can be null in a + template-id-expr. + +2005-12-05 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + 2005-10-13 Mark Mitchell <mark@codesourcery.com> + + PR c++/22352 + * pt.c (tsubst_template_parms): Set processing_template_decl while + processing the parameters. + (tsubst_decl): Set processing_template_decl when substituting into + a TEMPLATE_DECL. + +2005-12-05 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + 2005-10-13 Mark Mitchell <mark@codesourcery.com> + + PR c++/22464 + * semantics.c (finish_id_expression): Issue errors about uses of + local variables in containing functions even in templates. + +2005-12-05 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + 2005-10-13 Mark Mitchell <mark@codesourcery.com> + + PR c++/23307 + * pt.c (push_template_decl_real): Complain about attempts to + declare template variables. + +2005-11-30 Release Manager + + * GCC 3.4.5 released. + +2005-11-23 Jakub Jelinek <jakub@redhat.com> + + PR c++/21983 + * class.c (find_final_overrider): Move diagnostic about no unique final + overrider to... + (update_vtable_entry_for_fn): ... here. + +2005-11-15 Jason Merrill <jason@redhat.com> + + PR c++/24580 + * method.c (locate_copy): Also use skip_artificial_parms here. + (synthesize_exception_spec): Use CLASS_TYPE_P rather than checking + for RECORD_TYPE. + +2005-11-16 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport from mainline: + 2005-10-12 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/23797 + * parser.c (cp_parser_functional_cast): Cope when TYPE is not a + TYPE_DECL. Use dependent_type_p to check type. + * pt.c (uses_template_parms_p): Use dependent_type_p for a + TYPE_DECL. + (type_dependent_expression_p): Assert we've not been given a + TYPE_DECL. + +2005-11-15 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/19253 + PR c++/22172 + Backport from mainline: + 2005-11-02 Mark Mitchell <mark@codesourcery.com> + + * parser.c (cp_parser_postfix_expression): Use + cp_parser_elaborated_type_specifier to handle typename-types in + functional casts. + (cp_parser_enclosed_argument_list): Skip ahead to the end of the + template argument list if the closing ">" is not found. + +2005-11-14 Jason Merrill <jason@redhat.com> + + PR c++/24580 + * method.c (locate_ctor): Skip all artificial parms, not just + 'this'. + +2005-10-28 Josh Conner <jconner@apple.com> + + PR c++/22153 + * parser.c (cp_parser_member_declaration): Detect and handle + a template specialization. + +2005-10-20 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/22508 + * init.c (build_new_1): Remove misleading comment. + +2005-10-12 Paolo Bonzini <bonzini@gnu.org> + + PR c++/24052 + * error.c (dump_expr): Pass LABEL_DECL to dump_decl. Print + an ADDR_EXPR of a LABEL_DECL as &&. + +2005-10-11 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + 2004-09-23 Andrew Pinski <pinskia@physics.uc.edu> + PR c++/17618 + * cvt.c (cp_convert_to_pointer): Return early when the type is + an error_mark_node. + + 2004-05-22 Roger Sayle <roger@eyesopen.com> + * name-lookup.c (check_for_out_of_scope_variable): Avoid ICE by + returning when TREE_TYPE is error_mark_node. + * typeck.c (require_complete_type): Return error_mark_node if + value's type is an error_mark_node. + + 2004-11-02 Mark Mitchell <mark@codesourcery.com> + PR c++/18177 + * typeck.c (build_const_cast): Use error_operand_p. + +2005-10-06 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + * call.c (resolve_args): Remove redundant test. + +2005-09-21 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/23965 + * call.c (resolve_args): Return error_mark_node on arguments + whose TREE_TYPE is error_mark_node. + +2005-09-21 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/17609 + Backport: + + 2004-03-08 Mark Mitchell <mark@codesourcery.com> + * lex.c (unqualified_name_lookup_error): Create a dummy VAR_DECL + in the innermost scope, rather than at namespace scope. + * name-lookup.c (push_local_binding): Give it external linkage. + * name-lookup.h (push_local_binding): Declare it. + +2005-09-17 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + + 2004-11-27 Mark Mitchell <mark@codesourcery.com> + PR c++/18368 + * parser.c (cp_parser_check_for_definition_in_return_type): Take + the defined type as a parameter, and inform the user about the + possibility of a missing semicolon. + (cp_parser_explicit_instantiation): Adjust call to + cp_parser_check_for_definition_in_return_type. + (cp_parser_init_declarator): Likewise. + (cp_parser_member_declaration): Likewise. + +2005-09-17 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/18803 + Revert: + + 2005-09-02 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + PR c++/18445 + * class.c (instantiate_type): Treat NON_DEPENDENT_EXPRs with + unknown_type as non matching. + * pt.c (build_non_dependent_expr): Do not build a + NON_DEPENDENT_EXPR for a VAR_DECL. + +2005-09-06 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + + 2004-12-14 Mark Mitchell <mark@codesourcery.com> + PR c++/18738 + * decl.c (make_typename_type): Do not handle namespace-scoped + names here. + (tag_name): Handle typename_type. + (check_elaborated_type_specifier): Handle typenames. + * parser.c (cp_parser_diagnose_invalid_type_name): Do not call + make_typename_type for namespace-scoped names here. + (cp_parser_elaborated_type_specifier): Use + cp_parser_diagnose_invalid_type_name. + +2005-09-03 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + + 2005-08-26 Mark Mitchell <mark@codesourcery.com> + PR c++/19004 + * pt.c (uses_template_parms): Handle IDENTIFIER_NODE. + (type_dependent_expression_p): Allow BASELINKs whose associated + functions are simply a FUNCTION_DECL. + +2005-09-02 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/22233 + * pt.c (push_template_decl_real): Return error_mark_node if the + number of template parameters does not match previous definition. + * decl.c (start_function): Handle error_mark_node returned by + push_template_decl. + +2005-09-02 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + + 2004-11-25 Mark Mitchell <mark@codesourcery.com> + PR c++/18466 + * decl.c (grokvardecl): Keep track of whether or not a there was + explicit qualification. + * name-lookup.c (set_decl_namespace): Complain about explicit + qualification of a name within its own namespace. + +2005-09-02 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + + 2004-11-25 Mark Mitchell <mark@codesourcery.com> + PR c++/18445 + * class.c (instantiate_type): Treat NON_DEPENDENT_EXPRs with + unknown_type as non matching. + * pt.c (build_non_dependent_expr): Do not build a + NON_DEPENDENT_EXPR for a VAR_DECL. + +2005-09-01 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + + 2004-11-27 Mark Mitchell <mark@codesourcery.com> + PR c++/18512 + * parser.c (cp_parser_postfix_expression): Robustify. + +2005-09-01 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + + 2004-11-25 Mark Mitchell <mark@codesourcery.com> + PR c++/18545 + * typeck.c (check_return_expr): Robustify. + +2005-09-01 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + Backport: + + 2005-02-22 Mark Mitchell <mark@codesourcery.com> + PR c++/20153 + * decl2.c (build_anon_union_vars): Add type parameter. + (finish_anon_union): Pass it. + + 2005-07-28 Mark Mitchell <mark@codesourcery.com> + PR c++/22545 + * call.c (add_builtin_candidate): Adjust for changes in + representation of pointer-to-member types. + +2005-09-01 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/13377 + * parser.c (cp_parser_lookup_name): Pass LOOKUP_COMPLAIN to + lookup_name_real on final parse. + +2005-08-31 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/23586 + * parser.c (cp_parser_namespace_name): Move diagnostic for + invalid namespace-name to here from ... + * name-lookup.c (do_namespace_alias): ... here and ... + (do_using_directive): ... here. Remove dead code. + +2005-08-31 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/23639 + * semantics.c (qualified_name_lookup_error): Do not complain again + on invalid scope. + +2005-07-28 Giovanni Bajo <giovannibajo@gcc.gnu.org> + + Backport: + + 2004-09-16 Mark Mitchell <mark@codesourcery.com> + PR c++/16002 + * parser.c (cp_parser_simple_declaration): Commit to tentative + parses after seeing a decl-specifier. + (cp_parser_simple_declaration): Eliminate spurious message. + (cp_parser_init_declarator): Adjust error message. + + 2005-06-17 Geoffrey Keating <geoffk@apple.com> + PR c++/17413 + * pt.c (type_unification_real): Apply template type deduction even + to procedure parameters that are not dependent on a template + parameter. + + 2004-11-02 Mark Mitchell <mark@codesourcery.com> + PR c++/18124 + * parser.c (cp_parser_type_parameter): Robustify. + PR c++/18155 + * parser.c (cp_parser_single_declaration): Disallow template + typedefs. + (cp_parser_typedef_p): New function. + + 2004-12-21 Mark Mitchell <mark@codesourcery.com> + PR c++/18378 + * call.c (convert_like_real): Do not permit the use of a copy + constructor to copy a packed field. + +2005-07-25 Giovanni Bajo <giovannibajo@gcc.gnu.org> + + PR c++/19208 + * pt.c (tsubst): Use fold_non_dependent_expr to fold array domains. + +2005-06-14 Mark Mitchell <mark@codesourcery.com> + + PR c++/21987 + * decl.c (grok_op_properties): Add missing warn_conversion check. + +2005-06-13 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/20789 + * decl.c (cp_finish_decl): Clear runtime runtime initialization if + in-class decl's initializer is bad. + +2005-06-10 Aldy Hernandez <aldyh@redhat.com> + + PR c++/10611 + * cvt.c (build_expr_type_conversion): Same. + * typeck.c (build_binary_op): Handle vectors. + (common_type): Same. + (type_after_usual_arithmetic_conversions): Same. + * testsuite/g++.dg/conversion/simd2.C: New. + +2005-06-08 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/21903 + * cp-tree.def (DEFAULT_ARG): Document TREE_CHAIN use. + * parser.c (cp_parser_late_parsing_default_args): Propagate parsed + argument to any early instantiations. + * pt.c (tsubst_arg_types): Chain early instantiation of default + arg. + + PR c++/19884 + * pt.c (check_explicit_specialization): Make sure namespace + binding lookup found an overloaded function. + (lookup_template_function): Just assert FNS is an overloaded + function. + + PR c++/19608 + * parser.c (cp_parser_late_parsing_for_member): Use + current_function_decl as scope to push to and from. + testsuite: + +2005-06-08 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/20563 + * parser.c (cp_parser_label_declaration): Deal with invalid/missing + identifiers. + +2005-06-03 Mark Mitchell <mark@codesourcery.com> + + PR c++/21853 + * typeck.c (casts_away_constness_r): Do not drop cv-qualifiers on + the pointed-to type for a pointer-to-member. + +2005-06-03 Mark Mitchell <mark@codesourcery.com> + + PR c++/21336 + * cp-tree.h (grok_op_properties): Remove friendp parameter. + * decl.c (grokfndecl): Adjust call. + (grok_op_properties): Determine the class of which the function is + a member by looking at its DECL_CONTEXT, not current_class_type. + * pt.c (tsubst_decl): Adjust call to grok_op_properties. + +2005-05-26 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + + PR c++/21768 + * pt.c (redeclare_class_template): Change error message according + to coding conventions. + 2005-05-19 Release Manager * GCC 3.4.4 released. diff --git a/contrib/gcc/cp/call.c b/contrib/gcc/cp/call.c index aeed315..01c8926 100644 --- a/contrib/gcc/cp/call.c +++ b/contrib/gcc/cp/call.c @@ -1556,7 +1556,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, if (IS_AGGR_TYPE (c1) && DERIVED_FROM_P (c2, c1) && (TYPE_PTRMEMFUNC_P (type2) - || is_complete (TREE_TYPE (TREE_TYPE (type2))))) + || is_complete (TYPE_PTRMEM_POINTED_TO_TYPE (type2)))) break; } return; @@ -2544,7 +2544,7 @@ resolve_args (tree args) { tree arg = TREE_VALUE (t); - if (arg == error_mark_node) + if (error_operand_p (arg)) return error_mark_node; else if (VOID_TYPE_P (TREE_TYPE (arg))) { @@ -4080,13 +4080,12 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner, if (NEED_TEMPORARY_P (convs) || !lvalue_p (expr)) { tree type = TREE_TYPE (TREE_OPERAND (convs, 0)); + cp_lvalue_kind lvalue = real_lvalue_p (expr); if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type))) { /* If the reference is volatile or non-const, we cannot create a temporary. */ - cp_lvalue_kind lvalue = real_lvalue_p (expr); - if (lvalue & clk_bitfield) error ("cannot bind bitfield `%E' to `%T'", expr, ref_type); @@ -4097,6 +4096,20 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner, error ("cannot bind rvalue `%E' to `%T'", expr, ref_type); return error_mark_node; } + /* If the source is a packed field, and we must use a copy + constructor, then building the target expr will require + binding the field to the reference parameter to the + copy constructor, and we'll end up with an infinite + loop. If we can use a bitwise copy, then we'll be + OK. */ + if ((lvalue & clk_packed) + && CLASS_TYPE_P (type) + && !TYPE_HAS_TRIVIAL_INIT_REF (type)) + { + error ("cannot bind packed field `%E' to `%T'", + expr, ref_type); + return error_mark_node; + } expr = build_target_expr_with_type (expr, type); } diff --git a/contrib/gcc/cp/class.c b/contrib/gcc/cp/class.c index 09daf11..c14313c 100644 --- a/contrib/gcc/cp/class.c +++ b/contrib/gcc/cp/class.c @@ -879,9 +879,10 @@ add_method (tree type, tree method, int error_p) fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); + tree fn_type; + tree method_type; tree parms1; tree parms2; - bool same = 1; if (TREE_CODE (fn) != TREE_CODE (method)) continue; @@ -896,8 +897,10 @@ add_method (tree type, tree method, int error_p) functions in the derived class override and/or hide member functions with the same name and parameter types in a base class (rather than conflicting). */ - parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn)); - parms2 = TYPE_ARG_TYPES (TREE_TYPE (method)); + fn_type = TREE_TYPE (fn); + method_type = TREE_TYPE (method); + parms1 = TYPE_ARG_TYPES (fn_type); + parms2 = TYPE_ARG_TYPES (method_type); /* Compare the quals on the 'this' parm. Don't compare the whole types, as used functions are treated as @@ -906,23 +909,25 @@ add_method (tree type, tree method, int error_p) && ! DECL_STATIC_FUNCTION_P (method) && (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1))) != TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2))))) - same = 0; + continue; /* For templates, the template parms must be identical. */ if (TREE_CODE (fn) == TEMPLATE_DECL - && !comp_template_parms (DECL_TEMPLATE_PARMS (fn), - DECL_TEMPLATE_PARMS (method))) - same = 0; + && (!same_type_p (TREE_TYPE (fn_type), + TREE_TYPE (method_type)) + || !comp_template_parms (DECL_TEMPLATE_PARMS (fn), + DECL_TEMPLATE_PARMS (method)))) + continue; if (! DECL_STATIC_FUNCTION_P (fn)) parms1 = TREE_CHAIN (parms1); if (! DECL_STATIC_FUNCTION_P (method)) parms2 = TREE_CHAIN (parms2); - if (same && compparms (parms1, parms2) + if (compparms (parms1, parms2) && (!DECL_CONV_FN_P (fn) - || same_type_p (TREE_TYPE (TREE_TYPE (fn)), - TREE_TYPE (TREE_TYPE (method))))) + || same_type_p (TREE_TYPE (fn_type), + TREE_TYPE (method_type)))) { if (using && DECL_CONTEXT (fn) == type) /* Defer to the local function. */ @@ -2035,11 +2040,7 @@ find_final_overrider (tree derived, tree binfo, tree fn) /* If there was no winner, issue an error message. */ if (!ffod.candidates || TREE_CHAIN (ffod.candidates)) - { - error ("no unique final overrider for `%D' in `%T'", fn, - BINFO_TYPE (derived)); - return error_mark_node; - } + return error_mark_node; return ffod.candidates; } @@ -2099,7 +2100,10 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, /* Find the final overrider. */ overrider = find_final_overrider (TYPE_BINFO (t), b, target_fn); if (overrider == error_mark_node) - return; + { + error ("no unique final overrider for `%D' in `%T'", target_fn, t); + return; + } overrider_target = overrider_fn = TREE_PURPOSE (overrider); /* Check for adjusting covariant return types. */ diff --git a/contrib/gcc/cp/cp-tree.def b/contrib/gcc/cp/cp-tree.def index 36b7aaa..f6a2bee 100644 --- a/contrib/gcc/cp/cp-tree.def +++ b/contrib/gcc/cp/cp-tree.def @@ -203,7 +203,9 @@ DEFTREECODE (USING_DECL, "using_decl", 'd', 0) /* A using directive. The operand is USING_STMT_NAMESPACE. */ DEFTREECODE (USING_STMT, "using_directive", 'e', 1) -/* An un-parsed default argument. Looks like an IDENTIFIER_NODE. */ +/* An un-parsed default argument. + TREE_CHAIN is used to hold instantiations of functions that had to + be instantiated before the argument was parsed. */ DEFTREECODE (DEFAULT_ARG, "default_arg", 'x', 0) /* A template-id, like foo<int>. The first operand is the template. diff --git a/contrib/gcc/cp/cp-tree.h b/contrib/gcc/cp/cp-tree.h index ed33f32..cc1f937 100644 --- a/contrib/gcc/cp/cp-tree.h +++ b/contrib/gcc/cp/cp-tree.h @@ -3683,7 +3683,7 @@ extern int copy_fn_p (tree); extern tree get_scope_of_declarator (tree); extern void grok_special_member_properties (tree); extern int grok_ctor_properties (tree, tree); -extern bool grok_op_properties (tree, int, bool); +extern bool grok_op_properties (tree, bool); extern tree xref_tag (enum tag_types, tree, bool, bool); extern tree xref_tag_from_type (tree, tree, int); extern void xref_basetypes (tree, tree); diff --git a/contrib/gcc/cp/cvt.c b/contrib/gcc/cp/cvt.c index 95fce07..2071c26 100644 --- a/contrib/gcc/cp/cvt.c +++ b/contrib/gcc/cp/cvt.c @@ -79,6 +79,8 @@ cp_convert_to_pointer (tree type, tree expr, bool force) tree intype = TREE_TYPE (expr); enum tree_code form; tree rval; + if (intype == error_mark_node) + return error_mark_node; if (IS_AGGR_TYPE (intype)) { @@ -1029,6 +1031,7 @@ build_expr_type_conversion (int desires, tree expr, bool complain) return expr; /* else fall through... */ + case VECTOR_TYPE: case BOOLEAN_TYPE: return (desires & WANT_INT) ? expr : NULL_TREE; case ENUMERAL_TYPE: diff --git a/contrib/gcc/cp/decl2.c b/contrib/gcc/cp/decl2.c index 09fe5dd..abd86f7 100644 --- a/contrib/gcc/cp/decl2.c +++ b/contrib/gcc/cp/decl2.c @@ -64,7 +64,6 @@ typedef struct priority_info_s { static void mark_vtable_entries (tree); static void grok_function_init (tree, tree); static bool maybe_emit_vtables (tree); -static tree build_anon_union_vars (tree); static bool acceptable_java_type (tree); static tree start_objects (int, int); static void finish_objects (int, int, tree); @@ -1131,14 +1130,13 @@ defer_fn (tree fn) VARRAY_PUSH_TREE (deferred_fns, fn); } -/* Walks through the namespace- or function-scope anonymous union OBJECT, - building appropriate ALIAS_DECLs. Returns one of the fields for use in - the mangled name. */ +/* Walks through the namespace- or function-scope anonymous union + OBJECT, with the indicated TYPE, building appropriate ALIAS_DECLs. + Returns one of the fields for use in the mangled name. */ static tree -build_anon_union_vars (tree object) +build_anon_union_vars (tree type, tree object) { - tree type = TREE_TYPE (object); tree main_decl = NULL_TREE; tree field; @@ -1185,7 +1183,7 @@ build_anon_union_vars (tree object) decl = pushdecl (decl); } else if (ANON_AGGR_TYPE_P (TREE_TYPE (field))) - decl = build_anon_union_vars (ref); + decl = build_anon_union_vars (TREE_TYPE (field), ref); else decl = 0; @@ -1225,7 +1223,7 @@ finish_anon_union (tree anon_union_decl) return; } - main_decl = build_anon_union_vars (anon_union_decl); + main_decl = build_anon_union_vars (type, anon_union_decl); if (main_decl == NULL_TREE) { warning ("anonymous union with no members"); @@ -2961,7 +2959,7 @@ check_default_args (tree x) { cp_error_at ("default argument missing for parameter %P of `%+#D'", i, x); - break; + TREE_PURPOSE (arg) = error_mark_node; } } } @@ -2969,6 +2967,18 @@ check_default_args (tree x) void mark_used (tree decl) { + /* If DECL is a BASELINK for a single function, then treat it just + like the DECL for the function. Otherwise, if the BASELINK is + for an overloaded function, we don't know which function was + actually used until after overload resolution. */ + if (TREE_CODE (decl) == BASELINK) + { + decl = BASELINK_FUNCTIONS (decl); + if (really_overloaded_fn (decl)) + return; + decl = OVL_CURRENT (decl); + } + TREE_USED (decl) = 1; if (processing_template_decl || skip_evaluation) return; diff --git a/contrib/gcc/cp/error.c b/contrib/gcc/cp/error.c index 5b83c60..381b5be 100644 --- a/contrib/gcc/cp/error.c +++ b/contrib/gcc/cp/error.c @@ -1307,6 +1307,7 @@ dump_expr (tree t, int flags) case FUNCTION_DECL: case TEMPLATE_DECL: case NAMESPACE_DECL: + case LABEL_DECL: case OVERLOAD: case IDENTIFIER_NODE: dump_decl (t, (flags & ~TFF_DECL_SPECIFIERS) | TFF_NO_FUNCTION_ARGUMENTS); @@ -1547,6 +1548,8 @@ dump_expr (tree t, int flags) || (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)) dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); + else if (TREE_CODE (TREE_OPERAND (t, 0)) == LABEL_DECL) + dump_unary_op ("&&", t, flags); else dump_unary_op ("&", t, flags); break; diff --git a/contrib/gcc/cp/init.c b/contrib/gcc/cp/init.c index 732d4a0..4e3cd4b 100644 --- a/contrib/gcc/cp/init.c +++ b/contrib/gcc/cp/init.c @@ -1015,11 +1015,11 @@ expand_member_init (tree name) if (!direct_binfo && !virtual_binfo) { if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - error ("type `%D' is not a direct or virtual base of `%T'", - name, current_class_type); + error ("type `%T' is not a direct or virtual base of `%T'", + basetype, current_class_type); else - error ("type `%D' is not a direct base of `%T'", - name, current_class_type); + error ("type `%T' is not a direct base of `%T'", + basetype, current_class_type); return NULL_TREE; } @@ -2075,9 +2075,6 @@ build_new_1 (tree exp) fns = lookup_fnfields (true_type, fnname, /*protect=*/2); if (!fns) { - /* See PR 15967. This should never happen (and it is - fixed correctly in mainline), but on the release branch - we prefer this less-intrusive approacch. */ error ("no suitable or ambiguous `%D' found in class `%T'", fnname, true_type); return error_mark_node; diff --git a/contrib/gcc/cp/lex.c b/contrib/gcc/cp/lex.c index 2239c76..66e45ed 100644 --- a/contrib/gcc/cp/lex.c +++ b/contrib/gcc/cp/lex.c @@ -627,26 +627,18 @@ unqualified_name_lookup_error (tree name) if (name != ansi_opname (ERROR_MARK)) error ("`%D' not defined", name); } - else if (current_function_decl == 0) - error ("`%D' was not declared in this scope", name); else { - if (IDENTIFIER_NAMESPACE_VALUE (name) != error_mark_node - || IDENTIFIER_ERROR_LOCUS (name) != current_function_decl) + error ("`%D' was not declared in this scope", name); + /* Prevent repeated error messages by creating a VAR_DECL with + this NAME in the innermost block scope. */ + if (current_function_decl) { - static int undeclared_variable_notice; - - error ("`%D' undeclared (first use this function)", name); - - if (! undeclared_variable_notice) - { - error ("(Each undeclared identifier is reported only once for each function it appears in.)"); - undeclared_variable_notice = 1; - } + tree decl; + decl = build_decl (VAR_DECL, name, error_mark_node); + DECL_CONTEXT (decl) = current_function_decl; + push_local_binding (name, decl, 0); } - /* Prevent repeated error messages. */ - SET_IDENTIFIER_NAMESPACE_VALUE (name, error_mark_node); - SET_IDENTIFIER_ERROR_LOCUS (name, current_function_decl); } return error_mark_node; diff --git a/contrib/gcc/cp/method.c b/contrib/gcc/cp/method.c index ef69c37..9f3e72e 100644 --- a/contrib/gcc/cp/method.c +++ b/contrib/gcc/cp/method.c @@ -851,7 +851,7 @@ synthesize_exception_spec (tree type, tree (*extractor) (tree, void*), continue; while (TREE_CODE (type) == ARRAY_TYPE) type = TREE_TYPE (type); - if (TREE_CODE (type) != RECORD_TYPE) + if (!CLASS_TYPE_P (type)) continue; fn = (*extractor) (type, client); @@ -896,7 +896,9 @@ locate_ctor (tree type, void *client ATTRIBUTE_UNUSED) tree fn = OVL_CURRENT (fns); tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn)); - if (sufficient_parms_p (TREE_CHAIN (parms))) + parms = skip_artificial_parms_for (fn, parms); + + if (sufficient_parms_p (parms)) return fn; } return NULL_TREE; @@ -940,7 +942,7 @@ locate_copy (tree type, void *client_) int excess; int quals; - parms = TREE_CHAIN (parms); + parms = skip_artificial_parms_for (fn, parms); if (!parms) continue; src_type = non_reference (TREE_VALUE (parms)); diff --git a/contrib/gcc/cp/name-lookup.c b/contrib/gcc/cp/name-lookup.c index 3e79d3e..870eaab 100644 --- a/contrib/gcc/cp/name-lookup.c +++ b/contrib/gcc/cp/name-lookup.c @@ -35,7 +35,6 @@ static cxx_scope *innermost_nonclass_level (void); static tree select_decl (cxx_binding *, int); static cxx_binding *binding_for_name (cxx_scope *, tree); static tree lookup_name_current_level (tree); -static void push_local_binding (tree, tree, int); static tree push_overloaded_decl (tree, int); static bool lookup_using_namespace (tree, cxx_binding *, tree, tree, int); @@ -607,6 +606,9 @@ pushdecl (tree x) { int different_binding_level = 0; + if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x)) + check_default_args (x); + if (TREE_CODE (name) == TEMPLATE_ID_EXPR) name = TREE_OPERAND (name, 0); @@ -718,8 +720,6 @@ pushdecl (tree x) { if (TREE_CODE (t) == TYPE_DECL) SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t)); - else if (TREE_CODE (t) == FUNCTION_DECL) - check_default_args (t); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } @@ -1002,9 +1002,6 @@ pushdecl (tree x) } } - if (TREE_CODE (x) == FUNCTION_DECL) - check_default_args (x); - if (TREE_CODE (x) == VAR_DECL) maybe_register_incomplete_var (x); } @@ -1052,7 +1049,7 @@ maybe_push_decl (tree decl) doesn't really belong to this binding level, that it got here through a using-declaration. */ -static void +void push_local_binding (tree id, tree decl, int flags) { struct cp_binding_level *b; @@ -1180,6 +1177,10 @@ check_for_out_of_scope_variable (tree decl) return decl; DECL_ERROR_REPORTED (decl) = 1; + + if (TREE_TYPE (decl) == error_mark_node) + return decl; + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))) { error ("name lookup of `%D' changed for new ISO `for' scoping", @@ -3021,7 +3022,13 @@ set_decl_namespace (tree decl, tree scope, bool friendp) return; } else - return; + { + /* Writing "int N::i" to declare a variable within "N" is invalid. */ + if (at_namespace_scope_p ()) + error ("explicit qualification in declaration of `%D'", decl); + return; + } + complain: error ("`%D' should have been declared inside `%D'", decl, scope); @@ -3199,12 +3206,10 @@ namespace_ancestor (tree ns1, tree ns2) void do_namespace_alias (tree alias, tree namespace) { - if (TREE_CODE (namespace) != NAMESPACE_DECL) - { - /* The parser did not find it, so it's not there. */ - error ("unknown namespace `%D'", namespace); - return; - } + if (namespace == error_mark_node) + return; + + my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 20050830); namespace = ORIGINAL_NAMESPACE (namespace); @@ -3345,26 +3350,15 @@ do_toplevel_using_decl (tree decl, tree scope, tree name) void do_using_directive (tree namespace) { + if (namespace == error_mark_node) + return; + + my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 20050830); + if (building_stmt_tree ()) add_stmt (build_stmt (USING_STMT, namespace)); - - /* using namespace A::B::C; */ - if (TREE_CODE (namespace) == SCOPE_REF) - namespace = TREE_OPERAND (namespace, 1); - if (TREE_CODE (namespace) == IDENTIFIER_NODE) - { - /* Lookup in lexer did not find a namespace. */ - if (!processing_template_decl) - error ("namespace `%T' undeclared", namespace); - return; - } - if (TREE_CODE (namespace) != NAMESPACE_DECL) - { - if (!processing_template_decl) - error ("`%T' is not a namespace", namespace); - return; - } namespace = ORIGINAL_NAMESPACE (namespace); + if (!toplevel_bindings_p ()) push_using_directive (namespace); else @@ -4437,9 +4431,10 @@ arg_assoc (struct arg_lookup *k, tree n) return true; /* Now the arguments. */ - for (ix = TREE_VEC_LENGTH (args); ix--;) - if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1) - return true; + if (args) + for (ix = TREE_VEC_LENGTH (args); ix--;) + if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1) + return true; } else if (TREE_CODE (n) == OVERLOAD) { diff --git a/contrib/gcc/cp/name-lookup.h b/contrib/gcc/cp/name-lookup.h index 8377575..1ade1a9 100644 --- a/contrib/gcc/cp/name-lookup.h +++ b/contrib/gcc/cp/name-lookup.h @@ -287,6 +287,7 @@ extern tree lookup_namespace_name (tree, tree); extern tree lookup_qualified_name (tree, tree, bool, bool); extern tree lookup_name_nonclass (tree); extern tree lookup_function_nonclass (tree, tree); +extern void push_local_binding (tree, tree, int); extern int push_class_binding (tree, tree); extern bool pushdecl_class_level (tree); extern tree pushdecl_namespace_level (tree); diff --git a/contrib/gcc/cp/parser.c b/contrib/gcc/cp/parser.c index fb0d1e3..032cbd7 100644 --- a/contrib/gcc/cp/parser.c +++ b/contrib/gcc/cp/parser.c @@ -1672,6 +1672,8 @@ static bool cp_parser_declares_only_class_p (cp_parser *); static bool cp_parser_friend_p (tree); +static bool cp_parser_typedef_p + (tree); static cp_token *cp_parser_require (cp_parser *, enum cpp_ttype, const char *); static cp_token *cp_parser_require_keyword @@ -1717,7 +1719,7 @@ static bool cp_parser_simulate_error static void cp_parser_check_type_definition (cp_parser *); static void cp_parser_check_for_definition_in_return_type - (tree, int); + (tree, tree); static void cp_parser_check_for_invalid_template_id (cp_parser *, tree); static bool cp_parser_non_integral_constant_expression @@ -1849,14 +1851,13 @@ cp_parser_check_type_definition (cp_parser* parser) error ("%s", parser->type_definition_forbidden_message); } -/* This function is called when a declaration is parsed. If - DECLARATOR is a function declarator and DECLARES_CLASS_OR_ENUM - indicates that a type was defined in the decl-specifiers for DECL, - then an error is issued. */ +/* This function is called when the DECLARATOR is processed. The TYPE + was a type defined in the decl-specifiers. If it is invalid to + define a type in the decl-specifiers for DECLARATOR, an error is + issued. */ static void -cp_parser_check_for_definition_in_return_type (tree declarator, - int declares_class_or_enum) +cp_parser_check_for_definition_in_return_type (tree declarator, tree type) { /* [dcl.fct] forbids type definitions in return types. Unfortunately, it's not easy to know whether or not we are @@ -1866,9 +1867,12 @@ cp_parser_check_for_definition_in_return_type (tree declarator, || TREE_CODE (declarator) == ADDR_EXPR)) declarator = TREE_OPERAND (declarator, 0); if (declarator - && TREE_CODE (declarator) == CALL_EXPR - && declares_class_or_enum & 2) - error ("new types may not be defined in a return type"); + && TREE_CODE (declarator) == CALL_EXPR) + { + error ("new types may not be defined in a return type"); + inform ("(perhaps a semicolon is missing after the definition of `%T')", + type); + } } /* A type-specifier (TYPE) has been parsed which cannot be followed by @@ -3548,52 +3552,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) case RID_TYPENAME: { - 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. 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 - identifier. */ - cp_parser_parse_tentatively (parser); - /* Try a template-id. */ - id = cp_parser_template_id (parser, template_p, - /*check_dependency_p=*/true, - /*is_declaration=*/true); - /* 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. */ - 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 - functional cast is being performed. */ - else - type = make_typename_type (parser->scope, id, - /*complain=*/1); + /* The syntax permitted here is the same permitted for an + elaborated-type-specifier. */ + type = cp_parser_elaborated_type_specifier (parser, + /*is_friend=*/false, + /*is_declaration=*/false); postfix_expression = cp_parser_functional_cast (parser, type); } break; @@ -3964,20 +3929,29 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) if (parser->scope) idk = CP_ID_KIND_QUALIFIED; - if (name != error_mark_node - && !BASELINK_P (name) - && parser->scope) + /* If the name is a template-id that names a type, we will + get a TYPE_DECL here. That is invalid code. */ + if (TREE_CODE (name) == TYPE_DECL) { - name = build_nt (SCOPE_REF, parser->scope, name); - parser->scope = NULL_TREE; - parser->qualifying_scope = NULL_TREE; - parser->object_scope = NULL_TREE; + error ("invalid use of `%D'", name); + postfix_expression = error_mark_node; + } + else + { + if (name != error_mark_node && !BASELINK_P (name) + && parser->scope) + { + name = build_nt (SCOPE_REF, parser->scope, name); + parser->scope = NULL_TREE; + parser->qualifying_scope = NULL_TREE; + parser->object_scope = NULL_TREE; + } + if (scope && name && BASELINK_P (name)) + adjust_result_of_qualified_name_lookup + (name, BINFO_TYPE (BASELINK_BINFO (name)), scope); + postfix_expression = finish_class_member_access_expr + (postfix_expression, name); } - if (scope && name && BASELINK_P (name)) - adjust_result_of_qualified_name_lookup - (name, BINFO_TYPE (BASELINK_BINFO (name)), scope); - postfix_expression - = finish_class_member_access_expr (postfix_expression, name); } /* We no longer need to look up names in the scope of the @@ -6523,6 +6497,13 @@ cp_parser_simple_declaration (cp_parser* parser, /* Give up. */ goto done; } + + /* If we have seen at least one decl-specifier, and the next token + is not a parenthesis, then we must be looking at a declaration. + (After "int (" we might be looking at a functional cast.) */ + if (decl_specifiers + && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)) + cp_parser_commit_to_tentative_parse (parser); /* Keep going until we hit the `;' at the end of the simple declaration. */ @@ -6576,7 +6557,12 @@ cp_parser_simple_declaration (cp_parser* parser, /* Anything else is an error. */ else { - cp_parser_error (parser, "expected `,' or `;'"); + /* If we have already issued an error message we don't need + to issue another one. */ + if (decl != error_mark_node + || (cp_parser_parsing_tentatively (parser) + && !cp_parser_committed_to_tentative_parse (parser))) + cp_parser_error (parser, "expected `,' or `;'"); /* Skip tokens until we reach the end of the statement. */ cp_parser_skip_to_end_of_statement (parser); /* If the next token is now a `;', consume it. */ @@ -7802,9 +7788,15 @@ cp_parser_type_parameter (cp_parser* parser) if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ) && cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER) && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) - identifier = cp_parser_identifier (parser); + { + identifier = cp_parser_identifier (parser); + /* Treat invalid names as if the parameter were nameless. */ + if (identifier == error_mark_node) + identifier = NULL_TREE; + } else identifier = NULL_TREE; + /* Create the template parameter. */ parameter = finish_template_template_parm (class_type_node, identifier); @@ -7846,15 +7838,13 @@ cp_parser_type_parameter (cp_parser* parser) /* Create the combined representation of the parameter and the default argument. */ - parameter = build_tree_list (default_argument, parameter); + parameter = build_tree_list (default_argument, parameter); } break; default: - /* Anything else is an error. */ - cp_parser_error (parser, - "expected `class', `typename', or `template'"); - parameter = error_mark_node; + abort (); + break; } return parameter; @@ -8610,8 +8600,9 @@ cp_parser_explicit_instantiation (cp_parser* parser) /*ctor_dtor_or_conv_p=*/NULL, /*parenthesized_p=*/NULL, /*member_p=*/false); - cp_parser_check_for_definition_in_return_type (declarator, - declares_class_or_enum); + if (declares_class_or_enum & 2) + cp_parser_check_for_definition_in_return_type + (declarator, TREE_VALUE (decl_specifiers)); if (declarator != error_mark_node) { decl = grokdeclarator (declarator, decl_specifiers, @@ -9218,7 +9209,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, } /* For a `typename', we needn't call xref_tag. */ - if (tag_type == typename_type) + if (tag_type == typename_type + && TREE_CODE (parser->scope) != NAMESPACE_DECL) return make_typename_type (parser->scope, identifier, /*complain=*/1); /* Look up a qualified name in the usual way. */ @@ -9262,7 +9254,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, if (TREE_CODE (decl) != TYPE_DECL) { - error ("expected type-name"); + cp_parser_diagnose_invalid_type_name (parser); return error_mark_node; } @@ -9514,6 +9506,9 @@ cp_parser_namespace_name (cp_parser* parser) if (namespace_decl == error_mark_node || TREE_CODE (namespace_decl) != NAMESPACE_DECL) { + if (!cp_parser_parsing_tentatively (parser) + || cp_parser_committed_to_tentative_parse (parser)) + error ("`%D' is not a namespace-name", identifier); cp_parser_error (parser, "expected namespace-name"); namespace_decl = error_mark_node; } @@ -9982,8 +9977,9 @@ cp_parser_init_declarator (cp_parser* parser, if (declarator == error_mark_node) return error_mark_node; - cp_parser_check_for_definition_in_return_type (declarator, - declares_class_or_enum); + if (declares_class_or_enum & 2) + cp_parser_check_for_definition_in_return_type + (declarator, TREE_VALUE (decl_specifiers)); /* Figure out what scope the entity declared by the DECLARATOR is located in. `grokdeclarator' sometimes changes the scope, so @@ -10069,7 +10065,7 @@ cp_parser_init_declarator (cp_parser* parser, && token->type != CPP_COMMA && token->type != CPP_SEMICOLON) { - cp_parser_error (parser, "expected init-declarator"); + cp_parser_error (parser, "expected initializer"); return error_mark_node; } @@ -10909,7 +10905,7 @@ cp_parser_declarator_id (cp_parser* parser) /*declarator_p=*/true); /* If the name was qualified, create a SCOPE_REF to represent that. */ - if (parser->scope) + if (parser->scope && id_expression != error_mark_node) { id_expression = build_nt (SCOPE_REF, parser->scope, id_expression); parser->scope = NULL_TREE; @@ -12483,8 +12479,13 @@ cp_parser_member_declaration (cp_parser* parser) /* Check for a template-declaration. */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE)) { - /* Parse the template-declaration. */ - cp_parser_template_declaration (parser, /*member_p=*/true); + /* An explicit specialization here is an error condition, and we + expect the specialization handler to detect and report this. */ + if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_LESS + && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_GREATER) + cp_parser_explicit_specialization (parser); + else + cp_parser_template_declaration (parser, /*member_p=*/true); return; } @@ -12685,8 +12686,9 @@ cp_parser_member_declaration (cp_parser* parser) return; } - cp_parser_check_for_definition_in_return_type - (declarator, declares_class_or_enum); + if (declares_class_or_enum & 2) + cp_parser_check_for_definition_in_return_type + (declarator, TREE_VALUE (decl_specifiers)); /* Look for an asm-specification. */ asm_specification = cp_parser_asm_specification_opt (parser); @@ -13639,7 +13641,10 @@ cp_parser_label_declaration (cp_parser* parser) /* Look for an identifier. */ identifier = cp_parser_identifier (parser); - /* Declare it as a lobel. */ + /* If we failed, stop. */ + if (identifier == error_mark_node) + break; + /* Declare it as a label. */ finish_label_decl (identifier); /* If the next token is a `;', stop. */ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) @@ -13689,6 +13694,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, bool is_type, bool is_template, bool is_namespace, bool check_dependency) { + int flags = 0; tree decl; tree object_type = parser->context->object_type; @@ -13700,6 +13706,10 @@ cp_parser_lookup_name (cp_parser *parser, tree name, if (name == error_mark_node) return error_mark_node; + if (!cp_parser_parsing_tentatively (parser) + || cp_parser_committed_to_tentative_parse (parser)) + flags |= LOOKUP_COMPLAIN; + /* A template-id has already been resolved; there is no lookup to do. */ if (TREE_CODE (name) == TEMPLATE_ID_EXPR) @@ -13813,8 +13823,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, /*protect=*/0, is_type); /* Look it up in the enclosing context, too. */ decl = lookup_name_real (name, is_type, /*nonclass=*/0, - is_namespace, - /*flags=*/0); + is_namespace, flags); parser->object_scope = object_type; parser->qualifying_scope = NULL_TREE; if (object_decl) @@ -13823,8 +13832,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, else { decl = lookup_name_real (name, is_type, /*nonclass=*/0, - is_namespace, - /*flags=*/0); + is_namespace, flags); parser->qualifying_scope = NULL_TREE; parser->object_scope = NULL_TREE; } @@ -14508,6 +14516,12 @@ cp_parser_single_declaration (cp_parser* parser, tree attributes; bool function_definition_p = false; + /* This function is only used when processing a template + declaration. */ + if (innermost_scope_kind () != sk_template_parms + && innermost_scope_kind () != sk_template_spec) + abort (); + /* Defer access checks until we know what is being declared. */ push_deferring_access_checks (dk_deferred); @@ -14520,6 +14534,14 @@ cp_parser_single_declaration (cp_parser* parser, &declares_class_or_enum); if (friend_p) *friend_p = cp_parser_friend_p (decl_specifiers); + + /* There are no template typedefs. */ + if (cp_parser_typedef_p (decl_specifiers)) + { + error ("template declaration of `typedef'"); + decl = error_mark_node; + } + /* Gather up the access checks that occurred the decl-specifier-seq. */ stop_deferring_access_checks (); @@ -14536,8 +14558,6 @@ cp_parser_single_declaration (cp_parser* parser, decl = error_mark_node; } } - else - decl = NULL_TREE; /* If it's not a template class, try for a template function. If the next token is a `;', then this declaration does not declare anything. But, if there were errors in the decl-specifiers, then @@ -14563,7 +14583,8 @@ cp_parser_single_declaration (cp_parser* parser, parser->object_scope = NULL_TREE; /* Look for a trailing `;' after the declaration. */ if (!function_definition_p - && !cp_parser_require (parser, CPP_SEMICOLON, "`;'")) + && (decl == error_mark_node + || !cp_parser_require (parser, CPP_SEMICOLON, "`;'"))) cp_parser_skip_to_end_of_block_or_statement (parser); return decl; @@ -14593,8 +14614,10 @@ cp_parser_functional_cast (cp_parser* parser, tree type) cast = build_functional_cast (type, expression_list); /* [expr.const]/1: In an integral constant expression "only type conversions to integral or enumeration type can be used". */ - if (cast != error_mark_node && !type_dependent_expression_p (type) - && !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (type))) + if (TREE_CODE (type) == TYPE_DECL) + type = TREE_TYPE (type); + if (cast != error_mark_node && !dependent_type_p (type) + && !INTEGRAL_OR_ENUMERATION_TYPE_P (type)) { if (cp_parser_non_integral_constant_expression (parser, "a call to a constructor")) @@ -14716,8 +14739,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser) cp_lexer_consume_token (parser->lexer); } } - else if (!cp_parser_require (parser, CPP_GREATER, "`>'")) - error ("missing `>' to terminate the template argument list"); + else + cp_parser_skip_until_found (parser, CPP_GREATER, "`>'"); /* The `>' token might be a greater-than operator again now. */ parser->greater_than_is_operator_p = saved_greater_than_is_operator_p; @@ -14768,9 +14791,10 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function) tokens = DECL_PENDING_INLINE_INFO (member_function); DECL_PENDING_INLINE_INFO (member_function) = NULL; DECL_PENDING_INLINE_P (member_function) = 0; - /* If this was an inline function in a local class, enter the scope - of the containing function. */ - function_scope = decl_function_context (member_function); + + /* If this is a local class, enter the scope of the containing + function. */ + function_scope = current_function_decl; if (function_scope) push_function_context_to (function_scope); @@ -14851,33 +14875,49 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) parameters; parameters = TREE_CHAIN (parameters)) { - if (!TREE_PURPOSE (parameters) - || TREE_CODE (TREE_PURPOSE (parameters)) != DEFAULT_ARG) + tree default_arg = TREE_PURPOSE (parameters); + tree parsed_arg; + + if (!default_arg) + continue; + + if (TREE_CODE (default_arg) != DEFAULT_ARG) + /* This can happen for a friend declaration for a function + already declared with default arguments. */ continue; - /* Save away the current lexer. */ + /* Save away the current lexer. */ saved_lexer = parser->lexer; - /* Create a new one, using the tokens we have saved. */ - tokens = DEFARG_TOKENS (TREE_PURPOSE (parameters)); + /* Create a new one, using the tokens we have saved. */ + tokens = DEFARG_TOKENS (default_arg); parser->lexer = cp_lexer_new_from_tokens (tokens); - /* Set the current source position to be the location of the - first token in the default argument. */ + /* Set the current source position to be the location of the + first token in the default argument. */ cp_lexer_peek_token (parser->lexer); - /* Local variable names (and the `this' keyword) may not appear - in a default argument. */ + /* Local variable names (and the `this' keyword) may not appear + in a default argument. */ saved_local_variables_forbidden_p = parser->local_variables_forbidden_p; parser->local_variables_forbidden_p = true; - /* Parse the assignment-expression. */ + + /* Parse the assignment-expression. */ 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); + parsed_arg = cp_parser_assignment_expression (parser); if (DECL_FRIEND_CONTEXT (fn) || DECL_CLASS_SCOPE_P (fn)) pop_nested_class (); - + + TREE_PURPOSE (parameters) = parsed_arg; + + /* Update any instantiations we've already created. */ + for (default_arg = TREE_CHAIN (default_arg); + default_arg; + default_arg = TREE_CHAIN (default_arg)) + TREE_PURPOSE (TREE_PURPOSE (default_arg)) = parsed_arg; + /* If the token stream has not been completely used up, then there was extra junk after the end of the default argument. */ @@ -14889,6 +14929,9 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) parser->local_variables_forbidden_p = saved_local_variables_forbidden_p; } + /* Make sure no default arg is missing. */ + check_default_args (fn); + /* Restore the queue. */ parser->unparsed_functions_queues = TREE_CHAIN (parser->unparsed_functions_queues); @@ -15012,6 +15055,27 @@ cp_parser_friend_p (tree decl_specifiers) return false; } +/* DECL_SPECIFIERS is the representation of a decl-specifier-seq. + Returns TRUE iff `typedef' appears among the DECL_SPECIFIERS. */ + +static bool +cp_parser_typedef_p (tree decl_specifiers) +{ + while (decl_specifiers) + { + /* See if this decl-specifier is `typedef'. */ + if (TREE_CODE (TREE_VALUE (decl_specifiers)) == IDENTIFIER_NODE + && C_RID_CODE (TREE_VALUE (decl_specifiers)) == RID_TYPEDEF) + return true; + + /* Go on to the next decl-specifier. */ + decl_specifiers = TREE_CHAIN (decl_specifiers); + } + + return false; +} + + /* If the next token is of the indicated TYPE, consume it. Otherwise, issue an error message indicating that TOKEN_DESC was expected. diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c index e5aadc1..0ae2d23 100644 --- a/contrib/gcc/cp/pt.c +++ b/contrib/gcc/cp/pt.c @@ -744,8 +744,12 @@ check_specialization_namespace (tree tmpl) void maybe_process_partial_specialization (tree type) { - /* TYPE maybe an ERROR_MARK_NODE. */ - tree context = TYPE_P (type) ? TYPE_CONTEXT (type) : NULL_TREE; + tree context; + + if (type == error_mark_node) + return; + + context = TYPE_CONTEXT (type); if (CLASS_TYPE_P (type) && CLASSTYPE_USE_TEMPLATE (type)) { @@ -1779,6 +1783,11 @@ check_explicit_specialization (tree declarator, /* Find the namespace binding, using the declaration context. */ fns = namespace_binding (dname, CP_DECL_CONTEXT (decl)); + if (!fns || !is_overloaded_fn (fns)) + { + error ("`%D' is not a template function", dname); + fns = error_mark_node; + } } declarator = lookup_template_function (fns, NULL_TREE); @@ -2832,9 +2841,8 @@ push_template_decl_real (tree decl, int is_friend) 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))) + else if (DECL_IMPLICIT_TYPEDEF_P (decl) + && CLASS_TYPE_P (TREE_TYPE (decl))) /* OK */; else { @@ -2973,6 +2981,7 @@ push_template_decl_real (tree decl, int is_friend) error ("got %d template parameters for `%#T'", TREE_VEC_LENGTH (a), current); error (" but %d required", TREE_VEC_LENGTH (t)); + return error_mark_node; } /* Perhaps we should also check that the parms are used in the @@ -3074,10 +3083,9 @@ redeclare_class_template (tree type, tree parms) if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms)) { cp_error_at ("previous declaration `%D'", tmpl); - error ("used %d template parameter%s instead of %d", - TREE_VEC_LENGTH (tmpl_parms), - TREE_VEC_LENGTH (tmpl_parms) == 1 ? "" : "s", - TREE_VEC_LENGTH (parms)); + error ("used %d template parameter(s) instead of %d", + TREE_VEC_LENGTH (tmpl_parms), + TREE_VEC_LENGTH (parms)); return; } @@ -4067,18 +4075,9 @@ lookup_template_function (tree fns, tree arglist) return error_mark_node; my_friendly_assert (!arglist || TREE_CODE (arglist) == TREE_VEC, 20030726); - if (fns == NULL_TREE - || TREE_CODE (fns) == FUNCTION_DECL) - { - error ("non-template used as template"); - return error_mark_node; - } - - my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL - || TREE_CODE (fns) == OVERLOAD - || BASELINK_P (fns) - || TREE_CODE (fns) == IDENTIFIER_NODE, - 20020730); + my_friendly_assert (fns && (is_overloaded_fn (fns) + || TREE_CODE (fns) == IDENTIFIER_NODE), + 20050608); if (BASELINK_P (fns)) { @@ -4809,11 +4808,14 @@ uses_template_parms (tree t) else if (TREE_CODE (t) == TREE_LIST) dependent_p = (uses_template_parms (TREE_VALUE (t)) || uses_template_parms (TREE_CHAIN (t))); + else if (TREE_CODE (t) == TYPE_DECL) + dependent_p = dependent_type_p (TREE_TYPE (t)); else if (DECL_P (t) || EXPR_P (t) || TREE_CODE (t) == TEMPLATE_PARM_INDEX || TREE_CODE (t) == OVERLOAD || TREE_CODE (t) == BASELINK + || TREE_CODE (t) == IDENTIFIER_NODE || TREE_CODE_CLASS (TREE_CODE (t)) == 'c') dependent_p = (type_dependent_expression_p (t) || value_dependent_expression_p (t)); @@ -5787,6 +5789,12 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain) tree r = NULL_TREE; tree* new_parms; + /* When substituting into a template, we must set + PROCESSING_TEMPLATE_DECL as the template parameters may be + dependent if they are based on one-another, and the dependency + predicates are short-circuit outside of templates. */ + ++processing_template_decl; + for (new_parms = &r; TMPL_PARMS_DEPTH (parms) > TMPL_ARGS_DEPTH (args); new_parms = &(TREE_CHAIN (*new_parms)), @@ -5816,6 +5824,8 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain) new_vec, NULL_TREE); } + --processing_template_decl; + return r; } @@ -6001,8 +6011,14 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t)); tree full_args; + /* Because this is a template, the arguments will still be + dependent, even after substitution. If + PROCESSING_TEMPLATE_DECL is not set, the dependency + predicates will short-circuit. */ + ++processing_template_decl; full_args = tsubst_template_args (tmpl_args, args, complain, in_decl); + --processing_template_decl; /* tsubst_template_args doesn't copy the vector if nothing changed. But, *something* should have @@ -6034,15 +6050,14 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) break; } - DECL_CONTEXT (r) - = tsubst_aggr_type (DECL_CONTEXT (t), args, - complain, in_decl, - /*entering_scope=*/1); DECL_TEMPLATE_INFO (r) = build_tree_list (t, args); if (TREE_CODE (decl) == TYPE_DECL) { - tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); + tree new_type; + ++processing_template_decl; + new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); + --processing_template_decl; if (new_type == error_mark_node) return error_mark_node; @@ -6050,10 +6065,14 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) CLASSTYPE_TI_TEMPLATE (new_type) = r; DECL_TEMPLATE_RESULT (r) = TYPE_MAIN_DECL (new_type); DECL_TI_ARGS (r) = CLASSTYPE_TI_ARGS (new_type); + DECL_CONTEXT (r) = TYPE_CONTEXT (new_type); } else { - tree new_decl = tsubst (decl, args, complain, in_decl); + tree new_decl; + ++processing_template_decl; + new_decl = tsubst (decl, args, complain, in_decl); + --processing_template_decl; if (new_decl == error_mark_node) return error_mark_node; @@ -6061,6 +6080,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) DECL_TI_TEMPLATE (new_decl) = r; TREE_TYPE (r) = TREE_TYPE (new_decl); DECL_TI_ARGS (r) = DECL_TI_ARGS (new_decl); + DECL_CONTEXT (r) = DECL_CONTEXT (new_decl); } SET_DECL_IMPLICIT_INSTANTIATION (r); @@ -6292,8 +6312,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) clone_function_decl (r, /*update_method_vec_p=*/0); } else if (IDENTIFIER_OPNAME_P (DECL_NAME (r))) - grok_op_properties (r, DECL_FRIEND_P (r), - (complain & tf_error) != 0); + grok_op_properties (r, (complain & tf_error) != 0); if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t)) SET_DECL_FRIEND_CONTEXT (r, @@ -6486,6 +6505,8 @@ tsubst_arg_types (tree arg_types, { tree remaining_arg_types; tree type; + tree default_arg; + tree result = NULL_TREE; if (!arg_types || arg_types == void_list_node) return arg_types; @@ -6513,12 +6534,25 @@ tsubst_arg_types (tree arg_types, top-level qualifiers as required. */ type = TYPE_MAIN_VARIANT (type_decays_to (type)); - /* Note that we do not substitute into default arguments here. The - standard mandates that they be instantiated only when needed, - which is done in build_over_call. */ - return hash_tree_cons (TREE_PURPOSE (arg_types), type, - remaining_arg_types); - + /* We do not substitute into default arguments here. The standard + mandates that they be instantiated only when needed, which is + done in build_over_call. */ + default_arg = TREE_PURPOSE (arg_types); + + if (default_arg && TREE_CODE (default_arg) == DEFAULT_ARG) + { + /* We've instantiated a template before its default arguments + have been parsed. This can happen for a nested template + class, and is not an error unless we require the default + argument in a call of this function. */ + result = tree_cons (default_arg, type, remaining_arg_types); + TREE_CHAIN (default_arg) = tree_cons (result, NULL_TREE, + TREE_CHAIN (default_arg)); + } + else + result = hash_tree_cons (default_arg, type, remaining_arg_types); + + return result; } /* Substitute into a FUNCTION_TYPE or METHOD_TYPE. This routine does @@ -6711,8 +6745,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* The array dimension behaves like a non-type template arg, in that we want to fold it as much as possible. */ max = tsubst_template_arg (omax, args, complain, in_decl); - if (!processing_template_decl) - max = decl_constant_value (max); + max = fold_non_dependent_expr (max); if (integer_zerop (omax)) { @@ -7774,6 +7807,10 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) in_decl), tsubst (TREE_TYPE (t), args, complain, in_decl)); + case OFFSET_REF: + mark_used (TREE_OPERAND (t, 1)); + return t; + default: return t; } @@ -9158,17 +9195,12 @@ type_unification_real (tree tparms, else type = arg; - if (strict == DEDUCE_EXACT || strict == DEDUCE_ORDER) - { - if (same_type_p (parm, type)) - continue; - } - else - /* It might work; we shouldn't check now, because we might - get into infinite recursion. Overload resolution will - handle it. */ + if (same_type_p (parm, type)) continue; - + if (strict != DEDUCE_EXACT + && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg)) + continue; + return 1; } @@ -12024,7 +12056,8 @@ type_dependent_expression_p (tree expression) return true; expression = TREE_OPERAND (expression, 0); } - if (TREE_CODE (expression) == OVERLOAD) + if (TREE_CODE (expression) == OVERLOAD + || TREE_CODE (expression) == FUNCTION_DECL) { while (expression) { @@ -12037,6 +12070,8 @@ type_dependent_expression_p (tree expression) abort (); } + my_friendly_assert (TREE_CODE (expression) != TYPE_DECL, 20051116); + return (dependent_type_p (TREE_TYPE (expression))); } diff --git a/contrib/gcc/cp/search.c b/contrib/gcc/cp/search.c index 0dfdb92..c227175 100644 --- a/contrib/gcc/cp/search.c +++ b/contrib/gcc/cp/search.c @@ -946,8 +946,12 @@ accessible_p (tree type, tree decl) /* In a template declaration, we cannot be sure whether the particular specialization that is instantiated will be a friend or not. Therefore, all access checks are deferred until - instantiation. */ - if (processing_template_decl) + instantiation. However, PROCESSING_TEMPLATE_DECL is set in the + parameter list for a template (because we may see dependent types + in default arguments for template parameters), and access + checking should be performed in the outermost parameter list. */ + if (processing_template_decl + && (!processing_template_parmlist || processing_template_decl > 1)) return 1; if (!TYPE_P (type)) diff --git a/contrib/gcc/cp/semantics.c b/contrib/gcc/cp/semantics.c index bb2f3c9..943e7a1 100644 --- a/contrib/gcc/cp/semantics.c +++ b/contrib/gcc/cp/semantics.c @@ -2295,7 +2295,9 @@ check_multiple_declarators (void) void qualified_name_lookup_error (tree scope, tree name) { - if (TYPE_P (scope)) + if (scope == error_mark_node) + ; /* We already complained. */ + else if (TYPE_P (scope)) { if (!COMPLETE_TYPE_P (scope)) error ("incomplete type `%T' used in nested name specifier", scope); @@ -2398,6 +2400,21 @@ finish_id_expression (tree id_expression, was entirely defined. */ if (!scope && decl != error_mark_node) maybe_note_name_used_in_class (id_expression, decl); + + /* Disallow uses of local variables from containing functions. */ + if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) + { + tree context = decl_function_context (decl); + if (context != NULL_TREE && context != current_function_decl + && ! TREE_STATIC (decl)) + { + error (TREE_CODE (decl) == VAR_DECL + ? "use of `auto' variable from containing function" + : "use of parameter from containing function"); + cp_error_at (" `%#D' declared here", decl); + return error_mark_node; + } + } } /* If we didn't find anything, or what we found was a type, @@ -2664,23 +2681,6 @@ finish_id_expression (tree id_expression, } else { - if (TREE_CODE (decl) == VAR_DECL - || TREE_CODE (decl) == PARM_DECL - || TREE_CODE (decl) == RESULT_DECL) - { - tree context = decl_function_context (decl); - - if (context != NULL_TREE && context != current_function_decl - && ! TREE_STATIC (decl)) - { - error ("use of %s from containing function", - (TREE_CODE (decl) == VAR_DECL - ? "`auto' variable" : "parameter")); - cp_error_at (" `%#D' declared here", decl); - return error_mark_node; - } - } - if (DECL_P (decl) && DECL_NONLOCAL (decl) && DECL_CLASS_SCOPE_P (decl) && DECL_CONTEXT (decl) != current_class_type) diff --git a/contrib/gcc/cp/typeck.c b/contrib/gcc/cp/typeck.c index 0c9c6c4..b13fb85 100644 --- a/contrib/gcc/cp/typeck.c +++ b/contrib/gcc/cp/typeck.c @@ -95,6 +95,9 @@ require_complete_type (tree value) else type = TREE_TYPE (value); + if (type == error_mark_node) + return error_mark_node; + /* First, detect a valid value with a complete type. */ if (COMPLETE_TYPE_P (type)) return value; @@ -265,10 +268,12 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2) /* FIXME: Attributes. */ my_friendly_assert (ARITHMETIC_TYPE_P (t1) || TREE_CODE (t1) == COMPLEX_TYPE + || TREE_CODE (t1) == VECTOR_TYPE || TREE_CODE (t1) == ENUMERAL_TYPE, 19990725); my_friendly_assert (ARITHMETIC_TYPE_P (t2) || TREE_CODE (t2) == COMPLEX_TYPE + || TREE_CODE (t2) == VECTOR_TYPE || TREE_CODE (t2) == ENUMERAL_TYPE, 19990725); @@ -296,6 +301,16 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2) attributes); } + if (code1 == VECTOR_TYPE) + { + /* When we get here we should have two vectors of the same size. + Just prefer the unsigned one if present. */ + if (TREE_UNSIGNED (t1)) + return build_type_attribute_variant (t1, attributes); + else + return build_type_attribute_variant (t2, attributes); + } + /* If only one is real, use it as the result. */ if (code1 == REAL_TYPE && code2 != REAL_TYPE) return build_type_attribute_variant (t1, attributes); @@ -745,9 +760,9 @@ common_type (tree t1, tree t2) code2 = TREE_CODE (t2); if ((ARITHMETIC_TYPE_P (t1) || code1 == ENUMERAL_TYPE - || code1 == COMPLEX_TYPE) + || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE) && (ARITHMETIC_TYPE_P (t2) || code2 == ENUMERAL_TYPE - || code2 == COMPLEX_TYPE)) + || code2 == COMPLEX_TYPE || code2 == VECTOR_TYPE)) return type_after_usual_arithmetic_conversions (t1, t2); else if ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2)) @@ -2878,9 +2893,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, case ROUND_DIV_EXPR: case EXACT_DIV_EXPR: if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE - || code0 == COMPLEX_TYPE) + || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE) && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE)) + || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)) { if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1)) warning ("division by zero in `%E / 0'", op0); @@ -2907,7 +2922,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, case BIT_AND_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) + if ((code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) + || (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)) shorten = -1; break; @@ -3158,12 +3174,17 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, break; } - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) - && - (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) + if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) + && + (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) + || (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)) { int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE); + if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE + && !tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))) + error ("can't convert between vector values of different size"); + if (shorten || common || short_compare) result_type = common_type (type0, type1); @@ -4776,7 +4797,7 @@ build_const_cast (tree type, tree expr) { tree intype; - if (type == error_mark_node || expr == error_mark_node) + if (type == error_mark_node || error_operand_p (expr)) return error_mark_node; if (processing_template_decl) @@ -6066,6 +6087,15 @@ check_return_expr (tree retval) /* Remember that this function did return a value. */ current_function_returns_value = 1; + /* Check for erroneous operands -- but after giving ourselves a + chance to provide an error about returning a value from a void + function. */ + if (error_operand_p (retval)) + { + current_function_return_value = error_mark_node; + return error_mark_node; + } + /* Only operator new(...) throw(), can return NULL [expr.new/13]. */ if ((DECL_OVERLOADED_OPERATOR_P (current_function_decl) == NEW_EXPR || DECL_OVERLOADED_OPERATOR_P (current_function_decl) == VEC_NEW_EXPR) @@ -6122,8 +6152,8 @@ check_return_expr (tree retval) /* We don't need to do any conversions when there's nothing being returned. */ - if (!retval || retval == error_mark_node) - return retval; + if (!retval) + return NULL_TREE; /* Do any required conversions. */ if (retval == result || DECL_CONSTRUCTOR_P (current_function_decl)) @@ -6314,11 +6344,6 @@ casts_away_constness_r (tree *t1, tree *t2) and pointers to members (conv.qual), the "member" aspect of a pointer to member level is ignored when determining if a const cv-qualifier has been cast away. */ - if (TYPE_PTRMEM_P (*t1)) - *t1 = build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (*t1)); - if (TYPE_PTRMEM_P (*t2)) - *t2 = build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (*t2)); - /* [expr.const.cast] For two pointer types: @@ -6336,9 +6361,8 @@ casts_away_constness_r (tree *t1, tree *t2) to Tcv2,(M-K+1) * cv2,(M-K+2) * ... cv2,M *. */ - - if (TREE_CODE (*t1) != POINTER_TYPE - || TREE_CODE (*t2) != POINTER_TYPE) + if ((!TYPE_PTR_P (*t1) && !TYPE_PTRMEM_P (*t1)) + || (!TYPE_PTR_P (*t2) && !TYPE_PTRMEM_P (*t2))) { *t1 = cp_build_qualified_type (void_type_node, cp_type_quals (*t1)); @@ -6349,8 +6373,16 @@ casts_away_constness_r (tree *t1, tree *t2) quals1 = cp_type_quals (*t1); quals2 = cp_type_quals (*t2); - *t1 = TREE_TYPE (*t1); - *t2 = TREE_TYPE (*t2); + + if (TYPE_PTRMEM_P (*t1)) + *t1 = TYPE_PTRMEM_POINTED_TO_TYPE (*t1); + else + *t1 = TREE_TYPE (*t1); + if (TYPE_PTRMEM_P (*t2)) + *t2 = TYPE_PTRMEM_POINTED_TO_TYPE (*t2); + else + *t2 = TREE_TYPE (*t2); + casts_away_constness_r (t1, t2); *t1 = build_pointer_type (*t1); *t2 = build_pointer_type (*t2); |