summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog259
-rw-r--r--gcc/cp/call.c48
-rw-r--r--gcc/cp/class.c207
-rw-r--r--gcc/cp/cp-gimplify.c14
-rw-r--r--gcc/cp/cp-tree.h49
-rw-r--r--gcc/cp/cvt.c319
-rw-r--r--gcc/cp/decl.c62
-rw-r--r--gcc/cp/decl2.c20
-rw-r--r--gcc/cp/error.c2
-rw-r--r--gcc/cp/init.c136
-rw-r--r--gcc/cp/mangle.c27
-rw-r--r--gcc/cp/method.c269
-rw-r--r--gcc/cp/name-lookup.c50
-rw-r--r--gcc/cp/optimize.c29
-rw-r--r--gcc/cp/parser.c20
-rw-r--r--gcc/cp/pt.c203
-rw-r--r--gcc/cp/ptree.c9
-rw-r--r--gcc/cp/rtti.c6
-rw-r--r--gcc/cp/search.c4
-rw-r--r--gcc/cp/semantics.c29
-rw-r--r--gcc/cp/tree.c29
-rw-r--r--gcc/cp/typeck.c133
-rw-r--r--gcc/cp/typeck2.c11
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);
}