diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 446199364aa..7044d92c537 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,33 @@ +1998-08-27 Mark Mitchell + + * class.c (build_vbase_path): Use reverse_path. + (finish_base_struct): Move warnings for inaccessible bases to + layout_basetypes. + (modify_one_vtable): Remove check of TREE_USED (binfo). + (fixup_vtable_deltas1): Likewise. + * cp-tree.h (BINFO_INHERITANCE_CHAIN): Document here. + (xref_tag): Remove binfos parameter. + (make_binfo): Remove chain parameter. + (reverse_path): Add copy parameter. + * decl.c (init_decl_processing): Change calls to xref_tag. + (xref_tag): Remove binfos parameter. + (xref_basetypes): Change calls to make_binfo. + * decl2.c (grok_x_components): Change calls to xref_tag. + (handle_class_head): Likewise. + * friend.c (do_friend): Likewise. + * lex.c (make_lang_type): Change calls to make_binfo. + * parse.y (structsp): Change calls to xref_tag. + (named_complex_class_head_sans_basetype): Likewise. + (named_class_head): Likewise. + * rtti.c (init_rtti_processing): Likewise. + * search.c (compute_access): Change calls to reverse_path. + (dfs_get_vbase_types): Change calls to make_binfo. + (get_vbase_types): Remove dead code. + * tree.c (unshare_base_binfos): Change calls to make_binfo. + (layout_basetypes): Warn here about inaccessible bases. + (make_binfo): Remove chain parameter. + (reverse_path): Add copy parameter. + 1998-08-27 Jason Merrill * class.c: #if 0 complete_type_p. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index e86638eeda9..66b91436521 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -266,17 +266,8 @@ build_vbase_path (code, type, expr, path, nonnull) if (BINFO_INHERITANCE_CHAIN (path)) { - tree reverse_path = NULL_TREE; - push_expression_obstack (); - while (path) - { - tree r = copy_node (path); - BINFO_INHERITANCE_CHAIN (r) = reverse_path; - reverse_path = r; - path = BINFO_INHERITANCE_CHAIN (path); - } - path = reverse_path; + path = reverse_path (path, /*copy=*/1); pop_obstacks (); } @@ -1758,35 +1749,6 @@ finish_base_struct (t, b) } } - /* This comment said "Must come after offsets are fixed for all bases." - Well, now this happens before the offsets are fixed, but it seems to - work fine. Guess we'll see... */ - for (i = 0; i < n_baseclasses; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree basetype = BINFO_TYPE (base_binfo); - - if (get_base_distance (basetype, t, 0, (tree*)0) == -2) - { - cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity", - basetype, t); - } - } - { - tree v = get_vbase_types (t); - - for (; v; v = TREE_CHAIN (v)) - { - tree basetype = BINFO_TYPE (v); - if (get_base_distance (basetype, t, 0, (tree*)0) == -2) - { - if (extra_warnings) - cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity", - basetype, t); - } - } - } - { tree vfields; /* Find the base class with the largest number of virtual functions. */ @@ -2413,10 +2375,6 @@ modify_one_vtable (binfo, t, fndecl, pfn) BINFO_OFFSET (binfo)); this_offset = ssize_binop (MINUS_EXPR, offset, base_offset); - /* Make sure we can modify the derived association with immunity. */ - if (TREE_USED (binfo)) - my_friendly_assert (0, 999); - if (binfo == TYPE_BINFO (t)) { /* In this case, it is *type*'s vtable we are modifying. @@ -2516,9 +2474,6 @@ fixup_vtable_deltas1 (binfo, t) if (! tree_int_cst_equal (this_offset, delta)) { /* Make sure we can modify the derived association with immunity. */ - if (TREE_USED (binfo)) - my_friendly_assert (0, 999); - if (binfo == TYPE_BINFO (t)) { /* In this case, it is *type*'s vtable we are modifying. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 85d983cca3a..532a5147c75 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -966,6 +966,16 @@ struct lang_type /* Additional macros for inheritance information. */ +/* The BINFO_INHERITANCE_CHAIN is used opposite to the description in + gcc/tree.h. In particular if D is derived from B then the BINFO + for B (in D) will have a BINFO_INHERITANCE_CHAIN pointing to + D. In tree.h, this pointer is described as pointing in other + direction. + + After a call to get_vbase_types, the vbases are chained together in + depth-first order via TREE_CHAIN. Other than that, TREE_CHAIN is + unused. */ + #ifdef MI_MATRIX /* When building a matrix to determine by a single lookup whether one class is derived from another or not, @@ -2548,7 +2558,7 @@ extern int parmlist_is_exprlist PROTO((tree)); extern int copy_args_p PROTO((tree)); extern int grok_ctor_properties PROTO((tree, tree)); extern void grok_op_properties PROTO((tree, int, int)); -extern tree xref_tag PROTO((tree, tree, tree, int)); +extern tree xref_tag PROTO((tree, tree, int)); extern tree xref_tag_from_type PROTO((tree, tree, int)); extern void xref_basetypes PROTO((tree, tree, tree, tree)); extern tree start_enum PROTO((tree)); @@ -3005,9 +3015,9 @@ extern tree hash_tree_cons PROTO((int, int, int, tree, tree, tree)); extern tree hash_tree_chain PROTO((tree, tree)); extern tree hash_chainon PROTO((tree, tree)); extern tree get_decl_list PROTO((tree)); -extern tree make_binfo PROTO((tree, tree, tree, tree, tree)); +extern tree make_binfo PROTO((tree, tree, tree, tree)); extern tree binfo_value PROTO((tree, tree)); -extern tree reverse_path PROTO((tree)); +extern tree reverse_path PROTO((tree, int)); extern int count_functions PROTO((tree)); extern int is_overloaded_fn PROTO((tree)); extern tree get_first_fn PROTO((tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index ad52979fb8e..8e3b0722b86 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6166,7 +6166,7 @@ init_decl_processing () if (flag_honor_std) push_namespace (get_identifier ("std")); bad_alloc_type_node = xref_tag - (class_type_node, get_identifier ("bad_alloc"), NULL_TREE, 1); + (class_type_node, get_identifier ("bad_alloc"), 1); if (flag_honor_std) pop_namespace (); newtype = build_exception_variant @@ -11415,9 +11415,9 @@ grok_op_properties (decl, virtualp, friendp) scope.) */ tree -xref_tag (code_type_node, name, binfo, globalize) +xref_tag (code_type_node, name, globalize) tree code_type_node; - tree name, binfo; + tree name; int globalize; { enum tag_types tag_code; @@ -11623,9 +11623,6 @@ xref_tag (code_type_node, name, binfo, globalize) redeclare_class_template (ref, current_template_parms); } - if (binfo) - xref_basetypes (code_type_node, name, ref, binfo); - /* Until the type is defined, tentatively accept whatever structure tag the user hands us. */ if (TYPE_SIZE (ref) == NULL_TREE @@ -11662,7 +11659,7 @@ xref_tag_from_type (old, id, globalize) if (id == NULL_TREE) id = TYPE_IDENTIFIER (old); - return xref_tag (code_type_node, id, NULL_TREE, globalize); + return xref_tag (code_type_node, id, globalize); } void @@ -11759,7 +11756,7 @@ xref_basetypes (code_type_node, name, ref, binfo) base_binfo = make_binfo (integer_zero_node, basetype, TYPE_BINFO_VTABLE (basetype), - TYPE_BINFO_VIRTUALS (basetype), NULL_TREE); + TYPE_BINFO_VIRTUALS (basetype)); TREE_VEC_ELT (binfos, i) = base_binfo; TREE_VIA_PUBLIC (base_binfo) = via_public; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index b8c4370ceb9..098c8435c9d 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -945,7 +945,7 @@ grok_x_components (specs, components) x = DECL_NAME (CLASSTYPE_TI_TEMPLATE (t)); else x = TYPE_IDENTIFIER (t); - t = xref_tag (tcode, x, NULL_TREE, 0); + t = xref_tag (tcode, x, 0); } if (ANON_UNION_TYPE_P (t)) @@ -989,7 +989,7 @@ grok_x_components (specs, components) case ENUMERAL_TYPE: tcode = enum_type_node; - t = xref_tag (tcode, TYPE_IDENTIFIER (t), NULL_TREE, 0); + t = xref_tag (tcode, TYPE_IDENTIFIER (t), 0); x = grok_enum_decls (NULL_TREE); return x; break; @@ -4943,6 +4943,6 @@ handle_class_head (aggr, scope, id) cp_error ("no file-scope type named `%D'", id); id = xref_tag - (aggr, make_anon_name (), NULL_TREE, 1); + (aggr, make_anon_name (), 1); return TYPE_MAIN_DECL (id); } diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index a566d0504f5..561c9d747b3 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -476,7 +476,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag) if (decl == NULL_TREE) { cp_warning ("implicitly declaring `%T' as struct", declarator); - decl = xref_tag (record_type_node, declarator, NULL_TREE, 1); + decl = xref_tag (record_type_node, declarator, 1); decl = TYPE_MAIN_DECL (decl); } diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 8cd3eb54c6d..9d8f2d2ad06 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -4623,8 +4623,7 @@ make_lang_type (code) CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t); SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE, - NULL_TREE); + TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE); CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t)); /* Make sure this is laid out, for ease of use later. diff --git a/gcc/cp/parse.c b/gcc/cp/parse.c index 5ae0a84275e..f64a24f8c80 100644 --- a/gcc/cp/parse.c +++ b/gcc/cp/parse.c @@ -3589,7 +3589,7 @@ static const short yycheck[] = { 4, 77, 78, 79, 80, 81, 82, 83, 84 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/cygnus/gnupro-98r1/share/bison.simple" +#line 3 "/usr/lib/bison.simple" /* Skeleton output parser for bison, Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. @@ -3782,7 +3782,7 @@ __yy_memcpy (char *to, char *from, int count) #endif #endif -#line 196 "/usr/cygnus/gnupro-98r1/share/bison.simple" +#line 196 "/usr/lib/bison.simple" /* The user can define YYPARSE_PARAM as the name of an argument to be passed into yyparse. The argument should have type void *. @@ -6003,12 +6003,12 @@ case 470: break;} case 471: #line 2086 "parse.y" -{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, NULL_TREE, 1); +{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, 1); yyval.ftype.new_type_flag = 0; ; break;} case 472: #line 2089 "parse.y" -{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, NULL_TREE, 1); +{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, 1); yyval.ftype.new_type_flag = 0; ; break;} case 473: @@ -6130,11 +6130,11 @@ case 496: break;} case 497: #line 2196 "parse.y" -{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, NULL_TREE, 0); ; +{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, 0); ; break;} case 498: #line 2201 "parse.y" -{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, NULL_TREE, 1); ; +{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, 1); ; break;} case 499: #line 2204 "parse.y" @@ -6163,7 +6163,7 @@ case 500: break;} case 501: #line 2228 "parse.y" -{ yyval.ttype = xref_tag (yyval.ttype, make_anon_name (), NULL_TREE, 0); +{ yyval.ttype = xref_tag (yyval.ttype, make_anon_name (), 0); yyungetc ('{', 1); ; break;} case 504: @@ -7828,7 +7828,7 @@ case 870: break;} } /* the action file gets copied in in place of this dollarsign */ -#line 498 "/usr/cygnus/gnupro-98r1/share/bison.simple" +#line 498 "/usr/lib/bison.simple" yyvsp -= yylen; yyssp -= yylen; diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index c9842f9546f..022e50b2854 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -2083,10 +2083,10 @@ structsp: $$.new_type_flag = 1; check_for_missing_semicolon ($$.t); } | ENUM identifier - { $$.t = xref_tag (enum_type_node, $2, NULL_TREE, 1); + { $$.t = xref_tag (enum_type_node, $2, 1); $$.new_type_flag = 0; } | ENUM complex_type_name - { $$.t = xref_tag (enum_type_node, $2, NULL_TREE, 1); + { $$.t = xref_tag (enum_type_node, $2, 1); $$.new_type_flag = 0; } | TYPENAME_KEYWORD typename_sub { $$.t = $2; @@ -2193,12 +2193,12 @@ named_complex_class_head_sans_basetype: do_xref_defn: /* empty */ %prec EMPTY - { $$ = xref_tag (current_aggr, $0, NULL_TREE, 0); } + { $$ = xref_tag (current_aggr, $0, 0); } ; named_class_head: named_class_head_sans_basetype %prec EMPTY - { $$ = xref_tag (current_aggr, $1, NULL_TREE, 1); } + { $$ = xref_tag (current_aggr, $1, 1); } | named_class_head_sans_basetype_defn do_xref_defn maybe_base_class_list %prec EMPTY { @@ -2225,7 +2225,7 @@ named_class_head: unnamed_class_head: aggr '{' - { $$ = xref_tag ($$, make_anon_name (), NULL_TREE, 0); + { $$ = xref_tag ($$, make_anon_name (), 0); yyungetc ('{', 1); } ; diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 0087bc39467..01c4a861ec2 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -60,7 +60,7 @@ init_rtti_processing () if (flag_honor_std) push_namespace (get_identifier ("std")); type_info_type_node = xref_tag - (class_type_node, get_identifier ("type_info"), NULL_TREE, 1); + (class_type_node, get_identifier ("type_info"), 1); if (flag_honor_std) pop_namespace (); tinfo_fn_id = get_identifier ("__tf"); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 1d0f1c34920..8e29bc1a2c5 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1003,7 +1003,7 @@ compute_access (basetype_path, field) } /* must reverse more than one element */ - basetype_path = reverse_path (basetype_path); + basetype_path = reverse_path (basetype_path, /*copy=*/0); types = basetype_path; via_protected = 0; access = access_default_node; @@ -1049,7 +1049,7 @@ compute_access (basetype_path, field) else break; } - reverse_path (basetype_path); + reverse_path (basetype_path, /*copy=*/0); /* No special visibilities apply. Use normal rules. */ @@ -3196,10 +3196,12 @@ dfs_get_vbase_types (binfo) { if (TREE_VIA_VIRTUAL (binfo) && ! BINFO_VBASE_MARKED (binfo)) { - vbase_types = make_binfo (integer_zero_node, binfo, - BINFO_VTABLE (binfo), - BINFO_VIRTUALS (binfo), vbase_types); - TREE_VIA_VIRTUAL (vbase_types) = 1; + tree new_vbase = make_binfo (integer_zero_node, binfo, + BINFO_VTABLE (binfo), + BINFO_VIRTUALS (binfo)); + TREE_CHAIN (new_vbase) = vbase_types; + TREE_VIA_VIRTUAL (new_vbase) = 1; + vbase_types = new_vbase; SET_BINFO_VBASE_MARKED (binfo); } SET_BINFO_MARKED (binfo); @@ -3214,11 +3216,7 @@ get_vbase_types (type) tree vbases; tree binfo; - if (TREE_CODE (type) == TREE_VEC) - binfo = type; - else - binfo = TYPE_BINFO (type); - + binfo = TYPE_BINFO (type); vbase_types = NULL_TREE; dfs_walk (binfo, dfs_get_vbase_types, unmarkedp); dfs_walk (binfo, dfs_unmark, markedp); @@ -4004,3 +4002,4 @@ types_overlap_p (empty_type, next_type) dfs_walk (TYPE_BINFO (empty_type), dfs_check_overlap, dfs_no_overlap_yet); return found_overlap; } + diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 6f33ec86d10..feb1a44180f 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -646,8 +646,7 @@ unshare_base_binfos (base_binfo) = make_binfo (BINFO_OFFSET (base_base_binfo), base_base_binfo, BINFO_VTABLE (base_base_binfo), - BINFO_VIRTUALS (base_base_binfo), - chain); + BINFO_VIRTUALS (base_base_binfo)); chain = TREE_VEC_ELT (base_binfos, j); TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo); TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo); @@ -677,9 +676,7 @@ layout_basetypes (rec, max) tree binfos = TYPE_BINFO_BASETYPES (rec); int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - /* Get all the virtual base types that this type uses. - The TREE_VALUE slot holds the virtual baseclass type. */ - tree vbase_types = get_vbase_types (rec); + tree vbase_types; unsigned int record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec)); unsigned int desired_align; @@ -694,7 +691,11 @@ layout_basetypes (rec, max) record_align = MAX (record_align, STRUCTURE_SIZE_BOUNDARY); #endif - CLASSTYPE_VBASECLASSES (rec) = vbase_types; + /* Get all the virtual base types that this type uses. The + TREE_VALUE slot holds the virtual baseclass type. Note that + get_vbase_types makes copies of the virtual base BINFOs, so that + the vbase_types are unshared. */ + CLASSTYPE_VBASECLASSES (rec) = vbase_types = get_vbase_types (rec); my_friendly_assert (TREE_CODE (TYPE_SIZE (rec)) == INTEGER_CST, 19970302); const_size = TREE_INT_CST_LOW (TYPE_SIZE (rec)); @@ -761,6 +762,11 @@ layout_basetypes (rec, max) else { my_friendly_assert (TREE_TYPE (field) == basetype, 23897); + + if (get_base_distance (basetype, rec, 0, (tree*)0) == -2) + cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity", + basetype, rec); + BINFO_OFFSET (base_binfo) = size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)), BITS_PER_UNIT)); @@ -774,6 +780,14 @@ layout_basetypes (rec, max) { BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec); unshare_base_binfos (vbase_types); + + if (extra_warnings) + { + tree basetype = BINFO_TYPE (vbase_types); + if (get_base_distance (basetype, rec, 0, (tree*)0) == -2) + cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity", + basetype, rec); + } } return max; @@ -1198,15 +1212,12 @@ get_decl_list (value) VTABLE is the virtual function table with which to initialize sub-objects of type TYPE. - VIRTUALS are the virtual functions sitting in VTABLE. - - CHAIN are more associations we must retain. */ + VIRTUALS are the virtual functions sitting in VTABLE. */ tree -make_binfo (offset, binfo, vtable, virtuals, chain) +make_binfo (offset, binfo, vtable, virtuals) tree offset, binfo; tree vtable, virtuals; - tree chain; { tree new_binfo = make_tree_vec (7); tree type; @@ -1219,10 +1230,6 @@ make_binfo (offset, binfo, vtable, virtuals, chain) binfo = TYPE_BINFO (binfo); } - TREE_CHAIN (new_binfo) = chain; - if (chain) - TREE_USED (new_binfo) = TREE_USED (chain); - TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type); BINFO_OFFSET (new_binfo) = offset; BINFO_VTABLE (new_binfo) = vtable; @@ -1251,13 +1258,22 @@ binfo_value (elem, type) return get_binfo (elem, type, 0); } +/* Reverse the BINFO-chain given by PATH. (If the + BINFO_INHERITANCE_CHAIN points from base classes to derived + classes, it will instead point from derived classes to base + classes.) Returns the first node in the reversed chain. If COPY + is non-zero, the nodes are copied as the chain is traversed. */ + tree -reverse_path (path) +reverse_path (path, copy) tree path; + int copy; { register tree prev = 0, tmp, next; for (tmp = path; tmp; tmp = next) { + if (copy) + tmp = copy_node (tmp); next = BINFO_INHERITANCE_CHAIN (tmp); BINFO_INHERITANCE_CHAIN (tmp) = prev; prev = tmp; diff --git a/gcc/testsuite/g++.old-deja/g++.other/lookup2.C b/gcc/testsuite/g++.old-deja/g++.other/lookup2.C new file mode 100644 index 00000000000..0772399222d --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/lookup2.C @@ -0,0 +1,13 @@ +// Build don't link: + +struct B { + int i; +}; + +struct D: virtual public B { + int i; +}; + +struct D2 : public D { + void f() { i = 3; } +}; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/lookup5.C b/gcc/testsuite/g++.old-deja/g++.pt/lookup5.C new file mode 100644 index 00000000000..e38b2227487 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/lookup5.C @@ -0,0 +1,14 @@ +// Build don't link: + +struct B { + int i; +}; + +struct D: public B { + int i; +}; + +template +struct D2 : public D { + void f() { i = 3; } +};