aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMike Stump <mrs@gcc.gnu.org>1996-01-22 19:49:02 +0000
committerMike Stump <mrs@gcc.gnu.org>1996-01-22 19:49:02 +0000
commit455376771ffd21a96482f501e0b951a6d95e883d (patch)
tree72df105a5167566b5f363fefcb9ecf25a496676f /gcc
parentf589b741f98dc838c4ea9296e052b74be7b9e983 (diff)
downloadgcc-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/ChangeLog60
-rw-r--r--gcc/cp/class.c8
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c128
-rw-r--r--gcc/cp/decl2.c9
-rw-r--r--gcc/cp/init.c6
-rw-r--r--gcc/cp/parse.y35
-rw-r--r--gcc/cp/search.c51
-rw-r--r--gcc/cp/tree.c7
-rw-r--r--gcc/cp/typeck.c15
-rw-r--r--gcc/cp/typeck2.c30
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);