diff options
author | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-23 19:37:40 +0000 |
---|---|---|
committer | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-23 19:37:40 +0000 |
commit | 10ada81fea4490f94ba2eb5923bf5baa367a38bd (patch) | |
tree | 437dca120093cc7b1f6debf6f6b31779526c7192 /gcc/cp | |
parent | 95a236de8aa10bf009e9368dfd28f95a980e5570 (diff) | |
parent | 3bd7a983695352a99f7dd597725eb5b839d4b4cf (diff) | |
download | gcc-10ada81fea4490f94ba2eb5923bf5baa367a38bd.tar.gz |
Merged with trunk at revision 162480.ifunc
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/ifunc@162483 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 259 | ||||
-rw-r--r-- | gcc/cp/call.c | 48 | ||||
-rw-r--r-- | gcc/cp/class.c | 207 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 14 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 49 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 319 | ||||
-rw-r--r-- | gcc/cp/decl.c | 62 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 20 | ||||
-rw-r--r-- | gcc/cp/error.c | 2 | ||||
-rw-r--r-- | gcc/cp/init.c | 136 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 27 | ||||
-rw-r--r-- | gcc/cp/method.c | 269 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 50 | ||||
-rw-r--r-- | gcc/cp/optimize.c | 29 | ||||
-rw-r--r-- | gcc/cp/parser.c | 20 | ||||
-rw-r--r-- | gcc/cp/pt.c | 203 | ||||
-rw-r--r-- | gcc/cp/ptree.c | 9 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 6 | ||||
-rw-r--r-- | gcc/cp/search.c | 4 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 29 | ||||
-rw-r--r-- | gcc/cp/tree.c | 29 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 133 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 11 |
23 files changed, 1355 insertions, 580 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f72e7a6b97f..b7b08bbb526 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,6 +1,261 @@ +2010-07-21 Jason Merrill <jason@redhat.com> + + * tree.c (cp_tree_equal): Fix CONSTRUCTOR handling. + + * parser.c (cp_parser_init_declarator): Pass LOOKUP_NORMAL + to cp_finish_decl. + +2010-07-20 Jeffrey Yasskin <jyasskin@google.com> + + PR c++/44641 + * pt.c (instantiate_class_template): Propagate the template's + location to its instance. + +2010-07-20 Jason Merrill <jason@redhat.com> + + PR c++/44967 + * pt.c (tsubst_copy_and_build): Rework last change. + + PR c++/44967 + * pt.c (tsubst_copy_and_build): Handle partial substitution of + CALL_EXPR. + +2010-07-19 Jason Merrill <jason@redhat.com> + + PR c++/44996 + * semantics.c (finish_decltype_type): Correct decltype + of parenthesized rvalue reference variable. + + PR c++/44969 + * tree.c (cp_tree_equal): Compare type of *CAST_EXPR. + * pt.c (iterative_hash_template_arg): Hash type of *CAST_EXPR. + +2010-07-19 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/44969 + * typeck.c (build_x_compound_expr_from_list): Add tsubst_flags_t + parameter. + * cp-tree.h: Adjust declaration. + * init.c (perform_member_init): Adjust caller. + * decl.c (grok_reference_init, cp_finish_decl): Likewise. + * typeck2.c (store_init_value): Likewise. + (build_functional_cast): Pass complain argument to + build_x_compound_expr_from_list. + +2010-07-16 Jason Merrill <jason@redhat.com> + + PR c++/32505 + * pt.c (process_partial_specialization): Diagnose partial + specialization after instantiation. + (most_specialized_class): Add complain parm. + + * ptree.c (cxx_print_xnode): Handle TEMPLATE_INFO. + +2010-07-15 Nathan Froyd <froydnj@codesourcery.com> + + * init.c (build_new_1): Use cp_build_function_call_nary instead of + cp_build_function_call. + +2010-07-15 Jason Merrill <jason@redhat.com> + + PR c++/44909 + * call.c (add_function_candidate): If we're working on an implicit + declaration, don't consider candidates that won't match. + * typeck.c (same_type_ignoring_top_level_qualifiers_p): Now a fn. + * cp-tree.h (same_type_ignoring_top_level_qualifiers_p): Adjust. + + Revert: + * cp-tree.h (struct lang_type_class): Add has_user_opeq. + (TYPE_HAS_USER_OPEQ): New. + * decl.c (grok_special_member_properties): Set it. + * class.c (add_implicitly_declared_members): Don't lazily declare + constructors/operator= if a base or member has a user-declared one. + (check_bases_and_members, check_bases): Adjust. + (check_field_decls, check_field_decl): Adjust. + +2010-07-15 Anatoly Sokolov <aesok@post.ru> + + * decl.c (integer_three_node): Remove. + (cxx_init_decl_processing): Do not initialize the integer_three_node. + * cp-tree.h (integer_three_node): Remove. + +2010-07-15 Nathan Froyd <froydnj@codesourcery.com> + + * cp-tree.h: Carefully replace TREE_CHAIN with DECL_CHAIN. + * call.c: Likewise. + * class.c: Likewise. + * cp-gimplify.c: Likewise. + * decl.c: Likewise. + * decl2.c: Likewise. + * init.c: Likewise. + * mangle.c: Likewise. + * name-lookup.c: Likewise. + * optimize.c: Likewise. + * parser.c: Likewise. + * pt.c: Likewise. + * rtti.c: Likewise. + * search.c: Likewise. + * semantics.c: Likewise. + * typeck.c: Likewise. + * typeck2.c: Likewise. + +2010-07-14 Jason Merrill <jason@redhat.com> + + * init.c (sort_mem_initializers): Rename "field_type" to "ctx". + (build_field_list): Cache field type. + + Implement C++0x unrestricted unions (N2544) + * class.c (check_field_decl): Loosen union handling in C++0x. + * method.c (walk_field_subobs): Split out from... + (synthesized_method_walk): ...here. Set msg before loops. + (process_subob_fn): Check for triviality in union members. + * init.c (sort_mem_initializers): Splice out uninitialized + anonymous unions and union members. + (push_base_cleanups): Don't automatically destroy anonymous unions + and union members. + +2010-07-13 Jason Merrill <jason@redhat.com> + + PR c++/44909 + * cp-tree.h (struct lang_type_class): Add has_user_opeq. + (TYPE_HAS_USER_OPEQ): New. + * decl.c (grok_special_member_properties): Set it. + * class.c (add_implicitly_declared_members): Don't lazily declare + constructors/operator= if a base or member has a user-declared one. + (check_bases_and_members, check_bases): Adjust. + (check_field_decls, check_field_decl): Adjust. + * method.c (synthesized_method_walk): Initialize check_vdtor. + + PR c++/44540 + * mangle.c (write_type): Canonicalize. + (canonicalize_for_substitution): Retain cv-quals on FUNCTION_TYPE. + (write_CV_qualifiers_for_type): Ignore them in abi>=5. + +2010-07-13 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/44908 + * call.c (convert_like_real): Adjust convert_ptrmem call, pass + complain argument. + * typeck.c (get_delta_difference): Update prototype, add a + tsubst_flags_t parameter; update get_delta_difference_1 calls and + add checks for error_mark_node. + (get_delta_difference_1): Update prototype, add a tsubst_flags_t + parameter; update lookup_base call. + (build_ptrmemfunc): Update prototype, add a tsubst_flags_t + parameter; update get_delta_difference call and add check for + error_mark_node. + (convert_ptrmem): Update prototype, add a tsubst_flags_t + parameter; update get_delta_difference call and add check for + error_mark_node; update build_ptrmemfunc call. + (build_static_cast_1): Adjust convert_ptrmem call. + (expand_ptrmemfunc_cst): Adjust get_delta_difference call. + (cp_build_unary_op): Adjust build_ptrmemfunc call. + * cvt.c (cp_convert_to_pointer, convert_force): Adjust convert_ptrmem + and build_ptrmemfunc calls. + * cp-tree.h: Update build_ptrmemfunc and convert_ptrmem prototypes. + +2010-07-12 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/44907 + * call.c (build_temp): Add tsubst_flags_t complain parameter; + adjust build_special_member_call call, pass complain. + (convert_like_real): Adjust build_temp call, pass complain. + +2010-07-09 Jason Merrill <jason@redhat.com> + + PR c++/43120 + * cp-tree.h (BV_LOST_PRIMARY): New macro. + * class.c (update_vtable_entry_for_fn): Fix covariant thunk logic. + Set BV_LOST_PRIMARY. + (build_vtbl_initializer): Check BV_LOST_PRIMARY. + +2010-07-08 Jason Merrill <jason@redhat.com> + + PR c++/43120 + * class.c (update_vtable_entry_for_fn): Fix handling of dummy + virtual bases for covariant thunks. + +2010-07-08 Manuel López-Ibáñez <manu@gcc.gnu.org> + + * cp-tree.h: Do not include toplev.h. + +2010-07-06 Jason Merrill <jason@redhat.com> + + PR c++/44703 + * call.c (is_std_init_list): Look through typedefs. + + PR c++/44778 + * init.c (build_offset_ref): If scope isn't dependent, + don't exit early. Look at TYPE_MAIN_VARIANT. + * pt.c (tsubst_copy) [OFFSET_REF]: Do substitution. + + * error.c (dump_function_decl): Don't crash on null DECL_NAME. + +2010-07-06 Shujing Zhao <pearly.zhao@oracle.com> + + * cp-tree.h (impl_conv_void): New type. + (convert_to_void): Adjust prototype. + * cvt.c (convert_to_void): Use impl_conv_void, emit and adjust the + diagnostic for easy translation. Change caller. + * typeck.c: Update call to convert_to_void. + * semantics.c: Likewise. + * init.c: Likewise. + +2010-07-05 Nathan Froyd <froydnj@codesourcery.com> + + * decl.c (cp_finish_decl): Call add_local_decl. + * optimize.c (clone_body): Adjust for new type of cfun->local_decls. + +2010-07-05 Paolo Carlini <paolo.carlini@oracle.com> + + * pt.c (tsubst): Early declare code = TREE_CODE (t) and use it + throughout. + +2010-07-05 Shujing Zhao <pearly.zhao@oracle.com> + + PR c++/22138 + * parser.c (cp_parser_primary_expression): Error if local template is + declared. + +2010-07-02 Le-Chun Wu <lcwu@google.com> + + PR/44128 + * name-lookup.c (pushdecl_maybe_friend): Warn when a local decl + (variable or type) shadows another type. + +2010-07-02 Jakub Jelinek <jakub@redhat.com> + + PR c++/44780 + * typeck.c (convert_for_assignment): When converting a convertible + vector type or objc++ types, call mark_rvalue_use. + * typeck2.c (build_m_component_ref): Use return values from + mark_rvalue_use or mark_lvalue_use. + * class.c (build_base_path): Likewise. + * call.c (build_conditional_expr): Likewise. + +2010-07-02 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/44039 + * pt.c (tsubst_baselink): Return error_mark_node if lookup_fnfields + returns NULL_TREE. + +2010-07-01 Richard Guenther <rguenther@suse.de> + + * cp-gimplify.c (cp_gimplify_expr): Open-code the rhs + predicate we are looking for, allow non-gimplified + INDIRECT_REFs. + +2010-06-30 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/44628 + * typeck.c (cp_build_unary_op): Early return error_mark_node when + arg is NULL_TREE too. + * call.c (convert_class_to_reference): Return error_mark_node when + expr is NULL_TREE. + 2010-06-30 Michael Matz <matz@suse.de> - * repo.c ((finish_repo): Fix typo. + * repo.c (finish_repo): Fix typo. 2010-06-30 Nathan Froyd <froydnj@codesourcery.com> @@ -17,7 +272,7 @@ * tree.c: Include gimple.h. Do not include tree-flow.h * decl.c: Do not include tree-flow.h * Make-lang.in: Adjust dependencies. - + 2010-06-29 Nathan Froyd <froydnj@codesourcery.com> * decl.c (incomplete_var): Declare. Declare VECs containing them. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index cca35c5e1fb..e7d87a0e3c6 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -204,7 +204,7 @@ static void add_candidates (tree, tree, const VEC(tree,gc) *, tree, tree, bool, tree, tree, int, struct z_candidate **); static conversion *merge_conversion_sequences (conversion *, conversion *); static bool magic_varargs_p (tree); -static tree build_temp (tree, tree, int, diagnostic_t *); +static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t); /* Returns nonzero iff the destructor name specified in NAME matches BASETYPE. NAME can take many forms... */ @@ -641,7 +641,7 @@ build_aggr_conv (tree type, tree ctor, int flags) tree field = next_initializable_field (TYPE_FIELDS (type)); tree empty_ctor = NULL_TREE; - for (; field; field = next_initializable_field (TREE_CHAIN (field))) + for (; field; field = next_initializable_field (DECL_CHAIN (field))) { if (i < CONSTRUCTOR_NELTS (ctor)) { @@ -1045,6 +1045,9 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags) struct z_candidate *cand; bool any_viable_p; + if (!expr) + return NULL; + conversions = lookup_conversions (s, /*lookup_template_convs_p=*/true); if (!conversions) return NULL; @@ -1598,6 +1601,27 @@ add_function_candidate (struct z_candidate **candidates, else if (!sufficient_parms_p (parmnode)) viable = 0; + /* Kludge: When looking for a function from a subobject while generating + an implicit copy/move constructor/operator=, don't consider anything + that takes (a reference to) a different type. See c++/44909. */ + else if (flags & LOOKUP_SPECULATIVE) + { + if (DECL_CONSTRUCTOR_P (fn)) + i = 1; + else if (DECL_ASSIGNMENT_OPERATOR_P (fn) + && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR) + i = 2; + else + i = 0; + if (i && len == i) + { + parmnode = chain_index (i-1, parmlist); + if (!(same_type_ignoring_top_level_qualifiers_p + (non_reference (TREE_VALUE (parmnode)), ctype))) + viable = 0; + } + } + if (! viable) goto out; @@ -3863,8 +3887,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3, && same_type_p (arg2_type, arg3_type)) { result_type = arg2_type; - mark_lvalue_use (arg2); - mark_lvalue_use (arg3); + arg2 = mark_lvalue_use (arg2); + arg3 = mark_lvalue_use (arg3); goto valid_operands; } @@ -4853,7 +4877,7 @@ enforce_access (tree basetype_path, tree decl, tree diag_decl) static tree build_temp (tree expr, tree type, int flags, - diagnostic_t *diagnostic_kind) + diagnostic_t *diagnostic_kind, tsubst_flags_t complain) { int savew, savee; VEC(tree,gc) *args; @@ -4861,7 +4885,7 @@ build_temp (tree expr, tree type, int flags, savew = warningcount, savee = errorcount; args = make_tree_vector_single (expr); expr = build_special_member_call (NULL_TREE, complete_ctor_identifier, - &args, type, flags, tf_warning_or_error); + &args, type, flags, complain); release_tree_vector (args); if (warningcount > savew) *diagnostic_kind = DK_WARNING; @@ -5134,7 +5158,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, conversion (i.e. the second step of copy-initialization), so don't allow any more. */ flags |= LOOKUP_NO_CONVERSION; - expr = build_temp (expr, totype, flags, &diag_kind); + expr = build_temp (expr, totype, flags, &diag_kind, complain); if (diag_kind && fn) { if ((complain & tf_error)) @@ -5248,7 +5272,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, case ck_pmem: return convert_ptrmem (totype, expr, /*allow_inverse_p=*/false, - c_cast_p); + c_cast_p, complain); default: break; @@ -6097,7 +6121,7 @@ build_java_interface_fn_ref (tree fn, tree instance) /* Determine the itable index of FN. */ i = 1; - for (method = TYPE_METHODS (iface); method; method = TREE_CHAIN (method)) + for (method = TYPE_METHODS (iface); method; method = DECL_CHAIN (method)) { if (!DECL_VIRTUAL_P (method)) continue; @@ -6229,7 +6253,7 @@ build_special_member_call (tree instance, tree name, VEC(tree,gc) **args, /* If the current function is a complete object constructor or destructor, then we fetch the VTT directly. Otherwise, we look it up using the VTT we were given. */ - vtt = TREE_CHAIN (CLASSTYPE_VTABLES (current_class_type)); + vtt = DECL_CHAIN (CLASSTYPE_VTABLES (current_class_type)); vtt = decay_conversion (vtt); vtt = build3 (COND_EXPR, TREE_TYPE (vtt), build2 (EQ_EXPR, boolean_type_node, @@ -7955,6 +7979,10 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup, bool is_std_init_list (tree type) { + /* Look through typedefs. */ + if (!TYPE_P (type)) + return false; + type = TYPE_MAIN_VARIANT (type); return (CLASS_TYPE_P (type) && CP_TYPE_CONTEXT (type) == std_node && strcmp (TYPE_NAME_STRING (type), "initializer_list") == 0); diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 3f87303be93..6597111955e 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -284,7 +284,7 @@ build_base_path (enum tree_code code, /* This must happen before the call to save_expr. */ expr = cp_build_unary_op (ADDR_EXPR, expr, 0, tf_warning_or_error); else - mark_rvalue_use (expr); + expr = mark_rvalue_use (expr); offset = BINFO_OFFSET (binfo); fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); @@ -469,7 +469,7 @@ build_simple_base_path (tree expr, tree binfo) expr = build_simple_base_path (expr, d_binfo); for (field = TYPE_FIELDS (BINFO_TYPE (d_binfo)); - field; field = TREE_CHAIN (field)) + field; field = DECL_CHAIN (field)) /* Is this the base field created by build_base_field? */ if (TREE_CODE (field) == FIELD_DECL && DECL_FIELD_IS_BASE (field) @@ -1260,7 +1260,7 @@ check_bases (tree t, seen_non_virtual_nearly_empty_base_p = 0; if (!CLASSTYPE_NON_STD_LAYOUT (t)) - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL) break; @@ -1345,7 +1345,7 @@ check_bases (tree t, members, or has no base classes with non-static data members */ for (basefield = TYPE_FIELDS (basetype); basefield; - basefield = TREE_CHAIN (basefield)) + basefield = DECL_CHAIN (basefield)) if (TREE_CODE (basefield) == FIELD_DECL) { if (field) @@ -1603,7 +1603,7 @@ maybe_warn_about_overly_private_class (tree t) functions are private. (Since there are no friends or non-private statics, we can't ever call any of the private member functions.) */ - for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) + for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) /* We're not interested in compiler-generated methods; they don't provide any way to call private members. */ if (!DECL_ARTIFICIAL (fn)) @@ -1808,7 +1808,7 @@ finish_struct_methods (tree t) /* Clear DECL_IN_AGGR_P for all functions. */ for (fn_fields = TYPE_METHODS (t); fn_fields; - fn_fields = TREE_CHAIN (fn_fields)) + fn_fields = DECL_CHAIN (fn_fields)) DECL_IN_AGGR_P (fn_fields) = 0; /* Issue warnings about private constructors and such. If there are @@ -2058,8 +2058,9 @@ get_vcall_index (tree fn, tree type) } /* Update an entry in the vtable for BINFO, which is in the hierarchy - dominated by T. FN has been overridden in BINFO; VIRTUALS points to the - corresponding position in the BINFO_VIRTUALS list. */ + dominated by T. FN is the old function; VIRTUALS points to the + corresponding position in the new BINFO_VIRTUALS list. IX is the index + of that entry in the list. */ static void update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, @@ -2204,6 +2205,40 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, gcc_assert (DECL_INVALID_OVERRIDER_P (overrider_target) || !DECL_THUNK_P (fn)); + /* If we need a covariant thunk, then we may need to adjust first_defn. + The ABI specifies that the thunks emitted with a function are + determined by which bases the function overrides, so we need to be + sure that we're using a thunk for some overridden base; even if we + know that the necessary this adjustment is zero, there may not be an + appropriate zero-this-adjusment thunk for us to use since thunks for + overriding virtual bases always use the vcall offset. + + Furthermore, just choosing any base that overrides this function isn't + quite right, as this slot won't be used for calls through a type that + puts a covariant thunk here. Calling the function through such a type + will use a different slot, and that slot is the one that determines + the thunk emitted for that base. + + So, keep looking until we find the base that we're really overriding + in this slot: the nearest primary base that doesn't use a covariant + thunk in this slot. */ + if (overrider_target != overrider_fn) + { + if (BINFO_TYPE (b) == DECL_CONTEXT (overrider_target)) + /* We already know that the overrider needs a covariant thunk. */ + b = get_primary_binfo (b); + for (; ; b = get_primary_binfo (b)) + { + tree main_binfo = TYPE_BINFO (BINFO_TYPE (b)); + tree bv = chain_index (ix, BINFO_VIRTUALS (main_binfo)); + if (BINFO_LOST_PRIMARY_P (b)) + lost = true; + if (!DECL_THUNK_P (TREE_VALUE (bv))) + break; + } + first_defn = b; + } + /* Assume that we will produce a thunk that convert all the way to the final overrider, and not to an intermediate virtual base. */ virtual_base = NULL_TREE; @@ -2228,36 +2263,6 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, } } - if (overrider_fn != overrider_target && !virtual_base) - { - /* The ABI specifies that a covariant thunk includes a mangling - for a this pointer adjustment. This-adjusting thunks that - override a function from a virtual base have a vcall - adjustment. When the virtual base in question is a primary - virtual base, we know the adjustments are zero, (and in the - non-covariant case, we would not use the thunk). - Unfortunately we didn't notice this could happen, when - designing the ABI and so never mandated that such a covariant - thunk should be emitted. Because we must use the ABI mandated - name, we must continue searching from the binfo where we - found the most recent definition of the function, towards the - primary binfo which first introduced the function into the - vtable. If that enters a virtual base, we must use a vcall - this-adjusting thunk. Bleah! */ - tree probe = first_defn; - - while ((probe = get_primary_binfo (probe)) - && (unsigned) list_length (BINFO_VIRTUALS (probe)) > ix) - if (BINFO_VIRTUAL_P (probe)) - virtual_base = probe; - - if (virtual_base) - /* Even if we find a virtual base, the correct delta is - between the overrider and the binfo we're building a vtable - for. */ - goto virtual_covariant; - } - /* Compute the constant adjustment to the `this' pointer. The `this' pointer, when this function is called, will point at BINFO (or one of its primary bases, which are at the same offset). */ @@ -2277,7 +2282,6 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, /* The `this' pointer needs to be adjusted from pointing to BINFO to pointing at the base where the final overrider appears. */ - virtual_covariant: delta = size_diffop_loc (input_location, convert (ssizetype, BINFO_OFFSET (TREE_VALUE (overrider))), @@ -2290,6 +2294,9 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, = get_vcall_index (overrider_target, BINFO_TYPE (virtual_base)); else BV_VCALL_INDEX (*virtuals) = NULL_TREE; + + if (lost) + BV_LOST_PRIMARY (*virtuals) = true; } /* Called from modify_all_vtables via dfs_walk. */ @@ -2532,7 +2539,7 @@ finish_struct_anon (tree t) { tree field; - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) { if (TREE_STATIC (field)) continue; @@ -2544,7 +2551,7 @@ finish_struct_anon (tree t) { bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE; tree elt = TYPE_FIELDS (TREE_TYPE (field)); - for (; elt; elt = TREE_CHAIN (elt)) + for (; elt; elt = DECL_CHAIN (elt)) { /* We're generally only interested in entities the user declared, but we also find nested classes by noticing @@ -2715,7 +2722,7 @@ count_fields (tree fields) { tree x; int n_fields = 0; - for (x = fields; x; x = TREE_CHAIN (x)) + for (x = fields; x; x = DECL_CHAIN (x)) { if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x))) n_fields += count_fields (TYPE_FIELDS (TREE_TYPE (x))); @@ -2732,7 +2739,7 @@ static int add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, int idx) { tree x; - for (x = fields; x; x = TREE_CHAIN (x)) + for (x = fields; x; x = DECL_CHAIN (x)) { if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x))) idx = add_fields_to_record_type (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx); @@ -2827,9 +2834,9 @@ check_field_decl (tree field, { tree type = strip_array_types (TREE_TYPE (field)); - /* An anonymous union cannot contain any fields which would change + /* In C++98 an anonymous union cannot contain any fields which would change the settings of CANT_HAVE_CONST_CTOR and friends. */ - if (ANON_UNION_TYPE_P (type)) + if (ANON_UNION_TYPE_P (type) && cxx_dialect < cxx0x) ; /* And, we don't set TYPE_HAS_CONST_COPY_CTOR, etc., for anonymous structs. So, we recurse through their fields here. */ @@ -2837,7 +2844,7 @@ check_field_decl (tree field, { tree fields; - for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields)) + for (fields = TYPE_FIELDS (type); fields; fields = DECL_CHAIN (fields)) if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field)) check_field_decl (fields, t, cant_have_const_ctor, no_const_asn_ref, any_default_members); @@ -2850,8 +2857,10 @@ check_field_decl (tree field, make it through without complaint. */ abstract_virtuals_error (field, type); - if (TREE_CODE (t) == UNION_TYPE) + if (TREE_CODE (t) == UNION_TYPE && cxx_dialect < cxx0x) { + static bool warned; + int oldcount = errorcount; if (TYPE_NEEDS_CONSTRUCTING (type)) error ("member %q+#D with constructor not allowed in union", field); @@ -2860,8 +2869,12 @@ check_field_decl (tree field, if (TYPE_HAS_COMPLEX_COPY_ASSIGN (type)) error ("member %q+#D with copy assignment operator not allowed in union", field); - /* Don't bother diagnosing move assop now; C++0x has more - flexible unions. */ + if (!warned && errorcount > oldcount) + { + inform (DECL_SOURCE_LOCATION (field), "unrestricted unions " + "only available with -std=c++0x or -std=gnu++0x"); + warned = true; + } } else { @@ -2948,12 +2961,12 @@ check_field_decls (tree t, tree *access_decls, tree type = TREE_TYPE (x); int this_field_access; - next = &TREE_CHAIN (x); + next = &DECL_CHAIN (x); if (TREE_CODE (x) == USING_DECL) { /* Prune the access declaration from the list of fields. */ - *field = TREE_CHAIN (x); + *field = DECL_CHAIN (x); /* Save the access declarations for our caller. */ *access_decls = tree_cons (NULL_TREE, x, *access_decls); @@ -3386,7 +3399,7 @@ walk_subobject_offsets (tree type, } /* Iterate through the fields of TYPE. */ - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL && !DECL_ARTIFICIAL (field)) { tree field_offset; @@ -3735,9 +3748,9 @@ build_base_field (record_layout_info rli, tree binfo, objects of the same type at the same address. */ layout_nonempty_base_or_field (rli, decl, binfo, offsets); /* Add the new FIELD_DECL to the list of fields for T. */ - TREE_CHAIN (decl) = *next_field; + DECL_CHAIN (decl) = *next_field; *next_field = decl; - next_field = &TREE_CHAIN (decl); + next_field = &DECL_CHAIN (decl); } } else @@ -3849,7 +3862,7 @@ check_methods (tree t) { tree x; - for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) + for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x)) { check_for_override (x, t); if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x)) @@ -3888,8 +3901,8 @@ build_clone (tree fn, tree name) /* Remember where this function came from. */ DECL_ABSTRACT_ORIGIN (clone) = fn; /* Make it easy to find the CLONE given the FN. */ - TREE_CHAIN (clone) = TREE_CHAIN (fn); - TREE_CHAIN (fn) = clone; + DECL_CHAIN (clone) = DECL_CHAIN (fn); + DECL_CHAIN (fn) = clone; /* If this is a template, do the rest on the DECL_TEMPLATE_RESULT. */ if (TREE_CODE (clone) == TEMPLATE_DECL) @@ -3953,8 +3966,8 @@ build_clone (tree fn, tree name) /* Remove the in-charge parameter. */ if (DECL_HAS_IN_CHARGE_PARM_P (clone)) { - TREE_CHAIN (DECL_ARGUMENTS (clone)) - = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone))); + DECL_CHAIN (DECL_ARGUMENTS (clone)) + = DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))); DECL_HAS_IN_CHARGE_PARM_P (clone) = 0; } /* And the VTT parm, in a complete [cd]tor. */ @@ -3964,13 +3977,13 @@ build_clone (tree fn, tree name) DECL_HAS_VTT_PARM_P (clone) = 1; else { - TREE_CHAIN (DECL_ARGUMENTS (clone)) - = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone))); + DECL_CHAIN (DECL_ARGUMENTS (clone)) + = DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))); DECL_HAS_VTT_PARM_P (clone) = 0; } } - for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms)) + for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms)) { DECL_CONTEXT (parms) = clone; cxx_dup_lang_specific_decl (parms); @@ -4033,8 +4046,8 @@ clone_function_decl (tree fn, int update_method_vec_p) tree clone; /* Avoid inappropriate cloning. */ - if (TREE_CHAIN (fn) - && DECL_CLONED_FUNCTION_P (TREE_CHAIN (fn))) + if (DECL_CHAIN (fn) + && DECL_CLONED_FUNCTION_P (DECL_CHAIN (fn))) return; if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)) @@ -4091,8 +4104,8 @@ adjust_clone_args (tree decl) { tree clone; - for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION_P (clone); - clone = TREE_CHAIN (clone)) + for (clone = DECL_CHAIN (decl); clone && DECL_CLONED_FUNCTION_P (clone); + clone = DECL_CHAIN (clone)) { tree orig_clone_parms = TYPE_ARG_TYPES (TREE_TYPE (clone)); tree orig_decl_parms = TYPE_ARG_TYPES (TREE_TYPE (decl)); @@ -4363,9 +4376,9 @@ remove_zero_width_bit_fields (tree t) check_bitfield_decl eventually sets DECL_SIZE (*fieldsp) to that width. */ && integer_zerop (DECL_SIZE (*fieldsp))) - *fieldsp = TREE_CHAIN (*fieldsp); + *fieldsp = DECL_CHAIN (*fieldsp); else - fieldsp = &TREE_CHAIN (*fieldsp); + fieldsp = &DECL_CHAIN (*fieldsp); } } @@ -4519,7 +4532,7 @@ check_bases_and_members (tree t) { tree field; - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) { tree type; @@ -4545,7 +4558,7 @@ check_bases_and_members (tree t) /* Check defaulted declarations here so we have cant_have_const_ctor and don't need to worry about clones. */ - for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) + for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) if (DECL_DEFAULTED_IN_CLASS_P (fn)) { int copy = copy_fn_p (fn); @@ -4611,7 +4624,7 @@ create_vtable_ptr (tree t, tree* virtuals_p) tree fn; /* Collect the virtual functions declared in T. */ - for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) + for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn) && TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST) { @@ -4746,7 +4759,7 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets) bases will go after the last extant field to date. */ next_field = &TYPE_FIELDS (t); while (*next_field) - next_field = &TREE_CHAIN (*next_field); + next_field = &DECL_CHAIN (*next_field); /* Go through the virtual bases, allocating space for each virtual base that is not already a primary base class. These are @@ -4987,9 +5000,9 @@ layout_class_type (tree t, tree *virtuals_p) /* The vptr is always the first thing in the class. */ if (vptr) { - TREE_CHAIN (vptr) = TYPE_FIELDS (t); + DECL_CHAIN (vptr) = TYPE_FIELDS (t); TYPE_FIELDS (t) = vptr; - next_field = &TREE_CHAIN (vptr); + next_field = &DECL_CHAIN (vptr); place_field (rli, vptr); } else @@ -5001,7 +5014,7 @@ layout_class_type (tree t, tree *virtuals_p) build_base_fields (rli, empty_base_offsets, next_field); /* Layout the non-static data members. */ - for (field = non_static_data_members; field; field = TREE_CHAIN (field)) + for (field = non_static_data_members; field; field = DECL_CHAIN (field)) { tree type; tree padding; @@ -5282,7 +5295,7 @@ layout_class_type (tree t, tree *virtuals_p) /* Copy the fields from T. */ next_field = &TYPE_FIELDS (base_t); - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL) { *next_field = build_decl (input_location, @@ -5295,7 +5308,7 @@ layout_class_type (tree t, tree *virtuals_p) = DECL_FIELD_BIT_OFFSET (field); DECL_SIZE (*next_field) = DECL_SIZE (field); DECL_MODE (*next_field) = DECL_MODE (field); - next_field = &TREE_CHAIN (*next_field); + next_field = &DECL_CHAIN (*next_field); } /* Record the base version of the type. */ @@ -5342,7 +5355,7 @@ layout_class_type (tree t, tree *virtuals_p) warn_about_ambiguous_bases (t); /* Now that we're done with layout, give the base fields the real types. */ - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) if (DECL_ARTIFICIAL (field) && IS_FAKE_BASE_TYPE (TREE_TYPE (field))) TREE_TYPE (field) = TYPE_CONTEXT (TREE_TYPE (field)); @@ -5374,7 +5387,7 @@ determine_key_method (tree type) key function may not be inline; those targets should not call this function until the end of the translation unit. */ for (method = TYPE_METHODS (type); method != NULL_TREE; - method = TREE_CHAIN (method)) + method = DECL_CHAIN (method)) if (DECL_VINDEX (method) != NULL_TREE && ! DECL_DECLARED_INLINE_P (method) && ! DECL_PURE_VIRTUAL_P (method)) @@ -5498,7 +5511,7 @@ finish_struct_1 (tree t) /* Complete the rtl for any static member objects of the type we're working on. */ - for (x = TYPE_FIELDS (t); x; x = TREE_CHAIN (x)) + for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x)) if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x) && TREE_TYPE (x) != error_mark_node && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t)) @@ -5595,13 +5608,13 @@ unreverse_member_declarations (tree t) x && TREE_CODE (x) != TYPE_DECL; x = next) { - next = TREE_CHAIN (x); - TREE_CHAIN (x) = prev; + next = DECL_CHAIN (x); + DECL_CHAIN (x) = prev; prev = x; } if (prev) { - TREE_CHAIN (TYPE_FIELDS (t)) = x; + DECL_CHAIN (TYPE_FIELDS (t)) = x; if (prev) TYPE_FIELDS (t) = prev; } @@ -5638,7 +5651,7 @@ finish_struct (tree t, tree attributes) CLASSTYPE_PURE_VIRTUALS contains the list of the inline friends (see CLASSTYPE_INLINE_FRIENDS) so we need to clear it. */ CLASSTYPE_PURE_VIRTUALS (t) = NULL; - for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) + for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x)) if (DECL_PURE_VIRTUAL_P (x)) VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x); complete_vars (t); @@ -6749,7 +6762,7 @@ is_really_empty_class (tree type) BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) if (!is_really_empty_class (BINFO_TYPE (base_binfo))) return false; - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL && !DECL_ARTIFICIAL (field) && !is_really_empty_class (TREE_TYPE (field))) @@ -7202,8 +7215,8 @@ build_vtt (tree t) vtt = build_vtable (t, mangle_vtt_for_type (t), type); initialize_artificial_var (vtt, inits); /* Add the VTT to the vtables list. */ - TREE_CHAIN (vtt) = TREE_CHAIN (CLASSTYPE_VTABLES (t)); - TREE_CHAIN (CLASSTYPE_VTABLES (t)) = vtt; + DECL_CHAIN (vtt) = DECL_CHAIN (CLASSTYPE_VTABLES (t)); + DECL_CHAIN (CLASSTYPE_VTABLES (t)) = vtt; dump_vtt (t, vtt); } @@ -7656,7 +7669,7 @@ build_vtbl_initializer (tree binfo, int* non_fn_entries_p, VEC(constructor_elt,gc) **inits) { - tree v, b; + tree v; vtbl_init_data vid; unsigned ix, jx; tree vbinfo; @@ -7770,20 +7783,8 @@ build_vtbl_initializer (tree binfo, zero out unused slots in ctor vtables, rather than filling them with erroneous values (though harmless, apart from relocation costs). */ - for (b = binfo; ; b = get_primary_binfo (b)) - { - /* We found a defn before a lost primary; go ahead as normal. */ - if (look_for_overrides_here (BINFO_TYPE (b), fn_original)) - break; - - /* The nearest definition is from a lost primary; clear the - slot. */ - if (BINFO_LOST_PRIMARY_P (b)) - { - init = size_zero_node; - break; - } - } + if (BV_LOST_PRIMARY (v)) + init = size_zero_node; if (! init) { @@ -8045,7 +8046,7 @@ add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid) order. G++ 3.2 used the order in the vtable. */ for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo)); orig_fn; - orig_fn = TREE_CHAIN (orig_fn)) + orig_fn = DECL_CHAIN (orig_fn)) if (DECL_VINDEX (orig_fn)) add_vcall_offset (orig_fn, binfo, vid); } diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index fb7daeb3e81..abd5bf37b6e 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -51,7 +51,7 @@ static tree begin_bc_block (enum bc_t bc) { tree label = create_artificial_label (input_location); - TREE_CHAIN (label) = bc_label[bc]; + DECL_CHAIN (label) = bc_label[bc]; bc_label[bc] = label; return label; } @@ -73,8 +73,8 @@ finish_bc_block (enum bc_t bc, tree label, gimple_seq body) gimple_seq_add_stmt (&body, gimple_build_label (label)); } - bc_label[bc] = TREE_CHAIN (label); - TREE_CHAIN (label) = NULL_TREE; + bc_label[bc] = DECL_CHAIN (label); + DECL_CHAIN (label) = NULL_TREE; return body; } @@ -575,7 +575,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (op0), op1); - else if ((rhs_predicate_for (op0)) (op1) + else if ((is_gimple_lvalue (op1) || INDIRECT_REF_P (op1)) && !(TREE_CODE (op1) == CALL_EXPR && CALL_EXPR_RETURN_SLOT_OPT (op1)) && is_really_empty_class (TREE_TYPE (op0))) @@ -893,7 +893,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) IMPORTED_DECL_ASSOCIATED_DECL (using_directive) = TREE_OPERAND (stmt, 0); - TREE_CHAIN (using_directive) = BLOCK_VARS (block); + DECL_CHAIN (using_directive) = BLOCK_VARS (block); BLOCK_VARS (block) = using_directive; } /* The USING_STMT won't appear in GENERIC. */ @@ -921,7 +921,7 @@ cp_genericize (tree fndecl) struct cp_genericize_data wtd; /* Fix up the types of parms passed by invisible reference. */ - for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t)) + for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t)) if (TREE_ADDRESSABLE (TREE_TYPE (t))) { /* If a function's arguments are copied to create a thunk, @@ -1178,7 +1178,7 @@ cxx_omp_predetermined_sharing (tree decl) tree var; if (outer) - for (var = BLOCK_VARS (outer); var; var = TREE_CHAIN (var)) + for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var)) if (DECL_NAME (decl) == DECL_NAME (var) && (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (var)))) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index dbb6b9d5062..548bf68496e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -30,19 +30,18 @@ along with GCC; see the file COPYING3. If not see /* In order for the format checking to accept the C++ front end diagnostic framework extensions, you must include this file before - toplev.h, not after. We override the definition of GCC_DIAG_STYLE + diagnostic-core.h, not after. We override the definition of GCC_DIAG_STYLE in c-common.h. */ #undef GCC_DIAG_STYLE #define GCC_DIAG_STYLE __gcc_cxxdiag__ -#if defined(GCC_TOPLEV_H) || defined (GCC_C_COMMON_H) +#if defined(GCC_DIAGNOSTIC_CORE_H) || defined (GCC_C_COMMON_H) #error \ In order for the format checking to accept the C++ front end diagnostic \ -framework extensions, you must include this file before toplev.h and \ +framework extensions, you must include this file before diagnostic-core.h and \ c-common.h, not after. #endif -#include "toplev.h" -#include "diagnostic.h" #include "c-family/c-common.h" +#include "diagnostic.h" #include "name-lookup.h" @@ -169,6 +168,9 @@ c-common.h, not after. The BV_FN is the declaration for the virtual function itself. + If BV_LOST_PRIMARY is set, it means that this entry is for a lost + primary virtual base and can be left null in the vtable. + BINFO_VTABLE This is an expression with POINTER_TYPE that gives the value to which the vptr should be initialized. Use get_vtbl_decl_for_binfo @@ -287,11 +289,6 @@ typedef struct ptrmem_cst * ptrmem_cst_t; #define same_type_p(TYPE1, TYPE2) \ comptypes ((TYPE1), (TYPE2), COMPARE_STRICT) -/* Returns nonzero iff TYPE1 and TYPE2 are the same type, ignoring - top-level qualifiers. */ -#define same_type_ignoring_top_level_qualifiers_p(TYPE1, TYPE2) \ - same_type_p (TYPE_MAIN_VARIANT (TYPE1), TYPE_MAIN_VARIANT (TYPE2)) - /* Nonzero if we are presently building a statement tree, rather than expanding each statement as we encounter it. */ #define building_stmt_tree() (cur_stmt_list != NULL_TREE) @@ -435,6 +432,17 @@ typedef enum impl_conv_rhs { ICR_ASSIGN /* assignment */ } impl_conv_rhs; +/* Possible cases of implicit or explicit bad conversions to void. */ +typedef enum impl_conv_void { + ICV_CAST, /* (explicit) conversion to void */ + ICV_SECOND_OF_COND, /* second operand of conditional expression */ + ICV_THIRD_OF_COND, /* third operand of conditional expression */ + ICV_RIGHT_OF_COMMA, /* right operand of comma operator */ + ICV_LEFT_OF_COMMA, /* left operand of comma operator */ + ICV_STATEMENT, /* statement */ + ICV_THIRD_IN_FOR /* for increment expression */ +} impl_conv_void; + /* Macros for access to language-specific slots in an identifier. */ #define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \ @@ -1757,6 +1765,8 @@ struct GTY((variable_size)) lang_type { /* The function to call. */ #define BV_FN(NODE) (TREE_VALUE (NODE)) +/* Whether or not this entry is for a lost primary virtual base. */ +#define BV_LOST_PRIMARY(NODE) (TREE_LANG_FLAG_0 (NODE)) /* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that this type can raise. Each TREE_VALUE is a _TYPE. The TREE_VALUE @@ -2076,9 +2086,9 @@ struct GTY((variable_size)) lang_decl { if (TREE_CODE (FN) == FUNCTION_DECL \ && (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (FN) \ || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (FN))) \ - for (CLONE = TREE_CHAIN (FN); \ + for (CLONE = DECL_CHAIN (FN); \ CLONE && DECL_CLONED_FUNCTION_P (CLONE); \ - CLONE = TREE_CHAIN (CLONE)) + CLONE = DECL_CHAIN (CLONE)) /* Nonzero if NODE has DECL_DISCRIMINATOR and not DECL_ACCESS. */ #define DECL_DISCRIMINATOR_P(NODE) \ @@ -3992,7 +4002,6 @@ typedef enum base_kind { /* For building calls to `delete'. */ extern GTY(()) tree integer_two_node; -extern GTY(()) tree integer_three_node; /* The number of function bodies which we are currently processing. (Zero if we are at namespace scope, one inside the body of a @@ -4703,8 +4712,8 @@ extern tree ocp_convert (tree, tree, int, int); extern tree cp_convert (tree, tree); extern tree cp_convert_and_check (tree, tree); extern tree cp_fold_convert (tree, tree); -extern tree convert_to_void (tree, const char */*implicit context*/, - tsubst_flags_t); +extern tree convert_to_void (tree, impl_conv_void, + tsubst_flags_t); extern tree convert_force (tree, tree, int); extern tree build_expr_type_conversion (int, tree, bool); extern tree type_promotes_to (tree); @@ -5420,6 +5429,7 @@ extern int type_unknown_p (const_tree); enum { ce_derived, ce_normal, ce_exact }; extern bool comp_except_specs (const_tree, const_tree, int); extern bool comptypes (tree, tree, int); +extern bool same_type_ignoring_top_level_qualifiers_p (tree, tree); extern bool compparms (const_tree, const_tree); extern int comp_cv_qualification (const_tree, const_tree); extern int comp_cv_qual_signature (tree, tree); @@ -5458,7 +5468,8 @@ extern tree cp_build_unary_op (enum tree_code, tree, int, extern tree unary_complex_lvalue (enum tree_code, tree); extern tree build_x_conditional_expr (tree, tree, tree, tsubst_flags_t); -extern tree build_x_compound_expr_from_list (tree, expr_list_kind); +extern tree build_x_compound_expr_from_list (tree, expr_list_kind, + tsubst_flags_t); extern tree build_x_compound_expr_from_vec (VEC(tree,gc) *, const char *); extern tree build_x_compound_expr (tree, tree, tsubst_flags_t); extern tree build_compound_expr (location_t, tree, tree); @@ -5479,7 +5490,8 @@ extern int comp_ptr_ttypes (tree, tree); extern bool comp_ptr_ttypes_const (tree, tree); extern bool error_type_p (const_tree); extern int ptr_reasonably_similar (const_tree, const_tree); -extern tree build_ptrmemfunc (tree, tree, int, bool); +extern tree build_ptrmemfunc (tree, tree, int, bool, + tsubst_flags_t); extern int cp_type_quals (const_tree); extern int type_memfn_quals (const_tree); extern tree apply_memfn_quals (tree, cp_cv_quals); @@ -5508,7 +5520,8 @@ extern tree non_reference (tree); extern tree lookup_anon_field (tree, tree); extern bool invalid_nonstatic_memfn_p (const_tree, tsubst_flags_t); extern tree convert_member_func_to_ptr (tree, tree); -extern tree convert_ptrmem (tree, tree, bool, bool); +extern tree convert_ptrmem (tree, tree, bool, bool, + tsubst_flags_t); extern int lvalue_or_else (tree, enum lvalue_use, tsubst_flags_t); extern void check_template_keyword (tree); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 40a635153bc..26c4442a94b 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -176,7 +176,7 @@ cp_convert_to_pointer (tree type, tree expr) else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype)) || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))) return convert_ptrmem (type, expr, /*allow_inverse_p=*/false, - /*c_cast_p=*/false); + /*c_cast_p=*/false, tf_warning_or_error); else if (TYPE_PTRMEMFUNC_P (intype)) { if (!warn_pmf2ptr) @@ -200,7 +200,7 @@ cp_convert_to_pointer (tree type, tree expr) { if (TYPE_PTRMEMFUNC_P (type)) return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0, - /*c_cast_p=*/false); + /*c_cast_p=*/false, tf_warning_or_error); if (TYPE_PTRMEM_P (type)) { @@ -651,7 +651,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags) if (code == VOID_TYPE && (convtype & CONV_STATIC)) { - e = convert_to_void (e, /*implicit=*/NULL, tf_warning_or_error); + e = convert_to_void (e, ICV_CAST, tf_warning_or_error); return e; } @@ -814,19 +814,18 @@ ocp_convert (tree type, tree expr, int convtype, int flags) make it impossible to ignore the reference return value from functions. We issue warnings in the confusing cases. - IMPLICIT is non-NULL iff an expression is being implicitly converted; it - is NULL when the user is explicitly converting an expression to void via - a cast. When non-NULL, IMPLICIT is a string indicating the context of - the implicit conversion. */ + The IMPLICIT is ICV_CAST when the user is explicitly converting an expression + to void via a cast. If an expression is being implicitly converted, IMPLICIT + indicates the context of the implicit conversion. */ tree -convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) +convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) { if (expr == error_mark_node || TREE_TYPE (expr) == error_mark_node) return error_mark_node; - if (implicit == NULL) + if (implicit == ICV_CAST) mark_exp_read (expr); else { @@ -865,12 +864,17 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) tree op1 = TREE_OPERAND (expr,1); tree op2 = TREE_OPERAND (expr,2); bool side_effects = TREE_SIDE_EFFECTS (op1) || TREE_SIDE_EFFECTS (op2); - tree new_op1 = convert_to_void - (op1, (implicit && !side_effects - ? "second operand of conditional" : NULL), complain); - tree new_op2 = convert_to_void - (op2, (implicit && !side_effects - ? "third operand of conditional" : NULL), complain); + tree new_op1, new_op2; + if (implicit != ICV_CAST && !side_effects) + { + new_op1 = convert_to_void (op1, ICV_SECOND_OF_COND, complain); + new_op2 = convert_to_void (op2, ICV_THIRD_OF_COND, complain); + } + else + { + new_op1 = convert_to_void (op1, ICV_CAST, complain); + new_op2 = convert_to_void (op2, ICV_CAST, complain); + } expr = build3 (COND_EXPR, TREE_TYPE (new_op1), TREE_OPERAND (expr, 0), new_op1, new_op2); @@ -881,9 +885,11 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) { /* The second part of a compound expr contains the value. */ tree op1 = TREE_OPERAND (expr,1); - tree new_op1 = convert_to_void - (op1, (implicit && !TREE_NO_WARNING (expr) - ? "right-hand operand of comma" : NULL), complain); + tree new_op1; + if (implicit != ICV_CAST && !TREE_NO_WARNING (expr)) + new_op1 = convert_to_void (op1, ICV_RIGHT_OF_COMMA, complain); + else + new_op1 = convert_to_void (op1, ICV_CAST, complain); if (new_op1 != op1) { @@ -915,18 +921,133 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) if (is_volatile && !is_complete) { if (complain & tf_warning) - warning (0, "object of incomplete type %qT will not be accessed in %s", - type, implicit ? implicit : "void context"); + switch (implicit) + { + case ICV_CAST: + warning (0, "conversion to void will not access " + "object of incomplete type %qT", type); + break; + case ICV_SECOND_OF_COND: + warning (0, "indirection will not access object of " + "incomplete type %qT in second operand " + "of conditional expression", type); + break; + case ICV_THIRD_OF_COND: + warning (0, "indirection will not access object of " + "incomplete type %qT in third operand " + "of conditional expression", type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "indirection will not access object of " + "incomplete type %qT in right operand of " + "comma operator", type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "indirection will not access object of " + "incomplete type %qT in left operand of " + "comma operator", type); + break; + case ICV_STATEMENT: + warning (0, "indirection will not access object of " + "incomplete type %qT in statement", type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "indirection will not access object of " + "incomplete type %qT in for increment " + "expression", type); + break; + default: + gcc_unreachable (); + } } /* Don't load the value if this is an implicit dereference, or if the type needs to be handled by ctors/dtors. */ - else if (is_volatile && (is_reference || TREE_ADDRESSABLE (type))) + else if (is_volatile && is_reference) { if (complain & tf_warning) - warning (0, "object of type %qT will not be accessed in %s", - TREE_TYPE (TREE_OPERAND (expr, 0)), - implicit ? implicit : "void context"); + switch (implicit) + { + case ICV_CAST: + warning (0, "conversion to void will not access " + "object of type %qT", type); + break; + case ICV_SECOND_OF_COND: + warning (0, "implicit dereference will not access object " + "of type %qT in second operand of " + "conditional expression", type); + break; + case ICV_THIRD_OF_COND: + warning (0, "implicit dereference will not access object " + "of type %qT in third operand of " + "conditional expression", type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "implicit dereference will not access object " + "of type %qT in right operand of " + "comma operator", type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "implicit dereference will not access object " + "of type %qT in left operand of comma operator", + type); + break; + case ICV_STATEMENT: + warning (0, "implicit dereference will not access object " + "of type %qT in statement", type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "implicit dereference will not access object " + "of type %qT in for increment expression", + type); + break; + default: + gcc_unreachable (); + } } + else if (is_volatile && TREE_ADDRESSABLE (type)) + { + if (complain & tf_warning) + switch (implicit) + { + case ICV_CAST: + warning (0, "conversion to void will not access " + "object of non-trivially-copyable type %qT", + type); + break; + case ICV_SECOND_OF_COND: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in second " + "operand of conditional expression", type); + break; + case ICV_THIRD_OF_COND: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in third " + "operand of conditional expression", type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in right " + "operand of comma operator", type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in left " + "operand of comma operator", type); + break; + case ICV_STATEMENT: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in statement", + type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in for " + "increment expression", type); + break; + default: + gcc_unreachable (); + } + } if (is_reference || !is_volatile || !is_complete || TREE_ADDRESSABLE (type)) { /* Emit a warning (if enabled) when the "effect-less" INDIRECT_REF @@ -936,7 +1057,7 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) - automatic dereferencing of references, since the user cannot control it. (See also warn_if_unused_value() in stmt.c.) */ if (warn_unused_value - && implicit + && implicit != ICV_CAST && (complain & tf_warning) && !TREE_NO_WARNING (expr) && !is_reference) @@ -954,8 +1075,45 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) int is_complete = COMPLETE_TYPE_P (complete_type (type)); if (TYPE_VOLATILE (type) && !is_complete && (complain & tf_warning)) - warning (0, "object %qE of incomplete type %qT will not be accessed in %s", - expr, type, implicit ? implicit : "void context"); + switch (implicit) + { + case ICV_CAST: + warning (0, "conversion to void will not access " + "object %qE of incomplete type %qT", expr, type); + break; + case ICV_SECOND_OF_COND: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in second operand of " + "conditional expression", expr, type); + break; + case ICV_THIRD_OF_COND: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in third operand of " + "conditional expression", expr, type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in right operand of comma operator", + expr, type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in left operand of comma operator", + expr, type); + break; + case ICV_STATEMENT: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in statement", expr, type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in for increment expression", + expr, type); + break; + default: + gcc_unreachable (); + } + break; } @@ -994,18 +1152,81 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) /* [over.over] enumerates the places where we can take the address of an overloaded function, and this is not one of them. */ if (complain & tf_error) - error ("%s cannot resolve address of overloaded function", - implicit ? implicit : "void cast"); + switch (implicit) + { + case ICV_CAST: + error ("conversion to void " + "cannot resolve address of overloaded function"); + break; + case ICV_SECOND_OF_COND: + error ("second operand of conditional expression " + "cannot resolve address of overloaded function"); + break; + case ICV_THIRD_OF_COND: + error ("third operand of conditional expression " + "cannot resolve address of overloaded function"); + break; + case ICV_RIGHT_OF_COMMA: + error ("right operand of comma operator " + "cannot resolve address of overloaded function"); + break; + case ICV_LEFT_OF_COMMA: + error ("left operand of comma operator " + "cannot resolve address of overloaded function"); + break; + case ICV_STATEMENT: + error ("statement " + "cannot resolve address of overloaded function"); + break; + case ICV_THIRD_IN_FOR: + error ("for increment expression " + "cannot resolve address of overloaded function"); + break; + } else return error_mark_node; expr = void_zero_node; } - else if (implicit && probe == expr && is_overloaded_fn (probe)) + else if (implicit != ICV_CAST && probe == expr && is_overloaded_fn (probe)) { /* Only warn when there is no &. */ if (complain & tf_warning) - warning (OPT_Waddress, "%s is a reference, not call, to function %qE", - implicit, expr); + switch (implicit) + { + case ICV_SECOND_OF_COND: + warning (OPT_Waddress, + "second operand of conditional expression " + "is a reference, not call, to function %qE", expr); + break; + case ICV_THIRD_OF_COND: + warning (OPT_Waddress, + "third operand of conditional expression " + "is a reference, not call, to function %qE", expr); + break; + case ICV_RIGHT_OF_COMMA: + warning (OPT_Waddress, + "right operand of comma operator " + "is a reference, not call, to function %qE", expr); + break; + case ICV_LEFT_OF_COMMA: + warning (OPT_Waddress, + "left operand of comma operator " + "is a reference, not call, to function %qE", expr); + break; + case ICV_STATEMENT: + warning (OPT_Waddress, + "statement is a reference, not call, to function %qE", + expr); + break; + case ICV_THIRD_IN_FOR: + warning (OPT_Waddress, + "for increment expression " + "is a reference, not call, to function %qE", expr); + break; + default: + gcc_unreachable (); + } + if (TREE_CODE (expr) == COMPONENT_REF) expr = TREE_OPERAND (expr, 0); } @@ -1013,7 +1234,7 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr))) { - if (implicit + if (implicit != ICV_CAST && warn_unused_value && !TREE_NO_WARNING (expr) && !processing_template_decl) @@ -1022,7 +1243,35 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) been explicitly cast to void, so we must do so here. */ if (!TREE_SIDE_EFFECTS (expr)) { if (complain & tf_warning) - warning (OPT_Wunused_value, "%s has no effect", implicit); + switch (implicit) + { + case ICV_SECOND_OF_COND: + warning (OPT_Wunused_value, + "second operand of conditional expression has no effect"); + break; + case ICV_THIRD_OF_COND: + warning (OPT_Wunused_value, + "third operand of conditional expression has no effect"); + break; + case ICV_RIGHT_OF_COMMA: + warning (OPT_Wunused_value, + "right operand of comma operator has no effect"); + break; + case ICV_LEFT_OF_COMMA: + warning (OPT_Wunused_value, + "left operand of comma operator has no effect"); + break; + case ICV_STATEMENT: + warning (OPT_Wunused_value, + "statement has no effect"); + break; + case ICV_THIRD_IN_FOR: + warning (OPT_Wunused_value, + "for increment expression has no effect"); + break; + default: + gcc_unreachable (); + } } else { @@ -1127,7 +1376,7 @@ convert_force (tree type, tree expr, int convtype) && TYPE_PTRMEMFUNC_P (type)) /* compatible pointer to member functions. */ return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1, - /*c_cast_p=*/1); + /*c_cast_p=*/1, tf_warning_or_error); return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL); } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 62d3f651ead..73cf2bc58f7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -169,9 +169,9 @@ tree static_aggregates; /* -- end of C++ */ -/* A node for the integer constants 2, and 3. */ +/* A node for the integer constant 2. */ -tree integer_two_node, integer_three_node; +tree integer_two_node; /* Used only for jumps to as-yet undefined labels, since jumps to defined labels can have their validity checked immediately. */ @@ -393,7 +393,7 @@ pop_labels_1 (void **slot, void *data) /* Put the labels into the "variables" of the top-level block, so debugger can see them. */ - TREE_CHAIN (ent->label_decl) = BLOCK_VARS (block); + DECL_CHAIN (ent->label_decl) = BLOCK_VARS (block); BLOCK_VARS (block) = ent->label_decl; htab_clear_slot (named_labels, slot); @@ -474,7 +474,7 @@ poplevel_named_label_1 (void **slot, void *data) { tree decl; - for (decl = ent->names_in_scope; decl; decl = TREE_CHAIN (decl)) + for (decl = ent->names_in_scope; decl; decl = DECL_CHAIN (decl)) if (decl_jump_unsafe (decl)) VEC_safe_push (tree, gc, ent->bad_decls, decl); @@ -749,7 +749,7 @@ poplevel (int keep, int reverse, int functionbody) if (TREE_CODE (*d) == TREE_LIST) *d = TREE_CHAIN (*d); else - d = &TREE_CHAIN (*d); + d = &DECL_CHAIN (*d); } } @@ -822,7 +822,7 @@ walk_namespaces_r (tree name_space, walk_namespaces_fn f, void* data) result |= (*f) (name_space, data); - for (; current; current = TREE_CHAIN (current)) + for (; current; current = DECL_CHAIN (current)) result |= walk_namespaces_r (current, f, data); return result; @@ -1759,7 +1759,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) DECL_ARGUMENTS (old_result) = DECL_ARGUMENTS (new_result); for (parm = DECL_ARGUMENTS (old_result); parm; - parm = TREE_CHAIN (parm)) + parm = DECL_CHAIN (parm)) DECL_CONTEXT (parm) = old_result; } } @@ -2009,7 +2009,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) for (oldarg = DECL_ARGUMENTS(olddecl), newarg = DECL_ARGUMENTS(newdecl); oldarg && newarg; - oldarg = TREE_CHAIN(oldarg), newarg = TREE_CHAIN(newarg)) { + oldarg = DECL_CHAIN(oldarg), newarg = DECL_CHAIN(newarg)) { DECL_ATTRIBUTES (newarg) = (*targetm.merge_decl_attributes) (oldarg, newarg); DECL_ATTRIBUTES (oldarg) = DECL_ATTRIBUTES (newarg); @@ -2073,7 +2073,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) /* Update newdecl's parms to point at olddecl. */ for (parm = DECL_ARGUMENTS (newdecl); parm; - parm = TREE_CHAIN (parm)) + parm = DECL_CHAIN (parm)) DECL_CONTEXT (parm) = olddecl; if (! types_match) @@ -2619,7 +2619,7 @@ check_previous_goto_1 (tree decl, struct cp_binding_level* level, tree names, tree new_decls, old_decls = (b == level ? names : NULL_TREE); for (new_decls = b->names; new_decls != old_decls; - new_decls = TREE_CHAIN (new_decls)) + new_decls = DECL_CHAIN (new_decls)) { int problem = decl_jump_unsafe (new_decls); if (! problem) @@ -3472,7 +3472,6 @@ cxx_init_decl_processing (void) java_boolean_type_node = record_builtin_java_type ("__java_boolean", -1); integer_two_node = build_int_cst (NULL_TREE, 2); - integer_three_node = build_int_cst (NULL_TREE, 3); record_builtin_type (RID_BOOL, "bool", boolean_type_node); truthvalue_type_node = boolean_type_node; @@ -3918,7 +3917,7 @@ fixup_anonymous_aggr (tree t) if (DECL_ARTIFICIAL (*q)) *q = TREE_CHAIN (*q); else - q = &TREE_CHAIN (*q); + q = &DECL_CHAIN (*q); } /* ISO C++ 9.5.3. Anonymous unions may not have function members. */ @@ -3942,7 +3941,7 @@ fixup_anonymous_aggr (tree t) { tree field, type; - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL) { type = TREE_TYPE (field); @@ -4496,7 +4495,8 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup) } if (TREE_CODE (init) == TREE_LIST) - init = build_x_compound_expr_from_list (init, ELK_INIT); + init = build_x_compound_expr_from_list (init, ELK_INIT, + tf_warning_or_error); if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE) @@ -4844,7 +4844,7 @@ next_initializable_field (tree field) && (TREE_CODE (field) != FIELD_DECL || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field)) || DECL_ARTIFICIAL (field))) - field = TREE_CHAIN (field); + field = DECL_CHAIN (field); return field; } @@ -5014,7 +5014,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p) if (TREE_CODE (type) == UNION_TYPE) break; - field = next_initializable_field (TREE_CHAIN (field)); + field = next_initializable_field (DECL_CHAIN (field)); } return new_init; @@ -5717,7 +5717,8 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, return; } if (TREE_CODE (init) == TREE_LIST) - init = build_x_compound_expr_from_list (init, ELK_INIT); + init = build_x_compound_expr_from_list (init, ELK_INIT, + tf_warning_or_error); if (describable_type (init)) { type = TREE_TYPE (decl) = do_auto_deduction (type, init, auto_node); @@ -5871,8 +5872,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, but [cd]tors are never actually compiled directly. We need to put statics on the list so we can deal with the label address extension. */ - cfun->local_decls = tree_cons (NULL_TREE, decl, - cfun->local_decls); + add_local_decl (cfun, decl); } /* Convert the initializer to the type of DECL, if we have not @@ -6810,11 +6810,11 @@ grokfndecl (tree ctype, { tree parm; parm = build_this_parm (type, quals); - TREE_CHAIN (parm) = parms; + DECL_CHAIN (parm) = parms; parms = parm; } DECL_ARGUMENTS (decl) = parms; - for (t = parms; t; t = TREE_CHAIN (t)) + for (t = parms; t; t = DECL_CHAIN (t)) DECL_CONTEXT (t) = decl; /* Propagate volatile out from type to decl. */ if (TYPE_VOLATILE (type)) @@ -7314,7 +7314,7 @@ build_ptrmemfunc_type (tree type) field = build_decl (input_location, FIELD_DECL, delta_identifier, delta_type_node); - TREE_CHAIN (field) = fields; + DECL_CHAIN (field) = fields; fields = field; finish_builtin_struct (t, "__ptrmemfunc_type", fields, ptr_type_node); @@ -9238,7 +9238,7 @@ grokdeclarator (const cp_declarator *declarator, { tree decl = cp_build_parm_decl (NULL_TREE, TREE_VALUE (args)); - TREE_CHAIN (decl) = decls; + DECL_CHAIN (decl) = decls; decls = decl; } @@ -9870,7 +9870,7 @@ grokdeclarator (const cp_declarator *declarator, static void require_complete_types_for_parms (tree parms) { - for (; parms; parms = TREE_CHAIN (parms)) + for (; parms; parms = DECL_CHAIN (parms)) { if (dependent_type_p (TREE_TYPE (parms))) continue; @@ -10140,7 +10140,7 @@ grokparms (tree parmlist, tree *parms) && TREE_CHAIN (parm) != void_list_node) error ("parameter packs must be at the end of the parameter list"); - TREE_CHAIN (decl) = decls; + DECL_CHAIN (decl) = decls; decls = decl; result = tree_cons (init, type, result); } @@ -12151,11 +12151,11 @@ start_preparsed_function (tree decl1, tree attrs, int flags) /* Constructors and destructors need to know whether they're "in charge" of initializing virtual base classes. */ - t = TREE_CHAIN (t); + t = DECL_CHAIN (t); if (DECL_HAS_IN_CHARGE_PARM_P (decl1)) { current_in_charge_parm = t; - t = TREE_CHAIN (t); + t = DECL_CHAIN (t); } if (DECL_HAS_VTT_PARM_P (decl1)) { @@ -12366,7 +12366,7 @@ store_parm_decls (tree current_function_parms) for (parm = specparms; parm; parm = next) { - next = TREE_CHAIN (parm); + next = DECL_CHAIN (parm); if (TREE_CODE (parm) == PARM_DECL) { if (DECL_NAME (parm) == NULL_TREE @@ -12806,7 +12806,7 @@ finish_function (int flags) for (decl = DECL_ARGUMENTS (fndecl); decl; - decl = TREE_CHAIN (decl)) + decl = DECL_CHAIN (decl)) if (TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL && !DECL_READ_P (decl) @@ -12949,7 +12949,7 @@ grokmethod (cp_decl_specifier_seq *declspecs, if (! DECL_FRIEND_P (fndecl)) { - if (TREE_CHAIN (fndecl)) + if (DECL_CHAIN (fndecl)) { fndecl = copy_node (fndecl); TREE_CHAIN (fndecl) = NULL_TREE; @@ -13145,7 +13145,7 @@ revert_static_member_fn (tree decl) error ("static member function %q#D declared with type qualifiers", decl); if (DECL_ARGUMENTS (decl)) - DECL_ARGUMENTS (decl) = TREE_CHAIN (DECL_ARGUMENTS (decl)); + DECL_ARGUMENTS (decl) = DECL_CHAIN (DECL_ARGUMENTS (decl)); DECL_STATIC_FUNCTION_P (decl) = 1; } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index ce54c79f20e..a768877b1a8 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -242,7 +242,7 @@ maybe_retrofit_in_chrg (tree fn) basetype = TREE_TYPE (TREE_VALUE (arg_types)); arg_types = TREE_CHAIN (arg_types); - parms = TREE_CHAIN (DECL_ARGUMENTS (fn)); + parms = DECL_CHAIN (DECL_ARGUMENTS (fn)); /* If this is a subobject constructor or destructor, our caller will pass us a pointer to our VTT. */ @@ -251,7 +251,7 @@ maybe_retrofit_in_chrg (tree fn) parm = build_artificial_parm (vtt_parm_identifier, vtt_parm_type); /* First add it to DECL_ARGUMENTS between 'this' and the real args... */ - TREE_CHAIN (parm) = parms; + DECL_CHAIN (parm) = parms; parms = parm; /* ...and then to TYPE_ARG_TYPES. */ @@ -262,12 +262,12 @@ maybe_retrofit_in_chrg (tree fn) /* Then add the in-charge parm (before the VTT parm). */ parm = build_artificial_parm (in_charge_identifier, integer_type_node); - TREE_CHAIN (parm) = parms; + DECL_CHAIN (parm) = parms; parms = parm; arg_types = hash_tree_chain (integer_type_node, arg_types); /* Insert our new parameter(s) into the list. */ - TREE_CHAIN (DECL_ARGUMENTS (fn)) = parms; + DECL_CHAIN (DECL_ARGUMENTS (fn)) = parms; /* And rebuild the function type. */ fntype = build_method_type_directly (basetype, TREE_TYPE (TREE_TYPE (fn)), @@ -1321,7 +1321,7 @@ build_anon_union_vars (tree type, tree object) for (field = TYPE_FIELDS (type); field != NULL_TREE; - field = TREE_CHAIN (field)) + field = DECL_CHAIN (field)) { tree decl; tree ref; @@ -1826,7 +1826,7 @@ maybe_emit_vtables (tree ctype) determine_key_method (ctype); /* See if any of the vtables are needed. */ - for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl)) + for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = DECL_CHAIN (vtbl)) { import_export_decl (vtbl); if (DECL_NOT_REALLY_EXTERN (vtbl) && decl_needed_p (vtbl)) @@ -1845,7 +1845,7 @@ maybe_emit_vtables (tree ctype) /* The ABI requires that we emit all of the vtables if we emit any of them. */ - for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl)) + for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = DECL_CHAIN (vtbl)) { /* Mark entities references from the virtual table as used. */ mark_vtable_entries (vtbl); @@ -2242,7 +2242,7 @@ constrain_class_visibility (tree type) if (CLASSTYPE_VISIBILITY_SPECIFIED (type)) vis = VISIBILITY_INTERNAL; - for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t)) + for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t)) if (TREE_CODE (t) == FIELD_DECL && TREE_TYPE (t) != error_mark_node) { tree ftype = strip_pointer_or_array_types (TREE_TYPE (t)); @@ -2868,7 +2868,7 @@ start_static_storage_duration_function (unsigned count) DECL_CONTEXT (priority_decl) = ssdf_decl; TREE_USED (priority_decl) = 1; - TREE_CHAIN (initialize_p_decl) = priority_decl; + DECL_CHAIN (initialize_p_decl) = priority_decl; DECL_ARGUMENTS (ssdf_decl) = initialize_p_decl; /* Put the function in the global scope. */ @@ -2966,7 +2966,7 @@ fix_temporary_vars_context_r (tree *node, { tree var; - for (var = BIND_EXPR_VARS (*node); var; var = TREE_CHAIN (var)) + for (var = BIND_EXPR_VARS (*node); var; var = DECL_CHAIN (var)) if (TREE_CODE (var) == VAR_DECL && !DECL_NAME (var) && DECL_ARTIFICIAL (var) diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 1902a135b89..cff822a55c1 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1247,7 +1247,7 @@ dump_function_decl (tree t, int flags) tree exceptions; VEC(tree,gc) *typenames = NULL; - if (LAMBDA_FUNCTION_P (t)) + if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t)) { /* A lambda's signature is essentially its "type", so defer. */ gcc_assert (LAMBDA_TYPE_P (DECL_CONTEXT (t))); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 85ad582f2d1..d796fd0822c 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -184,7 +184,7 @@ build_zero_init (tree type, tree nelts, bool static_storage_p) VEC(constructor_elt,gc) *v = NULL; /* Iterate over the fields, building initializations. */ - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { if (TREE_CODE (field) != FIELD_DECL) continue; @@ -337,7 +337,7 @@ build_value_init_noctor (tree type) VEC(constructor_elt,gc) *v = NULL; /* Iterate over the fields, building initializations. */ - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { tree ftype, value; @@ -525,7 +525,8 @@ perform_member_init (tree member, tree init) else if (TREE_CODE (init) == TREE_LIST) /* There was an explicit member initialization. Do some work in that case. */ - init = build_x_compound_expr_from_list (init, ELK_MEM_INIT); + init = build_x_compound_expr_from_list (init, ELK_MEM_INIT, + tf_warning_or_error); if (init) finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init, @@ -562,27 +563,29 @@ build_field_list (tree t, tree list, int *uses_unions_p) if (TREE_CODE (t) == UNION_TYPE) *uses_unions_p = 1; - for (fields = TYPE_FIELDS (t); fields; fields = TREE_CHAIN (fields)) + for (fields = TYPE_FIELDS (t); fields; fields = DECL_CHAIN (fields)) { + tree fieldtype; + /* Skip CONST_DECLs for enumeration constants and so forth. */ if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields)) continue; + fieldtype = TREE_TYPE (fields); /* Keep track of whether or not any fields are unions. */ - if (TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE) + if (TREE_CODE (fieldtype) == UNION_TYPE) *uses_unions_p = 1; /* For an anonymous struct or union, we must recursively consider the fields of the anonymous type. They can be directly initialized from the constructor. */ - if (ANON_AGGR_TYPE_P (TREE_TYPE (fields))) + if (ANON_AGGR_TYPE_P (fieldtype)) { /* Add this field itself. Synthesized copy constructors initialize the entire aggregate. */ list = tree_cons (fields, NULL_TREE, list); /* And now add the fields in the anonymous aggregate. */ - list = build_field_list (TREE_TYPE (fields), list, - uses_unions_p); + list = build_field_list (fieldtype, list, uses_unions_p); } /* Add this field. */ else if (DECL_NAME (fields)) @@ -708,38 +711,54 @@ sort_mem_initializers (tree t, tree mem_inits) If a ctor-initializer specifies more than one mem-initializer for multiple members of the same union (including members of - anonymous unions), the ctor-initializer is ill-formed. */ + anonymous unions), the ctor-initializer is ill-formed. + + Here we also splice out uninitialized union members. */ if (uses_unions_p) { tree last_field = NULL_TREE; - for (init = sorted_inits; init; init = TREE_CHAIN (init)) + tree *p; + for (p = &sorted_inits; *p; ) { tree field; - tree field_type; + tree ctx; int done; - /* Skip uninitialized members and base classes. */ - if (!TREE_VALUE (init) - || TREE_CODE (TREE_PURPOSE (init)) != FIELD_DECL) - continue; + init = *p; + + field = TREE_PURPOSE (init); + + /* Skip base classes. */ + if (TREE_CODE (field) != FIELD_DECL) + goto next; + + /* If this is an anonymous union with no explicit initializer, + splice it out. */ + if (!TREE_VALUE (init) && ANON_UNION_TYPE_P (TREE_TYPE (field))) + goto splice; + /* See if this field is a member of a union, or a member of a structure contained in a union, etc. */ - field = TREE_PURPOSE (init); - for (field_type = DECL_CONTEXT (field); - !same_type_p (field_type, t); - field_type = TYPE_CONTEXT (field_type)) - if (TREE_CODE (field_type) == UNION_TYPE) + for (ctx = DECL_CONTEXT (field); + !same_type_p (ctx, t); + ctx = TYPE_CONTEXT (ctx)) + if (TREE_CODE (ctx) == UNION_TYPE) break; /* If this field is not a member of a union, skip it. */ - if (TREE_CODE (field_type) != UNION_TYPE) - continue; + if (TREE_CODE (ctx) != UNION_TYPE) + goto next; + + /* If this union member has no explicit initializer, splice + it out. */ + if (!TREE_VALUE (init)) + goto splice; /* It's only an error if we have two initializers for the same union type. */ if (!last_field) { last_field = field; - continue; + goto next; } /* See if LAST_FIELD and the field initialized by INIT are @@ -750,41 +769,48 @@ sort_mem_initializers (tree t, tree mem_inits) union { struct { int i; int j; }; }; initializing both `i' and `j' makes sense. */ - field_type = DECL_CONTEXT (field); + ctx = DECL_CONTEXT (field); done = 0; do { - tree last_field_type; + tree last_ctx; - last_field_type = DECL_CONTEXT (last_field); + last_ctx = DECL_CONTEXT (last_field); while (1) { - if (same_type_p (last_field_type, field_type)) + if (same_type_p (last_ctx, ctx)) { - if (TREE_CODE (field_type) == UNION_TYPE) + if (TREE_CODE (ctx) == UNION_TYPE) error_at (DECL_SOURCE_LOCATION (current_function_decl), "initializations for multiple members of %qT", - last_field_type); + last_ctx); done = 1; break; } - if (same_type_p (last_field_type, t)) + if (same_type_p (last_ctx, t)) break; - last_field_type = TYPE_CONTEXT (last_field_type); + last_ctx = TYPE_CONTEXT (last_ctx); } /* If we've reached the outermost class, then we're done. */ - if (same_type_p (field_type, t)) + if (same_type_p (ctx, t)) break; - field_type = TYPE_CONTEXT (field_type); + ctx = TYPE_CONTEXT (ctx); } while (!done); last_field = field; + + next: + p = &TREE_CHAIN (*p); + continue; + splice: + *p = TREE_CHAIN (*p); + continue; } } @@ -1005,7 +1031,7 @@ construct_virtual_base (tree vbase, tree arguments) in the outer block.) We trust the back end to figure out that the FLAG will not change across initializations, and avoid doing multiple tests. */ - flag = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)); + flag = DECL_CHAIN (DECL_ARGUMENTS (current_function_decl)); inner_if_stmt = begin_if_stmt (); finish_if_stmt_cond (flag, inner_if_stmt); @@ -1374,7 +1400,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags, release_tree_vector (parms); if (TREE_SIDE_EFFECTS (rval)) - finish_expr_stmt (convert_to_void (rval, NULL, complain)); + finish_expr_stmt (convert_to_void (rval, ICV_CAST, complain)); } /* This function is responsible for initializing EXP with INIT @@ -1507,18 +1533,9 @@ build_offset_ref (tree type, tree member, bool address_p) if (TREE_CODE (member) == TEMPLATE_DECL) return member; - if (dependent_type_p (type) || type_dependent_expression_p (member)) - { - tree ref, mem_type = NULL_TREE; - if (!dependent_scope_p (type)) - mem_type = TREE_TYPE (member); - ref = build_qualified_name (mem_type, type, member, + if (dependent_scope_p (type) || type_dependent_expression_p (member)) + return build_qualified_name (NULL_TREE, type, member, /*template_p=*/false); - /* Undo convert_from_reference. */ - if (TREE_CODE (ref) == INDIRECT_REF) - ref = TREE_OPERAND (ref, 0); - return ref; - } gcc_assert (TYPE_P (type)); if (! is_class_type (type, 1)) @@ -1528,6 +1545,7 @@ build_offset_ref (tree type, tree member, bool address_p) /* Callers should call mark_used before this point. */ gcc_assert (!DECL_P (member) || TREE_USED (member)); + type = TYPE_MAIN_VARIANT (type); if (!COMPLETE_OR_OPEN_TYPE_P (complete_type (type))) { error ("incomplete type %qT does not have member %qD", type, member); @@ -1798,7 +1816,7 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, if (type_has_user_provided_constructor (type)) return 0; - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { tree field_type; @@ -2016,10 +2034,8 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, } alloc_fn = OVL_CURRENT (alloc_fn); class_addr = build1 (ADDR_EXPR, jclass_node, class_decl); - alloc_call = (cp_build_function_call - (alloc_fn, - build_tree_list (NULL_TREE, class_addr), - complain)); + alloc_call = cp_build_function_call_nary (alloc_fn, complain, + class_addr, NULL_TREE); } else if (TYPE_FOR_JAVA (elt_type) && MAYBE_CLASS_TYPE_P (elt_type)) { @@ -2561,7 +2577,7 @@ build_java_class_ref (tree type) /* Mangle the class$ field. */ { tree field; - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (DECL_NAME (field) == CL_suffix) { mangle_decl (field); @@ -2726,7 +2742,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type, /* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR. */ body = build2 (COMPOUND_EXPR, void_type_node, base, body); - return convert_to_void (body, /*implicit=*/NULL, tf_warning_or_error); + return convert_to_void (body, ICV_CAST, tf_warning_or_error); } /* Create an unnamed variable of the indicated TYPE. */ @@ -3361,21 +3377,27 @@ push_base_cleanups (void) finish_decl_cleanup (NULL_TREE, expr); } + /* Don't automatically destroy union members. */ + if (TREE_CODE (current_class_type) == UNION_TYPE) + return; + for (member = TYPE_FIELDS (current_class_type); member; - member = TREE_CHAIN (member)) + member = DECL_CHAIN (member)) { - if (TREE_TYPE (member) == error_mark_node + tree this_type = TREE_TYPE (member); + if (this_type == error_mark_node || TREE_CODE (member) != FIELD_DECL || DECL_ARTIFICIAL (member)) continue; - if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (member))) + if (ANON_UNION_TYPE_P (this_type)) + continue; + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (this_type)) { tree this_member = (build_class_member_access_expr (current_class_ref, member, /*access_path=*/NULL_TREE, /*preserve_reference=*/false, tf_warning_or_error)); - tree this_type = TREE_TYPE (member); expr = build_delete (this_type, this_member, sfk_complete_destructor, LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL, diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index e8259521adb..a47dfa8babf 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -346,11 +346,19 @@ canonicalize_for_substitution (tree node) if (TYPE_P (node) && TYPE_CANONICAL (node) != node && TYPE_MAIN_VARIANT (node) != node) + { /* Here we want to strip the topmost typedef only. We need to do that so is_std_substitution can do proper name matching. */ - node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node), - cp_type_quals (node)); + if (TREE_CODE (node) == FUNCTION_TYPE) + /* Use build_qualified_type and TYPE_QUALS here to preserve + the old buggy mangling of attribute noreturn with abi<5. */ + node = build_qualified_type (TYPE_MAIN_VARIANT (node), + TYPE_QUALS (node)); + else + node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node), + cp_type_quals (node)); + } return node; } @@ -1281,7 +1289,7 @@ nested_anon_class_index (tree type) { int index = 0; tree member = TYPE_FIELDS (TYPE_CONTEXT (type)); - for (; member; member = TREE_CHAIN (member)) + for (; member; member = DECL_CHAIN (member)) if (DECL_IMPLICIT_TYPEDEF_P (member)) { tree memtype = TREE_TYPE (member); @@ -1711,7 +1719,7 @@ write_local_name (tree function, const tree local_entity, { tree t; int i = 0; - for (t = DECL_ARGUMENTS (function); t; t = TREE_CHAIN (t)) + for (t = DECL_ARGUMENTS (function); t; t = DECL_CHAIN (t)) { if (t == parm) i = 1; @@ -1776,6 +1784,7 @@ write_type (tree type) if (type == error_mark_node) return; + type = canonicalize_for_substitution (type); if (find_substitution (type)) return; @@ -1978,6 +1987,12 @@ write_CV_qualifiers_for_type (const tree type) array. */ cp_cv_quals quals = TYPE_QUALS (type); + /* Attribute const/noreturn are not reflected in mangling. */ + if (abi_version_at_least (5) + && (TREE_CODE (type) == FUNCTION_TYPE + || TREE_CODE (type) == METHOD_TYPE)) + return 0; + if (quals & TYPE_QUAL_RESTRICT) { write_char ('r'); @@ -2288,12 +2303,12 @@ write_method_parms (tree parm_types, const int method_p, const tree decl) if (method_p) { parm_types = TREE_CHAIN (parm_types); - parm_decl = parm_decl ? TREE_CHAIN (parm_decl) : NULL_TREE; + parm_decl = parm_decl ? DECL_CHAIN (parm_decl) : NULL_TREE; while (parm_decl && DECL_ARTIFICIAL (parm_decl)) { parm_types = TREE_CHAIN (parm_types); - parm_decl = TREE_CHAIN (parm_decl); + parm_decl = DECL_CHAIN (parm_decl); } } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index ad41e9acc57..b9511f5a628 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -103,7 +103,7 @@ make_thunk (tree function, bool this_adjusting, /* See if we already have the thunk in question. For this_adjusting thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it will be a BINFO. */ - for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk)) + for (thunk = DECL_THUNKS (function); thunk; thunk = DECL_CHAIN (thunk)) if (DECL_THIS_THUNK_P (thunk) == this_adjusting && THUNK_FIXED_OFFSET (thunk) == d && !virtual_offset == !THUNK_VIRTUAL_OFFSET (thunk) @@ -156,7 +156,7 @@ make_thunk (tree function, bool this_adjusting, DECL_TEMPLATE_INFO (thunk) = NULL; /* Add it to the list of thunks associated with FUNCTION. */ - TREE_CHAIN (thunk) = DECL_THUNKS (function); + DECL_CHAIN (thunk) = DECL_THUNKS (function); DECL_THUNKS (function) = thunk; return thunk; @@ -188,7 +188,7 @@ finish_thunk (tree thunk) tree cov_probe; for (cov_probe = DECL_THUNKS (function); - cov_probe; cov_probe = TREE_CHAIN (cov_probe)) + cov_probe; cov_probe = DECL_CHAIN (cov_probe)) if (DECL_NAME (cov_probe) == name) { gcc_assert (!DECL_THUNKS (thunk)); @@ -364,10 +364,10 @@ use_thunk (tree thunk_fndecl, bool emit_p) /* Set up cloned argument trees for the thunk. */ t = NULL_TREE; - for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a)) + for (a = DECL_ARGUMENTS (function); a; a = DECL_CHAIN (a)) { tree x = copy_node (a); - TREE_CHAIN (x) = t; + DECL_CHAIN (x) = t; DECL_CONTEXT (x) = thunk_fndecl; SET_DECL_RTL (x, NULL); DECL_HAS_VALUE_EXPR_P (x) = 0; @@ -529,7 +529,7 @@ do_build_copy_constructor (tree fndecl) member_init_list); } - for (; fields; fields = TREE_CHAIN (fields)) + for (; fields; fields = DECL_CHAIN (fields)) { tree field = fields; tree expr_type; @@ -545,7 +545,8 @@ do_build_copy_constructor (tree fndecl) } 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. */; + nontrivial copy ctors or assignment ops or this + function would be deleted. */; else continue; @@ -578,7 +579,7 @@ do_build_copy_constructor (tree fndecl) static void do_build_copy_assign (tree fndecl) { - tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); + tree parm = DECL_CHAIN (DECL_ARGUMENTS (fndecl)); tree compound_stmt; bool move_p = move_fn_p (fndecl); bool trivial = trivial_fn_p (fndecl); @@ -629,7 +630,7 @@ do_build_copy_assign (tree fndecl) /* Assign to each of the non-static data members. */ for (fields = TYPE_FIELDS (current_class_type); fields; - fields = TREE_CHAIN (fields)) + fields = DECL_CHAIN (fields)) { tree comp = current_class_ref; tree init = parm; @@ -663,7 +664,8 @@ do_build_copy_assign (tree fndecl) else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type) != NULL_TREE) /* Just use the field; anonymous types can't have - nontrivial copy ctors or assignment ops. */; + nontrivial copy ctors or assignment ops or this + function would be deleted. */; else continue; @@ -912,8 +914,19 @@ process_subob_fn (tree fn, bool move_p, tree *spec_p, bool *trivial_p, *spec_p = merge_exception_specifiers (*spec_p, raises); } - if (trivial_p && !trivial_fn_p (fn)) - *trivial_p = false; + if (!trivial_fn_p (fn)) + { + if (trivial_p) + *trivial_p = false; + if (TREE_CODE (arg) == FIELD_DECL + && TREE_CODE (DECL_CONTEXT (arg)) == UNION_TYPE) + { + if (deleted_p) + *deleted_p = true; + if (msg) + error ("union member %q+D with non-trivial %qD", arg, fn); + } + } if (move_p && !move_fn_p (fn) && !trivial_fn_p (fn)) { @@ -929,6 +942,99 @@ process_subob_fn (tree fn, bool move_p, tree *spec_p, bool *trivial_p, *deleted_p = true; } +/* Subroutine of synthesized_method_walk to allow recursion into anonymous + aggregates. */ + +static void +walk_field_subobs (tree fields, tree fnname, special_function_kind sfk, + int quals, bool copy_arg_p, bool move_p, + bool assign_p, tree *spec_p, bool *trivial_p, + bool *deleted_p, const char *msg, + int flags, tsubst_flags_t complain) +{ + tree field; + for (field = fields; field; field = DECL_CHAIN (field)) + { + tree mem_type, argtype, rval; + + if (TREE_CODE (field) != FIELD_DECL + || DECL_ARTIFICIAL (field)) + continue; + + mem_type = strip_array_types (TREE_TYPE (field)); + if (assign_p) + { + bool bad = true; + if (CP_TYPE_CONST_P (mem_type) && !CLASS_TYPE_P (mem_type)) + { + if (msg) + error ("non-static const member %q#D, can't use default " + "assignment operator", field); + } + else if (TREE_CODE (mem_type) == REFERENCE_TYPE) + { + if (msg) + error ("non-static reference member %q#D, can't use " + "default assignment operator", field); + } + else + bad = false; + + if (bad && deleted_p) + *deleted_p = true; + } + else if (sfk == sfk_constructor) + { + bool bad = true; + if (CP_TYPE_CONST_P (mem_type) + && (!CLASS_TYPE_P (mem_type) + || !type_has_user_provided_default_constructor (mem_type))) + { + if (msg) + error ("uninitialized non-static const member %q#D", + field); + } + else if (TREE_CODE (mem_type) == REFERENCE_TYPE) + { + if (msg) + error ("uninitialized non-static reference member %q#D", + field); + } + else + bad = false; + + if (bad && deleted_p) + *deleted_p = true; + } + + if (!CLASS_TYPE_P (mem_type)) + continue; + + if (ANON_AGGR_TYPE_P (mem_type)) + { + walk_field_subobs (TYPE_FIELDS (mem_type), fnname, sfk, quals, + copy_arg_p, move_p, assign_p, spec_p, trivial_p, + deleted_p, msg, flags, complain); + continue; + } + + if (copy_arg_p) + { + int mem_quals = cp_type_quals (mem_type) | quals; + if (DECL_MUTABLE_P (field)) + mem_quals &= ~TYPE_QUAL_CONST; + argtype = build_stub_type (mem_type, mem_quals, move_p); + } + else + argtype = NULL_TREE; + + rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain); + + process_subob_fn (rval, move_p, spec_p, trivial_p, deleted_p, + msg, field); + } +} + /* The caller wants to generate an implicit declaration of SFK for CTYPE which is const if relevant and CONST_P is set. If spec_p, trivial_p and deleted_p are non-null, set their referent appropriately. If diag is @@ -940,7 +1046,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, tree *spec_p, bool *trivial_p, bool *deleted_p, bool diag) { - tree binfo, base_binfo, field, scope, fnname, rval, argtype; + tree binfo, base_binfo, scope, fnname, rval, argtype; bool move_p, copy_arg_p, assign_p, expected_trivial, check_vdtor; VEC(tree,gc) *vbases; int i, quals, flags; @@ -1004,6 +1110,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, #endif assign_p = false; + check_vdtor = false; switch (sfk) { case sfk_move_assignment: @@ -1051,6 +1158,15 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, quals = TYPE_UNQUALIFIED; argtype = NULL_TREE; + if (!diag) + msg = NULL; + else if (assign_p) + msg = ("base %qT does not have a move assignment operator or trivial " + "copy assignment operator"); + else + msg = ("base %qT does not have a move constructor or trivial " + "copy constructor"); + for (binfo = TYPE_BINFO (ctype), i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) { @@ -1059,15 +1175,6 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, argtype = build_stub_type (basetype, quals, move_p); rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain); - if (!diag) - msg = NULL; - else if (assign_p) - msg = ("base %qT does not have a move assignment operator or trivial " - "copy assignment operator"); - else - msg = ("base %qT does not have a move constructor or trivial " - "copy constructor"); - process_subob_fn (rval, move_p, spec_p, trivial_p, deleted_p, msg, BINFO_TYPE (base_binfo)); @@ -1093,105 +1200,31 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, *deleted_p = true; } else if (!assign_p) - for (i = 0; VEC_iterate (tree, vbases, i, base_binfo); ++i) - { - if (copy_arg_p) - argtype = build_stub_type (BINFO_TYPE (base_binfo), quals, move_p); - rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain); - - if (!diag) - msg = NULL; - else if (assign_p) - msg = ("virtual base %qT does not have a move assignment " - "operator or trivial copy assignment operator"); - else - msg = ("virtual base %qT does not have a move constructor " - "or trivial copy constructor"); - - process_subob_fn (rval, move_p, spec_p, trivial_p, deleted_p, - msg, BINFO_TYPE (base_binfo)); - } - - for (field = TYPE_FIELDS (ctype); field; field = TREE_CHAIN (field)) { - tree mem_type; - - if (TREE_CODE (field) != FIELD_DECL - || DECL_ARTIFICIAL (field)) - continue; - - mem_type = strip_array_types (TREE_TYPE (field)); - if (assign_p) + if (diag) + msg = ("virtual base %qT does not have a move constructor " + "or trivial copy constructor"); + for (i = 0; VEC_iterate (tree, vbases, i, base_binfo); ++i) { - bool bad = true; - if (CP_TYPE_CONST_P (mem_type) && !CLASS_TYPE_P (mem_type)) - { - if (diag) - error ("non-static const member %q#D, can't use default " - "assignment operator", field); - } - else if (TREE_CODE (mem_type) == REFERENCE_TYPE) - { - if (diag) - error ("non-static reference member %q#D, can't use " - "default assignment operator", field); - } - else - bad = false; + if (copy_arg_p) + argtype = build_stub_type (BINFO_TYPE (base_binfo), quals, move_p); + rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain); - if (bad && deleted_p) - *deleted_p = true; + process_subob_fn (rval, move_p, spec_p, trivial_p, deleted_p, + msg, BINFO_TYPE (base_binfo)); } - else if (sfk == sfk_constructor) - { - bool bad = true; - if (CP_TYPE_CONST_P (mem_type) - && (!CLASS_TYPE_P (mem_type) - || !type_has_user_provided_default_constructor (mem_type))) - { - if (diag) - error ("uninitialized non-static const member %q#D", - field); - } - else if (TREE_CODE (mem_type) == REFERENCE_TYPE) - { - if (diag) - error ("uninitialized non-static reference member %q#D", - field); - } - else - bad = false; - - if (bad && deleted_p) - *deleted_p = true; - } - - if (!CLASS_TYPE_P (mem_type) - || ANON_AGGR_TYPE_P (mem_type)) - continue; - - if (copy_arg_p) - { - int mem_quals = cp_type_quals (mem_type) | quals; - if (DECL_MUTABLE_P (field)) - mem_quals &= ~TYPE_QUAL_CONST; - argtype = build_stub_type (mem_type, mem_quals, move_p); - } - - rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain); - - if (!diag) - msg = NULL; - else if (assign_p) - msg = ("non-static data member %qD does not have a move " - "assignment operator or trivial copy assignment operator"); - else - msg = ("non-static data member %qD does not have a move " - "constructor or trivial copy constructor"); - - process_subob_fn (rval, move_p, spec_p, trivial_p, deleted_p, - msg, field); } + if (!diag) + /* Leave msg null. */; + else if (assign_p) + msg = ("non-static data member %qD does not have a move " + "assignment operator or trivial copy assignment operator"); + else + msg = ("non-static data member %qD does not have a move " + "constructor or trivial copy constructor"); + walk_field_subobs (TYPE_FIELDS (ctype), fnname, sfk, quals, + copy_arg_p, move_p, assign_p, spec_p, trivial_p, + deleted_p, msg, flags, complain); pop_scope (scope); @@ -1399,7 +1432,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) } /* Add the "this" parameter. */ this_parm = build_this_parm (fn_type, TYPE_UNQUALIFIED); - TREE_CHAIN (this_parm) = DECL_ARGUMENTS (fn); + DECL_CHAIN (this_parm) = DECL_ARGUMENTS (fn); DECL_ARGUMENTS (fn) = this_parm; grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL); @@ -1592,7 +1625,7 @@ lazily_declare_fn (special_function_kind sfk, tree type) "and may change in a future version of GCC due to " "implicit virtual destructor", type); - TREE_CHAIN (fn) = TYPE_METHODS (type); + DECL_CHAIN (fn) = TYPE_METHODS (type); TYPE_METHODS (type) = fn; } maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 67131190305..c6e31c29445 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -542,7 +542,7 @@ add_decl_to_level (tree decl, cxx_scope *b) if (TREE_CODE (decl) == NAMESPACE_DECL && !DECL_NAMESPACE_ALIAS (decl)) { - TREE_CHAIN (decl) = b->namespaces; + DECL_CHAIN (decl) = b->namespaces; b->namespaces = decl; } else @@ -1017,10 +1017,22 @@ pushdecl_maybe_friend (tree x, bool is_friend) /* Inline decls shadow nothing. */ && !DECL_FROM_INLINE (x) && (TREE_CODE (oldlocal) == PARM_DECL - || TREE_CODE (oldlocal) == VAR_DECL) - /* Don't check the `this' parameter. */ - && !DECL_ARTIFICIAL (oldlocal) - && !DECL_ARTIFICIAL (x)) + || TREE_CODE (oldlocal) == VAR_DECL + /* If the old decl is a type decl, only warn if the + old decl is an explicit typedef or if both the old + and new decls are type decls. */ + || (TREE_CODE (oldlocal) == TYPE_DECL + && (!DECL_ARTIFICIAL (oldlocal) + || TREE_CODE (x) == TYPE_DECL))) + /* Don't check the `this' parameter or internally generated + vars unless it's an implicit typedef (see + create_implicit_typedef in decl.c). */ + && (!DECL_ARTIFICIAL (oldlocal) + || DECL_IMPLICIT_TYPEDEF_P (oldlocal)) + /* Don't check for internally generated vars unless + it's an implicit typedef (see create_implicit_typedef + in decl.c). */ + && (!DECL_ARTIFICIAL (x) || DECL_IMPLICIT_TYPEDEF_P (x))) { bool nowarn = false; @@ -1081,10 +1093,12 @@ pushdecl_maybe_friend (tree x, bool is_friend) /* Maybe warn if shadowing something else. */ else if (warn_shadow && !DECL_EXTERNAL (x) - /* No shadow warnings for internally generated vars. */ - && ! DECL_ARTIFICIAL (x) - /* No shadow warnings for vars made for inlining. */ - && ! DECL_FROM_INLINE (x)) + /* No shadow warnings for internally generated vars unless + it's an implicit typedef (see create_implicit_typedef + in decl.c). */ + && (! DECL_ARTIFICIAL (x) || DECL_IMPLICIT_TYPEDEF_P (x)) + /* No shadow warnings for vars made for inlining. */ + && ! DECL_FROM_INLINE (x)) { tree member; @@ -1103,7 +1117,13 @@ pushdecl_maybe_friend (tree x, bool is_friend) x); } else if (oldglobal != NULL_TREE - && TREE_CODE (oldglobal) == VAR_DECL) + && (TREE_CODE (oldglobal) == VAR_DECL + /* If the old decl is a type decl, only warn if the + old decl is an explicit typedef or if both the + old and new decls are type decls. */ + || (TREE_CODE (oldglobal) == TYPE_DECL + && (!DECL_ARTIFICIAL (oldglobal) + || TREE_CODE (x) == TYPE_DECL)))) /* XXX shadow warnings in outer-more namespaces */ { warning_at (input_location, OPT_Wshadow, @@ -1973,7 +1993,7 @@ push_using_decl (tree scope, tree name) timevar_push (TV_NAME_LOOKUP); gcc_assert (TREE_CODE (scope) == NAMESPACE_DECL); gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); - for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl)) + for (decl = current_binding_level->usings; decl; decl = DECL_CHAIN (decl)) if (USING_DECL_SCOPE (decl) == scope && DECL_NAME (decl) == name) break; if (decl) @@ -1981,7 +2001,7 @@ push_using_decl (tree scope, tree name) namespace_bindings_p () ? decl : NULL_TREE); decl = build_lang_decl (USING_DECL, name, NULL_TREE); USING_DECL_SCOPE (decl) = scope; - TREE_CHAIN (decl) = current_binding_level->usings; + DECL_CHAIN (decl) = current_binding_level->usings; current_binding_level->usings = decl; POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); } @@ -2137,7 +2157,7 @@ push_overloaded_decl (tree decl, int flags, bool is_friend) for (d = &IDENTIFIER_BINDING (name)->scope->names; *d; - d = &TREE_CHAIN (*d)) + d = &DECL_CHAIN (*d)) if (*d == old || (TREE_CODE (*d) == TREE_LIST && TREE_VALUE (*d) == old)) @@ -2148,7 +2168,7 @@ push_overloaded_decl (tree decl, int flags, bool is_friend) else /* Build a TREE_LIST to wrap the OVERLOAD. */ *d = tree_cons (NULL_TREE, new_binding, - TREE_CHAIN (*d)); + DECL_CHAIN (*d)); /* And update the cxx_binding node. */ IDENTIFIER_BINDING (name)->value = new_binding; @@ -2706,7 +2726,7 @@ pushdecl_class_level (tree x) aggregate, for naming purposes. */ tree f; - for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f)) + for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = DECL_CHAIN (f)) { location_t save_location = input_location; input_location = DECL_SOURCE_LOCATION (f); diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index 0196eaeb8b1..302a1332d66 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -107,12 +107,11 @@ clone_body (tree clone, tree fn, void *arg_map) if (DECL_NAME (clone) == base_dtor_identifier || DECL_NAME (clone) == base_ctor_identifier) { - tree decls = DECL_STRUCT_FUNCTION (fn)->local_decls; - for (; decls; decls = TREE_CHAIN (decls)) - { - tree decl = TREE_VALUE (decls); - walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL); - } + unsigned ix; + tree decl; + + FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl) + walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL); } append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone)); @@ -283,16 +282,16 @@ maybe_clone_body (tree fn) clone_parm = DECL_ARGUMENTS (clone); /* Update the `this' parameter, which is always first. */ update_cloned_parm (parm, clone_parm, first); - parm = TREE_CHAIN (parm); - clone_parm = TREE_CHAIN (clone_parm); + parm = DECL_CHAIN (parm); + clone_parm = DECL_CHAIN (clone_parm); if (DECL_HAS_IN_CHARGE_PARM_P (fn)) - parm = TREE_CHAIN (parm); + parm = DECL_CHAIN (parm); if (DECL_HAS_VTT_PARM_P (fn)) - parm = TREE_CHAIN (parm); + parm = DECL_CHAIN (parm); if (DECL_HAS_VTT_PARM_P (clone)) - clone_parm = TREE_CHAIN (clone_parm); + clone_parm = DECL_CHAIN (clone_parm); for (; parm; - parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm)) + parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm)) /* Update this parameter. */ update_cloned_parm (parm, clone_parm, first); @@ -349,7 +348,7 @@ maybe_clone_body (tree fn) clone_parm = DECL_ARGUMENTS (clone); parm; ++parmno, - parm = TREE_CHAIN (parm)) + parm = DECL_CHAIN (parm)) { /* Map the in-charge parameter to an appropriate constant. */ if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1) @@ -368,7 +367,7 @@ maybe_clone_body (tree fn) { DECL_ABSTRACT_ORIGIN (clone_parm) = parm; *pointer_map_insert (decl_map, parm) = clone_parm; - clone_parm = TREE_CHAIN (clone_parm); + clone_parm = DECL_CHAIN (clone_parm); } /* Otherwise, map the VTT parameter to `NULL'. */ else @@ -380,7 +379,7 @@ maybe_clone_body (tree fn) else { *pointer_map_insert (decl_map, parm) = clone_parm; - clone_parm = TREE_CHAIN (clone_parm); + clone_parm = DECL_CHAIN (clone_parm); } } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e8f10a4d000..3fd96fbe06e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2650,7 +2650,7 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, base_type = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (base_type); for (field = TYPE_FIELDS (base_type); field; - field = TREE_CHAIN (field)) + field = DECL_CHAIN (field)) if (TREE_CODE (field) == TYPE_DECL && DECL_NAME (field) == id) { @@ -3754,6 +3754,16 @@ cp_parser_primary_expression (cp_parser *parser, case RID_AT_SELECTOR: return cp_parser_objc_expression (parser); + case RID_TEMPLATE: + if (parser->in_function_body + && (cp_lexer_peek_nth_token (parser->lexer, 2)->type + == CPP_LESS)) + { + error_at (token->location, + "a template declaration cannot appear at block scope"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return error_mark_node; + } default: cp_parser_error (parser, "expected primary-expression"); return error_mark_node; @@ -7696,7 +7706,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) /* The function parameters must be in scope all the way until after the trailing-return-type in case of decltype. */ - for (t = current_binding_level->names; t; t = TREE_CHAIN (t)) + for (t = current_binding_level->names; t; t = DECL_CHAIN (t)) pop_binding (DECL_NAME (t), t); leave_scope (); @@ -14079,7 +14089,7 @@ cp_parser_init_declarator (cp_parser* parser, `explicit' constructor is OK. Otherwise, an `explicit' constructor cannot be used. */ ((is_direct_init || !is_initialized) - ? 0 : LOOKUP_ONLYCONVERTING)); + ? LOOKUP_NORMAL : LOOKUP_IMPLICIT)); } else if ((cxx_dialect != cxx98) && friend_p && decl && TREE_CODE (decl) == FUNCTION_DECL) @@ -14368,7 +14378,7 @@ cp_parser_direct_declarator (cp_parser* parser, } /* Remove the function parms from scope. */ - for (t = current_binding_level->names; t; t = TREE_CHAIN (t)) + for (t = current_binding_level->names; t; t = DECL_CHAIN (t)) pop_binding (DECL_NAME (t), t); leave_scope(); @@ -19666,7 +19676,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) parmdecl = DECL_ARGUMENTS (fn); parm && parm != void_list_node; parm = TREE_CHAIN (parm), - parmdecl = TREE_CHAIN (parmdecl)) + parmdecl = DECL_CHAIN (parmdecl)) { cp_token_cache *tokens; tree default_arg = TREE_PURPOSE (parm); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 09d077ade06..7a331479d8b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -158,7 +158,7 @@ static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_parms (tree, tree, tsubst_flags_t); static void regenerate_decl_from_template (tree, tree); -static tree most_specialized_class (tree, tree); +static tree most_specialized_class (tree, tree, tsubst_flags_t); static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int); static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree); static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); @@ -1566,31 +1566,43 @@ iterative_hash_template_arg (tree arg, hashval_t val) gcc_assert (seen_error ()); return val; + case CAST_EXPR: + case STATIC_CAST_EXPR: + case REINTERPRET_CAST_EXPR: + case CONST_CAST_EXPR: + case DYNAMIC_CAST_EXPR: + case NEW_EXPR: + val = iterative_hash_template_arg (TREE_TYPE (arg), val); + /* Now hash operands as usual. */ + break; + default: - switch (tclass) - { - case tcc_type: - if (TYPE_CANONICAL (arg)) - return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)), - val); - else if (TREE_CODE (arg) == DECLTYPE_TYPE) - return iterative_hash_template_arg (DECLTYPE_TYPE_EXPR (arg), val); - /* Otherwise just compare the types during lookup. */ - return val; + break; + } - case tcc_declaration: - case tcc_constant: - return iterative_hash_expr (arg, val); + switch (tclass) + { + case tcc_type: + if (TYPE_CANONICAL (arg)) + return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)), + val); + else if (TREE_CODE (arg) == DECLTYPE_TYPE) + return iterative_hash_template_arg (DECLTYPE_TYPE_EXPR (arg), val); + /* Otherwise just compare the types during lookup. */ + return val; - default: - gcc_assert (IS_EXPR_CODE_CLASS (tclass)); - { - unsigned n = TREE_OPERAND_LENGTH (arg); - for (i = 0; i < n; ++i) - val = iterative_hash_template_arg (TREE_OPERAND (arg, i), val); - return val; - } - } + case tcc_declaration: + case tcc_constant: + return iterative_hash_expr (arg, val); + + default: + gcc_assert (IS_EXPR_CODE_CLASS (tclass)); + { + unsigned n = TREE_OPERAND_LENGTH (arg); + for (i = 0; i < n; ++i) + val = iterative_hash_template_arg (TREE_OPERAND (arg, i), val); + return val; + } } gcc_unreachable (); return 0; @@ -2553,7 +2565,7 @@ check_explicit_specialization (tree declarator, definition, not in the original declaration. */ DECL_ARGUMENTS (result) = DECL_ARGUMENTS (decl); for (parm = DECL_ARGUMENTS (result); parm; - parm = TREE_CHAIN (parm)) + parm = DECL_CHAIN (parm)) DECL_CONTEXT (parm) = result; } return register_specialization (tmpl, gen_tmpl, targs, @@ -3831,6 +3843,7 @@ process_partial_specialization (tree decl) tree inner_args = INNERMOST_TEMPLATE_ARGS (specargs); tree main_inner_parms = DECL_INNERMOST_TEMPLATE_PARMS (maintmpl); tree inner_parms; + tree inst; int nargs = TREE_VEC_LENGTH (inner_args); int ntparms; int i; @@ -4045,6 +4058,22 @@ process_partial_specialization (tree decl) = tree_cons (specargs, inner_parms, DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type; + + for (inst = DECL_TEMPLATE_INSTANTIATIONS (maintmpl); inst; + inst = TREE_CHAIN (inst)) + { + tree inst_type = TREE_VALUE (inst); + if (COMPLETE_TYPE_P (inst_type) + && CLASSTYPE_IMPLICIT_INSTANTIATION (inst_type)) + { + tree spec = most_specialized_class (inst_type, maintmpl, tf_none); + if (spec && TREE_TYPE (spec) == type) + permerror (input_location, + "partial specialization of %qT after instantiation " + "of %qT", type, inst_type); + } + } + return decl; } @@ -4417,7 +4446,7 @@ push_template_decl_real (tree decl, bool is_friend) TREE_VALUE (argtype) = error_mark_node; } - arg = TREE_CHAIN (arg); + arg = DECL_CHAIN (arg); argtype = TREE_CHAIN (argtype); } @@ -7749,7 +7778,7 @@ instantiate_class_template (tree type) /* Determine what specialization of the original template to instantiate. */ - t = most_specialized_class (type, templ); + t = most_specialized_class (type, templ, tf_warning_or_error); if (t == error_mark_node) { TYPE_BEING_DEFINED (type) = 1; @@ -7803,7 +7832,8 @@ instantiate_class_template (tree type) /* Set the input location to the most specialized template definition. This is needed if tsubsting causes an error. */ typedecl = TYPE_MAIN_DECL (pattern); - input_location = DECL_SOURCE_LOCATION (typedecl); + input_location = DECL_SOURCE_LOCATION (TYPE_NAME (type)) = + DECL_SOURCE_LOCATION (typedecl); TYPE_HAS_USER_CONSTRUCTOR (type) = TYPE_HAS_USER_CONSTRUCTOR (pattern); TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern); @@ -8196,7 +8226,7 @@ instantiate_class_template (tree type) any member functions. We don't do this earlier because the default arguments may reference members of the class. */ if (!PRIMARY_TEMPLATE_P (templ)) - for (t = TYPE_METHODS (type); t; t = TREE_CHAIN (t)) + for (t = TYPE_METHODS (type); t; t = DECL_CHAIN (t)) if (TREE_CODE (t) == FUNCTION_DECL /* Implicitly generated member functions will not have template information; they are not instantiations, but instead are @@ -8261,7 +8291,7 @@ make_fnparm_pack (tree spec_parm) /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */ parmvec = make_tree_vec (len); parmtypevec = make_tree_vec (len); - for (i = 0; i < len; i++, spec_parm = TREE_CHAIN (spec_parm)) + for (i = 0; i < len; i++, spec_parm = DECL_CHAIN (spec_parm)) { TREE_VEC_ELT (parmvec, i) = spec_parm; TREE_VEC_ELT (parmtypevec, i) = TREE_TYPE (spec_parm); @@ -8541,7 +8571,7 @@ get_pattern_parm (tree parm, tree tmpl) if (DECL_ARTIFICIAL (parm)) { for (patparm = DECL_ARGUMENTS (pattern); - patparm; patparm = TREE_CHAIN (patparm)) + patparm; patparm = DECL_CHAIN (patparm)) if (DECL_ARTIFICIAL (patparm) && DECL_NAME (parm) == DECL_NAME (patparm)) break; @@ -8936,7 +8966,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) RETURN (error_mark_node); r = copy_decl (t); - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; TREE_TYPE (r) = new_type; DECL_TEMPLATE_RESULT (r) = build_decl (DECL_SOURCE_LOCATION (decl), @@ -8986,7 +9016,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) than the old one. */ r = copy_decl (t); gcc_assert (DECL_LANG_SPECIFIC (r) != 0); - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; DECL_TEMPLATE_INFO (r) = build_template_info (t, args); @@ -9196,7 +9226,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) assigned to the instantiation. */ DECL_INTERFACE_KNOWN (r) = !TREE_PUBLIC (r); DECL_DEFER_OUTPUT (r) = 0; - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; DECL_PENDING_INLINE_INFO (r) = 0; DECL_PENDING_INLINE_P (r) = 0; DECL_SAVED_TREE (r) = NULL_TREE; @@ -9395,12 +9425,12 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /* Build a proper chain of parameters when substituting into a function parameter pack. */ if (prev_r) - TREE_CHAIN (prev_r) = r; + DECL_CHAIN (prev_r) = r; } - if (TREE_CHAIN (t)) - TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args, - complain, TREE_CHAIN (t)); + if (DECL_CHAIN (t)) + DECL_CHAIN (r) = tsubst (DECL_CHAIN (t), args, + complain, DECL_CHAIN (t)); /* FIRST_R contains the start of the chain we've built. */ r = first_r; @@ -9425,7 +9455,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /*integral_constant_expression_p=*/true); /* We don't have to set DECL_CONTEXT here; it is set by finish_member_declaration. */ - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; if (VOID_TYPE_P (type)) error ("instantiation of %q+D as type %qT", r, type); @@ -9452,7 +9482,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) else { r = copy_node (t); - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; } break; @@ -9652,7 +9682,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) else register_local_specialization (r, t); - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), /*flags=*/0, @@ -9958,6 +9988,7 @@ tsubst_exception_specification (tree fntype, tree tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { + enum tree_code code; tree type, r; if (t == NULL_TREE || t == error_mark_node @@ -9974,7 +10005,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (args == NULL_TREE) return t; - if (TREE_CODE (t) == IDENTIFIER_NODE) + code = TREE_CODE (t); + + if (code == IDENTIFIER_NODE) type = IDENTIFIER_TYPE_VALUE (t); else type = TREE_TYPE (t); @@ -10017,16 +10050,16 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) } if (type - && TREE_CODE (t) != TYPENAME_TYPE - && TREE_CODE (t) != TEMPLATE_TYPE_PARM - && TREE_CODE (t) != IDENTIFIER_NODE - && TREE_CODE (t) != FUNCTION_TYPE - && TREE_CODE (t) != METHOD_TYPE) + && code != TYPENAME_TYPE + && code != TEMPLATE_TYPE_PARM + && code != IDENTIFIER_NODE + && code != FUNCTION_TYPE + && code != METHOD_TYPE) type = tsubst (type, args, complain, in_decl); if (type == error_mark_node) return error_mark_node; - switch (TREE_CODE (t)) + switch (code) { case RECORD_TYPE: case UNION_TYPE: @@ -10156,7 +10189,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) }; */ return t; - if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) + if (code == TEMPLATE_TYPE_PARM) { int quals; gcc_assert (TYPE_P (arg)); @@ -10166,7 +10199,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) return cp_build_qualified_type_real (arg, quals, complain | tf_ignore_bad_quals); } - else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM) + else if (code == BOUND_TEMPLATE_TEMPLATE_PARM) { /* We are processing a type constructed from a template template parameter. */ @@ -10205,7 +10238,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* If we get here, we must have been looking at a parm for a more deeply nested template. Make a new version of this template parameter, but with a lower level. */ - switch (TREE_CODE (t)) + switch (code) { case TEMPLATE_TYPE_PARM: case TEMPLATE_TEMPLATE_PARM: @@ -10215,7 +10248,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl); r = cp_build_qualified_type_real (r, cp_type_quals (t), - complain | (TREE_CODE (t) == TEMPLATE_TYPE_PARM + complain | (code == TEMPLATE_TYPE_PARM ? tf_ignore_bad_quals : 0)); } else @@ -10243,7 +10276,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) else TYPE_CANONICAL (r) = canonical_type_parameter (r); - if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM) + if (code == BOUND_TEMPLATE_TEMPLATE_PARM) { tree argvec = tsubst (TYPE_TI_ARGS (t), args, complain, in_decl); @@ -10314,14 +10347,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) case POINTER_TYPE: case REFERENCE_TYPE: { - enum tree_code code; - if (type == TREE_TYPE (t) && TREE_CODE (type) != METHOD_TYPE) return t; - code = TREE_CODE (t); - - /* [temp.deduct] Type deduction may fail for any of the following @@ -10506,7 +10534,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) return error_mark_node; return fold_build2_loc (input_location, - TREE_CODE (t), TREE_TYPE (t), e1, e2); + code, TREE_TYPE (t), e1, e2); } case NEGATE_EXPR: @@ -10516,7 +10544,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (e == error_mark_node) return error_mark_node; - return fold_build1_loc (input_location, TREE_CODE (t), TREE_TYPE (t), e); + return fold_build1_loc (input_location, code, TREE_TYPE (t), e); } case TYPENAME_TYPE: @@ -10672,9 +10700,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) case TYPE_ARGUMENT_PACK: case NONTYPE_ARGUMENT_PACK: { - tree r = TYPE_P (t) - ? cxx_make_type (TREE_CODE (t)) - : make_node (TREE_CODE (t)); + tree r = TYPE_P (t) ? cxx_make_type (code) : make_node (code); tree packed_out = tsubst_template_args (ARGUMENT_PACK_ARGS (t), args, @@ -10684,7 +10710,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* For template nontype argument packs, also substitute into the type. */ - if (TREE_CODE (t) == NONTYPE_ARGUMENT_PACK) + if (code == NONTYPE_ARGUMENT_PACK) TREE_TYPE (r) = tsubst (TREE_TYPE (t), args, complain, in_decl); return r; @@ -10692,8 +10718,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) break; default: - sorry ("use of %qs in template", - tree_code_name [(int) TREE_CODE (t)]); + sorry ("use of %qs in template", tree_code_name [(int) code]); return error_mark_node; } } @@ -10737,6 +10762,8 @@ tsubst_baselink (tree baselink, tree object_type, if (IDENTIFIER_TYPENAME_P (name)) name = mangle_conv_op_name_for_type (optype); baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1); + if (!baselink) + return error_mark_node; /* If lookup found a single function, mark it as used at this point. (If it lookup found multiple functions the one selected @@ -11312,8 +11339,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) gcc_unreachable (); case OFFSET_REF: - mark_used (TREE_OPERAND (t, 1)); - return t; + r = build2 + (code, tsubst (TREE_TYPE (t), args, complain, in_decl), + tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), + tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl)); + PTRMEM_OK_P (r) = PTRMEM_OK_P (t); + mark_used (TREE_OPERAND (r, 1)); + return r; case EXPR_PACK_EXPANSION: error ("invalid use of pack expansion expression"); @@ -12500,15 +12532,24 @@ tsubst_copy_and_build (tree t, ret = build_offset_ref_call_from_tree (function, &call_args); else if (TREE_CODE (function) == COMPONENT_REF) { - if (!BASELINK_P (TREE_OPERAND (function, 1))) + tree instance = TREE_OPERAND (function, 0); + tree fn = TREE_OPERAND (function, 1); + + if (processing_template_decl + && (type_dependent_expression_p (instance) + || (!BASELINK_P (fn) + && TREE_CODE (fn) != FIELD_DECL) + || type_dependent_expression_p (fn) + || any_type_dependent_arguments_p (call_args))) + ret = build_nt_call_vec (function, call_args); + else if (!BASELINK_P (fn)) ret = finish_call_expr (function, &call_args, /*disallow_virtual=*/false, /*koenig_p=*/false, complain); else ret = (build_new_method_call - (TREE_OPERAND (function, 0), - TREE_OPERAND (function, 1), + (instance, fn, &call_args, NULL_TREE, qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL, /*fn_p=*/NULL, @@ -13121,7 +13162,7 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) instantiate all the alternate entry points as well. We do this by cloning the instantiation of the main entry point, not by instantiating the template clones. */ - if (TREE_CHAIN (gen_tmpl) && DECL_CLONED_FUNCTION_P (TREE_CHAIN (gen_tmpl))) + if (DECL_CHAIN (gen_tmpl) && DECL_CLONED_FUNCTION_P (DECL_CHAIN (gen_tmpl))) clone_function_decl (fndecl, /*update_method_vec_p=*/0); return fndecl; @@ -15972,7 +16013,7 @@ most_general_template (tree decl) returned. */ static tree -most_specialized_class (tree type, tree tmpl) +most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain) { tree list = NULL_TREE; tree t; @@ -16092,6 +16133,8 @@ most_specialized_class (tree type, tree tmpl) { const char *str; char *spaces = NULL; + if (!(complain & tf_error)) + return error_mark_node; error ("ambiguous class template instantiation for %q#T", type); str = TREE_CHAIN (list) ? _("candidates are:") : _("candidate is:"); for (t = list; t; t = TREE_CHAIN (t)) @@ -16390,12 +16433,12 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain) interpretation is that it should be an explicit instantiation. */ if (! static_p) - for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp)) + for (tmp = TYPE_METHODS (t); tmp; tmp = DECL_CHAIN (tmp)) if (TREE_CODE (tmp) == FUNCTION_DECL && DECL_TEMPLATE_INSTANTIATION (tmp)) instantiate_class_member (tmp, extern_p); - for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp)) + for (tmp = TYPE_FIELDS (t); tmp; tmp = DECL_CHAIN (tmp)) if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp)) instantiate_class_member (tmp, extern_p); @@ -16483,8 +16526,8 @@ regenerate_decl_from_template (tree decl, tree tmpl) DECL_ATTRIBUTES (decl_parm) = attributes; cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0); } - decl_parm = TREE_CHAIN (decl_parm); - pattern_parm = TREE_CHAIN (pattern_parm); + decl_parm = DECL_CHAIN (decl_parm); + pattern_parm = DECL_CHAIN (pattern_parm); } /* Merge any parameters that match with the function parameter pack. */ @@ -16516,7 +16559,7 @@ regenerate_decl_from_template (tree decl, tree tmpl) DECL_ATTRIBUTES (decl_parm) = attributes; cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0); } - decl_parm = TREE_CHAIN (decl_parm); + decl_parm = DECL_CHAIN (decl_parm); } } /* Merge additional specifiers from the CODE_PATTERN. */ @@ -16926,8 +16969,8 @@ instantiate_decl (tree d, int defer_ok, while (tmpl_parm && !FUNCTION_PARAMETER_PACK_P (tmpl_parm)) { register_local_specialization (spec_parm, tmpl_parm); - tmpl_parm = TREE_CHAIN (tmpl_parm); - spec_parm = TREE_CHAIN (spec_parm); + tmpl_parm = DECL_CHAIN (tmpl_parm); + spec_parm = DECL_CHAIN (spec_parm); } if (tmpl_parm && FUNCTION_PARAMETER_PACK_P (tmpl_parm)) { @@ -16935,7 +16978,7 @@ instantiate_decl (tree d, int defer_ok, TMPL_PARM, then move on. */ tree argpack = make_fnparm_pack (spec_parm); register_local_specialization (argpack, tmpl_parm); - tmpl_parm = TREE_CHAIN (tmpl_parm); + tmpl_parm = DECL_CHAIN (tmpl_parm); spec_parm = NULL_TREE; } gcc_assert (!spec_parm); diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c index c2493c7fcad..ee3f52faf23 100644 --- a/gcc/cp/ptree.c +++ b/gcc/cp/ptree.c @@ -207,6 +207,15 @@ cxx_print_xnode (FILE *file, tree node, int indent) TEMPLATE_PARM_IDX (node), TEMPLATE_PARM_LEVEL (node), TEMPLATE_PARM_ORIG_LEVEL (node)); break; + case TEMPLATE_INFO: + print_node (file, "template", TI_TEMPLATE (node), indent+4); + print_node (file, "args", TI_ARGS (node), indent+4); + if (TI_PENDING_TEMPLATE_FLAG (node)) + { + indent_to (file, indent + 3); + fprintf (file, "pending_template"); + } + break; default: break; } diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index dde8e825dbe..c994683aae8 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -1210,7 +1210,7 @@ create_pseudo_type_info (int tk, const char *real_name, ...) /* Now add the derived fields. */ while ((field_decl = va_arg (ap, tree))) { - TREE_CHAIN (field_decl) = fields; + DECL_CHAIN (field_decl) = fields; fields = field_decl; } @@ -1375,7 +1375,7 @@ create_tinfo_types (void) field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, const_string_type_node); - TREE_CHAIN (field) = fields; + DECL_CHAIN (field) = fields; fields = field; ti = VEC_index (tinfo_s, tinfo_descs, TK_TYPE_INFO_TYPE); @@ -1415,7 +1415,7 @@ create_tinfo_types (void) field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, integer_types[itk_long]); - TREE_CHAIN (field) = fields; + DECL_CHAIN (field) = fields; fields = field; ti = VEC_index (tinfo_s, tinfo_descs, TK_BASE_TYPE); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 9dbefd3c5bc..0249fb06d48 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -170,7 +170,7 @@ accessible_base_p (tree t, tree base, bool consider_local_p) public typedef created in the scope of every class. */ decl = TYPE_FIELDS (base); while (!DECL_SELF_REFERENCE_P (decl)) - decl = TREE_CHAIN (decl); + decl = DECL_CHAIN (decl); while (ANON_AGGR_TYPE_P (t)) t = TYPE_CONTEXT (t); return accessible_p (t, decl, consider_local_p); @@ -447,7 +447,7 @@ lookup_field_1 (tree type, tree name, bool want_type) #ifdef GATHER_STATISTICS n_calls_lookup_field_1++; #endif /* GATHER_STATISTICS */ - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { #ifdef GATHER_STATISTICS n_fields_searched++; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 156f278e171..949e108902a 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -607,10 +607,10 @@ finish_expr_stmt (tree expr) { if (warn_sequence_point) verify_sequence_points (expr); - expr = convert_to_void (expr, "statement", tf_warning_or_error); + expr = convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error); } else if (!type_dependent_expression_p (expr)) - convert_to_void (build_non_dependent_expr (expr), "statement", + convert_to_void (build_non_dependent_expr (expr), ICV_STATEMENT, tf_warning_or_error); if (check_for_bare_parameter_packs (expr)) @@ -868,11 +868,11 @@ finish_for_expr (tree expr, tree for_stmt) { if (warn_sequence_point) verify_sequence_points (expr); - expr = convert_to_void (expr, "3rd expression in for", + expr = convert_to_void (expr, ICV_THIRD_IN_FOR, tf_warning_or_error); } else if (!type_dependent_expression_p (expr)) - convert_to_void (build_non_dependent_expr (expr), "3rd expression in for", + convert_to_void (build_non_dependent_expr (expr), ICV_THIRD_IN_FOR, tf_warning_or_error); expr = maybe_cleanup_point_expr_void (expr); if (check_for_bare_parameter_packs (expr)) @@ -2418,7 +2418,7 @@ finish_member_declaration (tree decl) return; /* We should see only one DECL at a time. */ - gcc_assert (TREE_CHAIN (decl) == NULL_TREE); + gcc_assert (DECL_CHAIN (decl) == NULL_TREE); /* Set up access control for DECL. */ TREE_PRIVATE (decl) @@ -2460,7 +2460,7 @@ finish_member_declaration (tree decl) CLASSTYPE_METHOD_VEC. */ if (add_method (current_class_type, decl, NULL_TREE)) { - TREE_CHAIN (decl) = TYPE_METHODS (current_class_type); + DECL_CHAIN (decl) = TYPE_METHODS (current_class_type); TYPE_METHODS (current_class_type) = decl; maybe_add_class_template_decl_list (current_class_type, decl, @@ -2493,7 +2493,7 @@ finish_member_declaration (tree decl) = chainon (TYPE_FIELDS (current_class_type), decl); else { - TREE_CHAIN (decl) = TYPE_FIELDS (current_class_type); + DECL_CHAIN (decl) = TYPE_FIELDS (current_class_type); TYPE_FIELDS (current_class_type) = decl; } @@ -3319,7 +3319,7 @@ emit_associated_thunks (tree fn) { tree thunk; - for (thunk = DECL_THUNKS (fn); thunk; thunk = TREE_CHAIN (thunk)) + for (thunk = DECL_THUNKS (fn); thunk; thunk = DECL_CHAIN (thunk)) { if (!THUNK_ALIAS (thunk)) { @@ -3329,7 +3329,7 @@ emit_associated_thunks (tree fn) tree probe; for (probe = DECL_THUNKS (thunk); - probe; probe = TREE_CHAIN (probe)) + probe; probe = DECL_CHAIN (probe)) use_thunk (probe, /*emit_p=*/1); } } @@ -4899,8 +4899,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) type = TYPE_MAIN_VARIANT (type); else if (real_lvalue_p (expr)) { - if (TREE_CODE (type) != REFERENCE_TYPE) - type = build_reference_type (type); + if (TREE_CODE (type) != REFERENCE_TYPE + || TYPE_REF_IS_RVALUE (type)) + type = build_reference_type (non_reference (type)); } else type = non_reference (type); @@ -5850,8 +5851,8 @@ maybe_add_lambda_conv_op (tree type) DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_DECLARED_INLINE_P (fn) = 1; DECL_STATIC_FUNCTION_P (fn) = 1; - DECL_ARGUMENTS (fn) = copy_list (TREE_CHAIN (DECL_ARGUMENTS (callop))); - for (arg = DECL_ARGUMENTS (fn); arg; arg = TREE_CHAIN (arg)) + DECL_ARGUMENTS (fn) = copy_list (DECL_CHAIN (DECL_ARGUMENTS (callop))); + for (arg = DECL_ARGUMENTS (fn); arg; arg = DECL_CHAIN (arg)) DECL_CONTEXT (arg) = fn; if (nested) DECL_INTERFACE_KNOWN (fn) = 1; @@ -5884,7 +5885,7 @@ maybe_add_lambda_conv_op (tree type) null_pointer_node); argvec = make_tree_vector (); VEC_quick_push (tree, argvec, arg); - for (arg = DECL_ARGUMENTS (statfn); arg; arg = TREE_CHAIN (arg)) + for (arg = DECL_ARGUMENTS (statfn); arg; arg = DECL_CHAIN (arg)) VEC_safe_push (tree, gc, argvec, arg); call = build_call_a (callop, VEC_length (tree, argvec), VEC_address (tree, argvec)); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index d62f9d7acf6..450b9e89433 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2023,11 +2023,21 @@ cp_tree_equal (tree t1, tree t2) /* We need to do this when determining whether or not two non-type pointer to member function template arguments are the same. */ - if (!(same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) - /* The first operand is RTL. */ - && TREE_OPERAND (t1, 0) == TREE_OPERAND (t2, 0))) + if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) + || CONSTRUCTOR_NELTS (t1) != CONSTRUCTOR_NELTS (t2)) return false; - return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)); + { + tree field, value; + unsigned int i; + FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t1), i, field, value) + { + constructor_elt *elt2 = CONSTRUCTOR_ELT (t2, i); + if (!cp_tree_equal (field, elt2->index) + || !cp_tree_equal (value, elt2->value)) + return false; + } + } + return true; case TREE_LIST: if (!cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2))) @@ -2191,6 +2201,17 @@ cp_tree_equal (tree t1, tree t2) return same_type_p (TRAIT_EXPR_TYPE1 (t1), TRAIT_EXPR_TYPE1 (t2)) && same_type_p (TRAIT_EXPR_TYPE2 (t1), TRAIT_EXPR_TYPE2 (t2)); + case CAST_EXPR: + case STATIC_CAST_EXPR: + case REINTERPRET_CAST_EXPR: + case CONST_CAST_EXPR: + case DYNAMIC_CAST_EXPR: + case NEW_EXPR: + if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))) + return false; + /* Now compare operands as usual. */ + break; + default: break; } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 371bb87c8e8..8411c90c9e8 100644 --- a/gcc/cp/typeck.c +++ b/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, 2005, 2006, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) @@ -53,7 +53,7 @@ static int comp_ptr_ttypes_real (tree, tree, int); static bool comp_except_types (tree, tree, bool); static bool comp_array_types (const_tree, const_tree, bool); static tree pointer_diff (tree, tree, tree); -static tree get_delta_difference (tree, tree, bool, bool); +static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t); static void casts_away_constness_r (tree *, tree *); static bool casts_away_constness (tree, tree); static void maybe_warn_about_returning_address_of_local (tree); @@ -1503,6 +1503,18 @@ comptypes (tree t1, tree t2, int strict) return structural_comptypes (t1, t2, strict); } +/* Returns nonzero iff TYPE1 and TYPE2 are the same type, ignoring + top-level qualifiers. */ + +bool +same_type_ignoring_top_level_qualifiers_p (tree type1, tree type2) +{ + if (type1 == error_mark_node || type2 == error_mark_node) + return false; + + return same_type_p (TYPE_MAIN_VARIANT (type1), TYPE_MAIN_VARIANT (type2)); +} + /* Returns 1 if TYPE1 is at least as qualified as TYPE2. */ bool @@ -2136,7 +2148,7 @@ lookup_anon_field (tree t, tree type) { tree field; - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) { if (TREE_STATIC (field)) continue; @@ -4781,7 +4793,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, tree val; const char *invalid_op_diag; - if (error_operand_p (arg)) + if (!arg || error_operand_p (arg)) return error_mark_node; if ((invalid_op_diag @@ -5276,7 +5288,8 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, build_ptrmemfunc_type (argtype); val = build_ptrmemfunc (argtype, val, 0, - /*c_cast_p=*/false); + /*c_cast_p=*/false, + tf_warning_or_error); } return val; @@ -5511,14 +5524,16 @@ build_x_conditional_expr (tree ifexp, tree op1, tree op2, that performs them all and returns the value of the last of them. */ tree -build_x_compound_expr_from_list (tree list, expr_list_kind exp) +build_x_compound_expr_from_list (tree list, expr_list_kind exp, + tsubst_flags_t complain) { tree expr = TREE_VALUE (list); if (TREE_CHAIN (list)) { - switch (exp) - { + if (complain & tf_error) + switch (exp) + { case ELK_INIT: permerror (input_location, "expression list treated as compound " "expression in initializer"); @@ -5533,11 +5548,11 @@ build_x_compound_expr_from_list (tree list, expr_list_kind exp) break; default: gcc_unreachable (); - } + } for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list)) expr = build_x_compound_expr (expr, TREE_VALUE (list), - tf_warning_or_error); + complain); } return expr; @@ -5613,7 +5628,7 @@ build_compound_expr (location_t loc ATTRIBUTE_UNUSED, tree lhs, tree rhs) tree cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain) { - lhs = convert_to_void (lhs, "left-hand operand of comma", complain); + lhs = convert_to_void (lhs, ICV_LEFT_OF_COMMA, complain); if (lhs == error_mark_node || rhs == error_mark_node) return error_mark_node; @@ -5691,7 +5706,7 @@ check_for_casting_away_constness (tree src_type, tree dest_type, tree convert_ptrmem (tree type, tree expr, bool allow_inverse_p, - bool c_cast_p) + bool c_cast_p, tsubst_flags_t complain) { if (TYPE_PTRMEM_P (type)) { @@ -5702,7 +5717,10 @@ convert_ptrmem (tree type, tree expr, bool allow_inverse_p, delta = get_delta_difference (TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (expr)), TYPE_PTRMEM_CLASS_TYPE (type), allow_inverse_p, - c_cast_p); + c_cast_p, complain); + if (delta == error_mark_node) + return error_mark_node; + if (!integer_zerop (delta)) { tree cond, op1, op2; @@ -5726,7 +5744,7 @@ convert_ptrmem (tree type, tree expr, bool allow_inverse_p, } else return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, - allow_inverse_p, c_cast_p); + allow_inverse_p, c_cast_p, complain); } /* If EXPR is an INTEGER_CST and ORIG is an arithmetic constant, return @@ -5880,7 +5898,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, Any expression can be explicitly converted to type cv void. */ if (TREE_CODE (type) == VOID_TYPE) - return convert_to_void (expr, /*implicit=*/NULL, complain); + return convert_to_void (expr, ICV_CAST, complain); /* [expr.static.cast] @@ -5962,7 +5980,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, if (!c_cast_p) check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR); return convert_ptrmem (type, expr, /*allow_inverse_p=*/1, - c_cast_p); + c_cast_p, tf_warning_or_error); } } @@ -6877,20 +6895,32 @@ build_x_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, /* Helper function for get_delta_difference which assumes FROM is a base class of TO. Returns a delta for the conversion of pointer-to-member - of FROM to pointer-to-member of TO. If the conversion is invalid, + of FROM to pointer-to-member of TO. If the conversion is invalid and + tf_error is not set in COMPLAIN returns error_mark_node, otherwise returns zero. If FROM is not a base class of TO, returns NULL_TREE. - If C_CAST_P is true, this conversion is taking place as part of a C-style - cast. */ + If C_CAST_P is true, this conversion is taking place as part of a + C-style cast. */ static tree -get_delta_difference_1 (tree from, tree to, bool c_cast_p) +get_delta_difference_1 (tree from, tree to, bool c_cast_p, + tsubst_flags_t complain) { tree binfo; base_kind kind; + base_access access = c_cast_p ? ba_unique : ba_check; + + /* Note: ba_quiet does not distinguish between access control and + ambiguity. */ + if (!(complain & tf_error)) + access |= ba_quiet; + + binfo = lookup_base (to, from, access, &kind); - binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check, &kind); if (kind == bk_inaccessible || kind == bk_ambig) { + if (!(complain & tf_error)) + return error_mark_node; + error (" in pointer to member function conversion"); return size_zero_node; } @@ -6902,22 +6932,26 @@ get_delta_difference_1 (tree from, tree to, bool c_cast_p) /* FROM is a virtual base class of TO. Issue an error or warning depending on whether or not this is a reinterpret cast. */ { + if (!(complain & tf_error)) + return error_mark_node; + error ("pointer to member conversion via virtual base %qT", BINFO_TYPE (binfo_from_vbase (binfo))); return size_zero_node; } } - else - return NULL_TREE; + else + return NULL_TREE; } /* Get difference in deltas for different pointer to member function - types. Returns an integer constant of type PTRDIFF_TYPE_NODE. If - the conversion is invalid, the constant is zero. If - ALLOW_INVERSE_P is true, then allow reverse conversions as well. - If C_CAST_P is true this conversion is taking place as part of a - C-style cast. + types. If the conversion is invalid and tf_error is not set in + COMPLAIN, returns error_mark_node, otherwise returns an integer + constant of type PTRDIFF_TYPE_NODE and its value is zero if the + conversion is invalid. If ALLOW_INVERSE_P is true, then allow reverse + conversions as well. If C_CAST_P is true this conversion is taking + place as part of a C-style cast. Note that the naming of FROM and TO is kind of backwards; the return value is what we add to a TO in order to get a FROM. They are named @@ -6927,7 +6961,7 @@ get_delta_difference_1 (tree from, tree to, bool c_cast_p) static tree get_delta_difference (tree from, tree to, bool allow_inverse_p, - bool c_cast_p) + bool c_cast_p, tsubst_flags_t complain) { tree result; @@ -6935,25 +6969,37 @@ get_delta_difference (tree from, tree to, /* Pointer to member of incomplete class is permitted*/ result = size_zero_node; else - result = get_delta_difference_1 (from, to, c_cast_p); + result = get_delta_difference_1 (from, to, c_cast_p, complain); + + if (result == error_mark_node) + return error_mark_node; if (!result) { if (!allow_inverse_p) { + if (!(complain & tf_error)) + return error_mark_node; + error_not_base_type (from, to); error (" in pointer to member conversion"); - result = size_zero_node; + result = size_zero_node; } else { - result = get_delta_difference_1 (to, from, c_cast_p); + result = get_delta_difference_1 (to, from, c_cast_p, complain); + + if (result == error_mark_node) + return error_mark_node; if (result) result = size_diffop_loc (input_location, - size_zero_node, result); + size_zero_node, result); else { + if (!(complain & tf_error)) + return error_mark_node; + error_not_base_type (from, to); error (" in pointer to member conversion"); result = size_zero_node; @@ -6978,7 +7024,7 @@ build_ptrmemfunc1 (tree type, tree delta, tree pfn) /* Pull the FIELD_DECLs out of the type. */ pfn_field = TYPE_FIELDS (type); - delta_field = TREE_CHAIN (pfn_field); + delta_field = DECL_CHAIN (pfn_field); /* Make sure DELTA has the type we want. */ delta = convert_and_check (delta_type_node, delta); @@ -7012,7 +7058,8 @@ build_ptrmemfunc1 (tree type, tree delta, tree pfn) Return error_mark_node, if something goes wrong. */ tree -build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p) +build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p, + tsubst_flags_t complain) { tree fn; tree pfn_type; @@ -7039,7 +7086,9 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p) n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type), TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type), force, - c_cast_p); + c_cast_p, complain); + if (n == error_mark_node) + return error_mark_node; /* We don't have to do any conversion to convert a pointer-to-member to its own type. But, we don't want to @@ -7122,7 +7171,7 @@ expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn) /* First, calculate the adjustment to the function's class. */ *delta = get_delta_difference (fn_class, ptr_class, /*force=*/0, - /*c_cast_p=*/0); + /*c_cast_p=*/0, tf_warning_or_error); if (!DECL_VIRTUAL_P (fn)) *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_addr_func (fn)); @@ -7233,7 +7282,10 @@ convert_for_assignment (tree type, tree rhs, if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE && vector_types_convertible_p (type, rhstype, true)) - return convert (type, rhs); + { + rhs = mark_rvalue_use (rhs); + return convert (type, rhs); + } if (rhs == error_mark_node || rhstype == error_mark_node) return error_mark_node; @@ -7277,7 +7329,10 @@ convert_for_assignment (tree type, tree rhs, } if (objc_compare_types (type, rhstype, parmno, rname)) - return convert (type, rhs); + { + rhs = mark_rvalue_use (rhs); + return convert (type, rhs); + } } /* [expr.ass] diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index f62bbb5d950..ce83d7c40b7 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -737,7 +737,8 @@ store_init_value (tree decl, tree init, int flags) } else /* We get here with code like `int a (2);' */ - init = build_x_compound_expr_from_list (init, ELK_INIT); + init = build_x_compound_expr_from_list (init, ELK_INIT, + tf_warning_or_error); } /* End of special C++ code. */ @@ -1115,7 +1116,7 @@ process_init_constructor_record (tree type, tree init) /* Generally, we will always have an index for each initializer (which is a FIELD_DECL, put by reshape_init), but compound literals don't go trough reshape_init. So we need to handle both cases. */ - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { tree next; tree type; @@ -1478,8 +1479,8 @@ build_m_component_ref (tree datum, tree component) if (error_operand_p (datum) || error_operand_p (component)) return error_mark_node; - mark_lvalue_use (datum); - mark_rvalue_use (component); + datum = mark_lvalue_use (datum); + component = mark_rvalue_use (component); ptrmem_type = TREE_TYPE (component); if (!TYPE_PTR_TO_MEMBER_P (ptrmem_type)) @@ -1594,7 +1595,7 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain) return cp_convert (type, integer_zero_node); /* This must build a C cast. */ - parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST); + parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain); return cp_build_c_cast (type, parms, complain); } |