diff options
author | Mike Stump <mrs@gcc.gnu.org> | 1996-01-22 19:49:02 +0000 |
---|---|---|
committer | Mike Stump <mrs@gcc.gnu.org> | 1996-01-22 19:49:02 +0000 |
commit | 455376771ffd21a96482f501e0b951a6d95e883d (patch) | |
tree | 72df105a5167566b5f363fefcb9ecf25a496676f /gcc | |
parent | f589b741f98dc838c4ea9296e052b74be7b9e983 (diff) | |
download | gcc-455376771ffd21a96482f501e0b951a6d95e883d.zip gcc-455376771ffd21a96482f501e0b951a6d95e883d.tar.gz gcc-455376771ffd21a96482f501e0b951a6d95e883d.tar.bz2 |
79th Cygnus<->FSF merge
From-SVN: r11082
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 60 | ||||
-rw-r--r-- | gcc/cp/class.c | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/decl.c | 128 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 9 | ||||
-rw-r--r-- | gcc/cp/init.c | 6 | ||||
-rw-r--r-- | gcc/cp/parse.y | 35 | ||||
-rw-r--r-- | gcc/cp/search.c | 51 | ||||
-rw-r--r-- | gcc/cp/tree.c | 7 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 15 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 30 |
11 files changed, 236 insertions, 115 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 22cb2b3..a7fe9fe 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,60 @@ +Fri Jan 19 18:03:14 1996 Mike Stump <mrs@cygnus.com> + + * typeck.c (build_component_ref): Handle getting vbase pointers + out of complex multiple inheritance better. + +Fri Jan 19 16:27:40 1996 Mike Stump <mrs@cygnus.com> + + * typeck.c (build_object_ref): Make sure we use the real type, not + any reference type. + +Fri Jan 19 16:01:47 1996 Mike Stump <mrs@cygnus.com> + + * tree.c (build_exception_variant): Don't create new types if we + don't have to, also build new types on the right obstack. + +Fri Jan 19 14:09:44 1996 Jason Merrill <jason@yorick.cygnus.com> + + * decl.c (store_bindings): Split out from push_to_top_level. + (push_to_top_level): Call it for b->type_shadowed on class binding + levels. + +Fri Jan 19 13:53:14 1996 Mike Stump <mrs@cygnus.com> + + * search.c (expand_upcast_fixups): Fix so that offsets stored in + vbase_offsets are always right. Fixes a problem where virtual base + upcasting and downcasting could be wrong during conversions on this + during virtual function dispatch at ctor/dtor time when dynamic + vtable fixups for deltas are needed. This only sounds easier than + it is. :-) + (fixup_virtual_upcast_offsets): Change to reflect new calling + convention for expand_upcast_fixups. + +Fri Jan 19 12:23:08 1996 Brendan Kehoe <brendan@lisa.cygnus.com> + + * decl2.c (grokbitfield): Strip the NOPs from WIDTH before we + check that it's usable as the bitfield width. + +Wed Jan 17 21:22:40 1996 Brendan Kehoe <brendan@lisa.cygnus.com> + + * decl2.c (grokfield): Call cplus_decl_attributes with the attrlist. + Pass a null tree to grokdeclarator for its ATTRLIST arg, since it's + only ever used for functions in it. + +Wed Jan 17 12:10:38 1996 Jason Merrill <jason@yorick.cygnus.com> + + * parse.y (qualified_type_name): Use the TYPE_DECL, not the type. + (nested_type): Ditto. + (nested_name_specifier): Use lastiddecl. + + * decl.c (grokdeclarator): Adjust accordingly. + * init.c (expand_member_init): Ditto. + * parse.y (base_class): Ditto. + * typeck2.c (build_functional_cast): Ditto. + + * typeck2.c (build_functional_cast): Fill in name after we've + checked for non-aggr type. + Wed Jan 17 10:18:01 1996 Mike Stump <mrs@cygnus.com> * decl2.c (warn_pointer_arith): Default to on. @@ -53,9 +110,6 @@ Mon Jan 15 16:19:32 1996 Jason Merrill <jason@yorick.cygnus.com> * init.c (sort_base_init): Ditto. (expand_member_init): Ditto. * init.c (is_aggr_type): New function, like is_aggr_typedef. - * class.c (pushclass): If !modify and - CLASSTYPE_LOCAL_TYPEDECLS (type)), do set up IDENTIFIER_TYPE_VALUE - for inherited types. Mon Jan 15 08:45:01 1996 Jeffrey A Law (law@cygnus.com) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index cca35da..87dc9c0 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4416,7 +4416,7 @@ pushclass (type, modify) else if (type != previous_class_type || current_class_depth > 1) { build_mi_matrix (type); - push_class_decls (type, !modify); + push_class_decls (type); free_mi_matrix (); if (current_class_depth == 1) previous_class_type = type; @@ -4453,12 +4453,6 @@ pushclass (type, modify) current_function_decl = this_fndecl; } - else if (CLASSTYPE_LOCAL_TYPEDECLS (type)) - { - build_mi_matrix (type); - push_class_decls (type, !modify); - free_mi_matrix (); - } if (flag_cadillac) cadillac_push_class (type); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 6ad5ea0..b4b55b83 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2332,7 +2332,7 @@ extern void build_mi_virtuals PROTO((int, int)); extern void add_mi_virtuals PROTO((int, tree)); extern void report_ambiguous_mi_virtuals PROTO((int, tree)); extern void note_debug_info_needed PROTO((tree)); -extern void push_class_decls PROTO((tree, int)); +extern void push_class_decls PROTO((tree)); extern void pop_class_decls PROTO((tree)); extern void unuse_fields PROTO((tree)); extern void unmark_finished_struct PROTO((tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 49eb67e..de18522 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1832,6 +1832,48 @@ struct saved_scope { static struct saved_scope *current_saved_scope; extern tree prev_class_type; +tree +store_bindings (names, old_bindings) + tree names, old_bindings; +{ + tree t; + for (t = names; t; t = TREE_CHAIN (t)) + { + tree binding, t1, id; + + if (TREE_CODE (t) == TREE_LIST) + id = TREE_PURPOSE (t); + else + id = DECL_NAME (t); + + if (!id + || (!IDENTIFIER_LOCAL_VALUE (id) + && !IDENTIFIER_CLASS_VALUE (id))) + continue; + + for (t1 = old_bindings; t1; t1 = TREE_CHAIN (t1)) + if (TREE_VEC_ELT (t1, 0) == id) + goto skip_it; + + binding = make_tree_vec (4); + if (id) + { + my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135); + TREE_VEC_ELT (binding, 0) = id; + TREE_VEC_ELT (binding, 1) = IDENTIFIER_TYPE_VALUE (id); + TREE_VEC_ELT (binding, 2) = IDENTIFIER_LOCAL_VALUE (id); + TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id); + IDENTIFIER_LOCAL_VALUE (id) = NULL_TREE; + IDENTIFIER_CLASS_VALUE (id) = NULL_TREE; + } + TREE_CHAIN (binding) = old_bindings; + old_bindings = binding; + skip_it: + ; + } + return old_bindings; +} + void push_to_top_level () { @@ -1849,37 +1891,13 @@ push_to_top_level () if (b == global_binding_level) continue; - - for (t = b->names; t; t = TREE_CHAIN (t)) - { - tree binding, t1, t2 = t; - tree id = DECL_ASSEMBLER_NAME (t2); - if (!id - || (!IDENTIFIER_LOCAL_VALUE (id) - && !IDENTIFIER_CLASS_VALUE (id))) - continue; + old_bindings = store_bindings (b->names, old_bindings); + /* We also need to check type_shadowed to save class-level type + bindings, since pushclass doesn't fill in b->names. */ + if (b->parm_flag == 2) + old_bindings = store_bindings (b->type_shadowed, old_bindings); - for (t1 = old_bindings; t1; t1 = TREE_CHAIN (t1)) - if (TREE_VEC_ELT (t1, 0) == id) - goto skip_it; - - binding = make_tree_vec (4); - if (id) - { - my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135); - TREE_VEC_ELT (binding, 0) = id; - TREE_VEC_ELT (binding, 1) = IDENTIFIER_TYPE_VALUE (id); - TREE_VEC_ELT (binding, 2) = IDENTIFIER_LOCAL_VALUE (id); - TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id); - IDENTIFIER_LOCAL_VALUE (id) = NULL_TREE; - IDENTIFIER_CLASS_VALUE (id) = NULL_TREE; - } - TREE_CHAIN (binding) = old_bindings; - old_bindings = binding; - skip_it: - ; - } /* Unwind type-value slots back to top level. */ for (t = b->type_shadowed; t; t = TREE_CHAIN (t)) SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t)); @@ -7783,7 +7801,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli innermost_code = TREE_CODE (decl); if (decl_context == FIELD && ctype == NULL_TREE) ctype = current_class_type; - if (ctype && TREE_OPERAND (decl, 0) == ctype) + if (ctype + && (TREE_CODE (TREE_OPERAND (decl, 0)) == TYPE_DECL + && ((DECL_NAME (TREE_OPERAND (decl, 0)) + == constructor_name_full (ctype)) + || (DECL_NAME (TREE_OPERAND (decl, 0)) + == constructor_name (ctype))))) TREE_OPERAND (decl, 0) = constructor_name (ctype); next = &TREE_OPERAND (decl, 0); decl = *next; @@ -7886,23 +7909,26 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli next = 0; break; + case TYPE_DECL: + /* Parse error puts this typespec where + a declarator should go. */ + cp_error ("`%T' specified as declarator-id", DECL_NAME (decl)); + if (TREE_TYPE (decl) == current_class_type) + cp_error (" perhaps you want `%T' for a constructor", + current_class_name); + dname = DECL_NAME (decl); + name = IDENTIFIER_POINTER (dname); + + /* Avoid giving two errors for this. */ + IDENTIFIER_CLASS_VALUE (dname) = NULL_TREE; + + declspecs = temp_tree_cons (NULL_TREE, integer_type_node, + declspecs); + *next = dname; + next = 0; + break; + default: - if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't') - { - /* Parse error puts this typespec where - a declarator should go. */ - error ("typename specified as declarator-id"); - if (current_class_type) - cp_error (" perhaps you want `%T' for a constructor", - current_class_name); - dname = TYPE_IDENTIFIER (decl); - name = dname ? IDENTIFIER_POINTER (dname) : "<nameless>"; - declspecs = temp_tree_cons (NULL_TREE, integer_type_node, - declspecs); - *next = dname; - next = 0; - break; - } cp_compiler_error ("`%D' as declarator", decl); return 0; /* We used to do a 155 abort here. */ } @@ -8031,6 +8057,16 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli } } } + /* C++ aggregate types. */ + else if (TREE_CODE (id) == TYPE_DECL) + { + if (type) + cp_error ("multiple declarations `%T' and `%T'", type, + TREE_TYPE (id)); + else + type = TREE_TYPE (id); + goto found; + } if (type) error ("two or more data types in declaration of `%s'", name); else if (TREE_CODE (id) == IDENTIFIER_NODE) diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 03b8ff9..27f83b0 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1362,7 +1362,7 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist) init = NULL_TREE; value = grokdeclarator (declarator, declspecs, FIELD, init != 0, - raises, attrlist); + raises, NULL_TREE); if (! value) return value; /* friend or constructor went bad. */ @@ -1476,6 +1476,10 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist) /* The corresponding pop_obstacks is in cp_finish_decl. */ push_obstacks_nochange (); + if (attrlist) + cplus_decl_attributes (value, TREE_PURPOSE (attrlist), + TREE_VALUE (attrlist)); + if (TREE_CODE (value) == VAR_DECL) { /* We cannot call pushdecl here, because that would @@ -1616,6 +1620,9 @@ grokbitfield (declarator, declspecs, width) if (width != error_mark_node) { + /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs. */ + STRIP_NOPS (width); + /* detect invalid field size. */ if (TREE_CODE (width) == CONST_DECL) width = DECL_INITIAL (width); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index e114414..d10fb16 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -930,10 +930,10 @@ expand_member_init (exp, name, init) type = TYPE_MAIN_VARIANT (TREE_TYPE (exp)); - if (TREE_CODE_CLASS (TREE_CODE (name)) == 't') + if (TREE_CODE (name) == TYPE_DECL) { - basetype = name; - name = TYPE_IDENTIFIER (name); + basetype = TREE_TYPE (name); + name = DECL_NAME (name); } if (name == NULL_TREE && IS_AGGR_TYPE (type)) diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index e3c2607..b3c8edc 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -2349,7 +2349,7 @@ base_class_list: base_class: base_class.1 { - tree type = $1; + tree type = TREE_TYPE ($1); if (! is_aggr_type (type, 1)) $$ = NULL_TREE; else if (current_aggr == signature_type_node @@ -2362,7 +2362,7 @@ base_class: { sorry ("signature inheritance, base type `%s' ignored", IDENTIFIER_POINTER ($$)); - $$ = build_tree_list (access_public_node, $$); + $$ = build_tree_list (access_public_node, type); } else if (type && IS_SIGNATURE (type)) { @@ -2370,11 +2370,11 @@ base_class: $$ = NULL_TREE; } else - $$ = build_tree_list (access_default_node, $$); + $$ = build_tree_list (access_default_node, type); } | base_class_access_list see_typename base_class.1 { - tree type = $3; + tree type = TREE_TYPE ($3); if (current_aggr == signature_type_node) error ("access and source specifiers not allowed in signature"); if (! IS_AGGR_TYPE (type)) @@ -2389,7 +2389,7 @@ base_class: { sorry ("signature inheritance, base type `%s' ignored", IDENTIFIER_POINTER ($$)); - $$ = build_tree_list (access_public_node, $3); + $$ = build_tree_list (access_public_node, type); } else if (type && IS_SIGNATURE (type)) { @@ -2397,7 +2397,7 @@ base_class: $$ = NULL_TREE; } else - $$ = build_tree_list ($$, $3); + $$ = build_tree_list ($$, type); } ; @@ -2857,20 +2857,25 @@ after_type_declarator: qualified_type_name: type_name %prec EMPTY { - $$ = TREE_TYPE ($1); + $$ = identifier_typedecl_value ($1); /* Remember that this name has been used in the class definition, as per [class.scope0] */ if (current_class_type && TYPE_BEING_DEFINED (current_class_type) + && ! IDENTIFIER_TEMPLATE ($1) && ! IDENTIFIER_CLASS_VALUE ($1)) - pushdecl_class_level (lookup_name ($1, -2)); + { + /* Be sure to get an inherited typedef. */ + $$ = lookup_name ($1, 1); + pushdecl_class_level ($$); + } } | nested_type ; nested_type: nested_name_specifier type_name %prec EMPTY - { $$ = TREE_TYPE ($2); } + { $$ = identifier_typedecl_value ($2); } ; direct_after_type_declarator: @@ -2984,7 +2989,17 @@ nested_name_specifier: inline here?!? (jason) */ nested_name_specifier_1: TYPENAME SCOPE - { got_scope = $$ = TREE_TYPE ($1); } + { + $$ = lastiddecl; + /* Remember that this name has been used in the class + definition, as per [class.scope0] */ + if (current_class_type + && TYPE_BEING_DEFINED (current_class_type) + && ! TREE_MANGLED ($1) + && ! IDENTIFIER_CLASS_VALUE ($1)) + pushdecl_class_level ($$); + got_scope = $$ = TREE_TYPE ($$); + } | NSNAME SCOPE { got_scope = $$ = $1; } | template_type SCOPE diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 110eaed..208cc0a 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2663,7 +2663,10 @@ virtual_context (fndecl, t, vbase) they may upcast into a direct base, or they may upcast into a different vbase. - We only need to do fixups in case 2 and 3. + We only need to do fixups in case 2 and 3. In case 2, we add in + the virtual base offset to effect an upcast, in case 3, we add in + the virtual base offset to effect an upcast, then subtract out the + offset for the other virtual base, to effect a downcast into it. This routine mirrors fixup_vtable_deltas in functionality, though this one is runtime based, and the other is compile time based. @@ -2671,10 +2674,14 @@ virtual_context (fndecl, t, vbase) done at runtime. VBASE_OFFSETS is an association list of virtual bases that contains - offset information, so the offsets are only calculated once. */ + offset information for the virtual bases, so the offsets are only + calculated once. The offsets are computed by where we think the + vbase should be (as noted by the CLASSTYPE_SEARCH_SLOT) minus where + the vbase really is. */ static void -expand_upcast_fixups (binfo, addr, orig_addr, vbase, t, vbase_offsets) - tree binfo, addr, orig_addr, vbase, t, *vbase_offsets; +expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t, + vbase_offsets) + tree binfo, addr, orig_addr, vbase, vbase_addr, t, *vbase_offsets; { tree virtuals = BINFO_VIRTUALS (binfo); tree vc; @@ -2685,7 +2692,7 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, t, vbase_offsets) if (! delta) { delta = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbase)); - delta = build (MINUS_EXPR, ptrdiff_type_node, delta, addr); + delta = build (MINUS_EXPR, ptrdiff_type_node, delta, vbase_addr); delta = save_expr (delta); delta = tree_cons (vbase, delta, *vbase_offsets); *vbase_offsets = delta; @@ -2739,26 +2746,32 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, t, vbase_offsets) naref = build_array_ref (nvtbl, idx); old_delta = build_component_ref (aref, delta_identifier, 0, 0); new_delta = build_component_ref (naref, delta_identifier, 0, 0); + + /* This is a upcast, so we have to add the offset for the + virtual base. */ old_delta = build_binary_op (PLUS_EXPR, old_delta, TREE_VALUE (delta), 0); if (vc) { - /* If this is set, we need to add in delta adjustments for - the other virtual base. */ + /* If this is set, we need to subtract out the delta + adjustments for the other virtual base that we + downcast into. */ tree vc_delta = purpose_member (vc, *vbase_offsets); if (! vc_delta) { tree vc_addr = convert_pointer_to_real (vc, orig_addr); vc_delta = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vc)); vc_delta = build (MINUS_EXPR, ptrdiff_type_node, - vc_addr, vc_delta); + vc_delta, vc_addr); vc_delta = save_expr (vc_delta); *vbase_offsets = tree_cons (vc, vc_delta, *vbase_offsets); } else vc_delta = TREE_VALUE (vc_delta); - old_delta = build_binary_op (PLUS_EXPR, old_delta, vc_delta, 0); + /* This is a downcast, so we have to subtract the offset + for the virtual base. */ + old_delta = build_binary_op (MINUS_EXPR, old_delta, vc_delta, 0); } TREE_READONLY (new_delta) = 0; @@ -2800,8 +2813,9 @@ fixup_virtual_upcast_offsets (real_binfo, binfo, init_self, can_elide, addr, ori /* Should we use something besides CLASSTYPE_VFIELDS? */ if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo))) { - addr = convert_pointer_to_real (binfo, addr); - expand_upcast_fixups (real_binfo, addr, orig_addr, vbase, type, vbase_offsets); + tree new_addr = convert_pointer_to_real (binfo, addr); + expand_upcast_fixups (real_binfo, new_addr, orig_addr, vbase, addr, + type, vbase_offsets); } } @@ -3334,14 +3348,10 @@ dfs_compress_decls (binfo) lattice. Where ambiguities result, we mark them with `error_mark_node' so that if they are encountered without explicit qualification, we can emit an error - message. - - ONLY_TYPES is set when defining TYPE so that inherited types are visible - in the derived class. */ + message. */ void -push_class_decls (type, only_types) +push_class_decls (type) tree type; - int only_types; { tree id; struct obstack *ambient_obstack = current_obstack; @@ -3396,12 +3406,7 @@ push_class_decls (type, only_types) /* Install the original class value in order to make pushdecl_class_level work correctly. */ IDENTIFIER_CLASS_VALUE (id) = TREE_VALUE (closed_envelopes); - if (only_types) - { - if (TREE_CODE (new) == TYPE_DECL) - set_identifier_type_value (id, TREE_TYPE (new)); - } - else if (TREE_CODE (new) == TREE_LIST) + if (TREE_CODE (new) == TREE_LIST) push_class_level_binding (id, new); else pushdecl_class_level (new); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index be0fc99..d0f27f9 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1579,7 +1579,7 @@ build_exception_variant (type, raises) int constp = TYPE_READONLY (type); int volatilep = TYPE_VOLATILE (type); - for (v = TYPE_NEXT_VARIANT (v); v; v = TYPE_NEXT_VARIANT (v)) + for (; v; v = TYPE_NEXT_VARIANT (v)) { if (TYPE_READONLY (v) != constp || TYPE_VOLATILE (v) != volatilep) @@ -1595,9 +1595,8 @@ build_exception_variant (type, raises) } /* Need to build a new variant. */ - v = copy_node (type); - TYPE_NEXT_VARIANT (v) = TYPE_NEXT_VARIANT (type); - TYPE_NEXT_VARIANT (type) = v; + v = build_type_copy (type); + if (raises && ! TREE_PERMANENT (raises)) { push_obstacks_nochange (); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 9901080..9e5f4e6 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1539,7 +1539,7 @@ build_object_ref (datum, basetype, field) } else if (is_aggr_type (basetype, 1)) { - tree binfo = binfo_or_else (basetype, TREE_TYPE (datum)); + tree binfo = binfo_or_else (basetype, dtype); if (binfo) return build_component_ref (build_scoped_ref (datum, basetype), field, binfo, 1); @@ -1825,7 +1825,16 @@ build_component_ref (datum, component, basetype_path, protect) error ("invalid reference to NULL ptr, use ptr-to-member instead"); return error_mark_node; } - addr = convert_pointer_to (DECL_FIELD_CONTEXT (field), addr); + if (VBASE_NAME_P (DECL_NAME (field))) + { + /* It doesn't matter which vbase pointer we grab, just + find one of them. */ + tree binfo = get_binfo (DECL_FIELD_CONTEXT (field), + TREE_TYPE (TREE_TYPE (addr)), 0); + addr = convert_pointer_to_real (binfo, addr); + } + else + addr = convert_pointer_to (DECL_FIELD_CONTEXT (field), addr); datum = build_indirect_ref (addr, NULL_PTR); my_friendly_assert (datum != error_mark_node, 311); } @@ -5831,7 +5840,7 @@ build_modify_expr (lhs, modifycode, rhs) if (build_default_binary_type_conversion (modifycode, &lhs_tmp, &rhs_tmp)) { lhs = stabilize_reference (lhs_tmp); - /* Forget is was ever anything else. */ + /* Forget it was ever anything else. */ olhstype = lhstype = TREE_TYPE (lhs); newrhs = build_binary_op (modifycode, lhs, rhs_tmp, 1); } diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index a2f8172..69d003d 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1440,6 +1440,8 @@ build_functional_cast (exp, parms) type = TREE_TYPE (type); } } + else if (TREE_CODE (exp) == TYPE_DECL) + type = TREE_TYPE (exp); else type = exp; @@ -1449,20 +1451,6 @@ build_functional_cast (exp, parms) return error_mark_node; } - /* Prepare to evaluate as a call to a constructor. If this expression - is actually used, for example, - - return X (arg1, arg2, ...); - - then the slot being initialized will be filled in. */ - - if (name == NULL_TREE) - { - name = TYPE_NAME (type); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NESTED_TYPENAME (name); - } - if (! IS_AGGR_TYPE (type)) { /* this must build a C cast */ @@ -1478,6 +1466,20 @@ build_functional_cast (exp, parms) return build_c_cast (type, parms, 1); } + /* Prepare to evaluate as a call to a constructor. If this expression + is actually used, for example, + + return X (arg1, arg2, ...); + + then the slot being initialized will be filled in. */ + + if (name == NULL_TREE) + { + name = TYPE_NAME (type); + if (TREE_CODE (name) == TYPE_DECL) + name = DECL_NESTED_TYPENAME (name); + } + if (TYPE_SIZE (type) == NULL_TREE) { cp_error ("type `%T' is not yet defined", type); |