From: Nathan Sidwell Date: Mon, 12 Jul 2004 16:06:40 +0000 (+0000) Subject: call.c (build_user_type_conversion_1, [...]): Pass type directly to lookup_fnfields... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cad7e87b1191e2b96f22ca5b12cddc528e364340;p=gcc.git call.c (build_user_type_conversion_1, [...]): Pass type directly to lookup_fnfields & build_special_member_call. * call.c (build_user_type_conversion_1, build_new_op, check_constructor_callable, build_temp, perform_direct_initialization_of_possible): Pass type directly to lookup_fnfields & build_special_member_call. (build_special_member_call): Accept a type, and complete it. * class.c (finish_stuct_bits): Copy the BINFOs here. * cvt.c (ocp_convert): Pass type directly to build_special_member_call. * decl.c (build_ptrmemfunc_type): Call xref_bastypes here. (xref_basetypes): Allocate the binfo here. Adjust. * init.c (build_init, build_new_1): Pass type directly to build_special_member_call. * lex.c (cxx_make_type): Do not allocate binfo here. * name-lookup.c (arg_assoc_class): Incomplete types have no binfo. * parser.c (cp_parser_class_head): Always call xref_basetypes. * pt.c (instantiate_class_template): Likewise. Inhibit access checking for template friends. * ptree.c (cxx_print_type): Adjust record printing. * search.c (lookup_base): When taking a type, complete it before looking for a binfo. (lookup_member): Delay completing a type. (push_class_decls): Don't walk an incomplete type. (lookup_conversions): Likewise. * semantics.c (finish_stmt_expr_expr): Pass type directly to build_special_member_call. * tree.c (copy_base_binfos): Adjust. (make_binfo): Likewise. * typeck.c (build_modify_expr): Pass type directly to build_special_member_call. * typeck2.c (process_init_constructor): Check a binfo exists. (build_m_component_ref): Allow accessing an incomplete type. (build_functional_cast): Pass type directly to build_special_member_call. From-SVN: r84562 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4b80aa6d5aa..392a7321c52 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,39 @@ +2004-07-12 Nathan Sidwell + + * call.c (build_user_type_conversion_1, build_new_op, + check_constructor_callable, build_temp, + perform_direct_initialization_of_possible): Pass type directly to + lookup_fnfields & build_special_member_call. + (build_special_member_call): Accept a type, and complete it. + * class.c (finish_stuct_bits): Copy the BINFOs here. + * cvt.c (ocp_convert): Pass type directly to + build_special_member_call. + * decl.c (build_ptrmemfunc_type): Call xref_bastypes here. + (xref_basetypes): Allocate the binfo here. Adjust. + * init.c (build_init, build_new_1): Pass type directly to + build_special_member_call. + * lex.c (cxx_make_type): Do not allocate binfo here. + * name-lookup.c (arg_assoc_class): Incomplete types have no binfo. + * parser.c (cp_parser_class_head): Always call xref_basetypes. + * pt.c (instantiate_class_template): Likewise. Inhibit access + checking for template friends. + * ptree.c (cxx_print_type): Adjust record printing. + * search.c (lookup_base): When taking a type, complete it before + looking for a binfo. + (lookup_member): Delay completing a type. + (push_class_decls): Don't walk an incomplete type. + (lookup_conversions): Likewise. + * semantics.c (finish_stmt_expr_expr): Pass type directly to + build_special_member_call. + * tree.c (copy_base_binfos): Adjust. + (make_binfo): Likewise. + * typeck.c (build_modify_expr): Pass type directly to + build_special_member_call. + * typeck2.c (process_init_constructor): Check a binfo exists. + (build_m_component_ref): Allow accessing an incomplete type. + (build_functional_cast): Pass type directly to + build_special_member_call. + 2004-07-12 Giovanni Bajo PR c++/2204 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index b4f4dbbcab0..d2a17d9a7ed 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -2500,9 +2500,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) || !DERIVED_FROM_P (totype, fromtype), 20011226); if (IS_AGGR_TYPE (totype)) - ctors = lookup_fnfields (TYPE_BINFO (totype), - complete_ctor_identifier, - 0); + ctors = lookup_fnfields (totype, complete_ctor_identifier, 0); if (IS_AGGR_TYPE (fromtype)) conv_fns = lookup_conversions (fromtype); @@ -3650,7 +3648,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, { tree fns; - fns = lookup_fnfields (TYPE_BINFO (TREE_TYPE (arg1)), fnname, 1); + fns = lookup_fnfields (TREE_TYPE (arg1), fnname, 1); if (fns == error_mark_node) { result = error_mark_node; @@ -4092,7 +4090,7 @@ check_constructor_callable (tree type, tree expr) build_special_member_call (NULL_TREE, complete_ctor_identifier, build_tree_list (NULL_TREE, expr), - TYPE_BINFO (type), + type, LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING | LOOKUP_CONSTRUCTOR_CALLABLE); } @@ -4113,8 +4111,7 @@ build_temp (tree expr, tree type, int flags, expr = build_special_member_call (NULL_TREE, complete_ctor_identifier, build_tree_list (NULL_TREE, expr), - TYPE_BINFO (type), - flags); + type, flags); if (warningcount > savew) *diagnostic_fn = warning; else if (errorcount > savee) @@ -5014,6 +5011,15 @@ build_special_member_call (tree instance, tree name, tree args, || name == deleting_dtor_identifier || name == ansi_assopname (NOP_EXPR), 20020712); + if (TYPE_P (binfo)) + { + /* Resolve the name. */ + if (!complete_type_or_else (binfo, NULL_TREE)) + return error_mark_node; + + binfo = TYPE_BINFO (binfo); + } + my_friendly_assert (binfo != NULL_TREE, 20020712); class_type = BINFO_TYPE (binfo); @@ -5053,10 +5059,6 @@ build_special_member_call (tree instance, tree name, tree args, my_friendly_assert (instance != NULL_TREE, 20020712); - /* Resolve the name. */ - if (!complete_type_or_else (BINFO_TYPE (binfo), NULL_TREE)) - return error_mark_node; - fns = lookup_fnfields (binfo, name, 1); /* When making a call to a constructor or destructor for a subobject @@ -6302,8 +6304,7 @@ perform_direct_initialization_if_possible (tree type, tree expr) { expr = build_special_member_call (NULL_TREE, complete_ctor_identifier, build_tree_list (NULL_TREE, expr), - TYPE_BINFO (type), - LOOKUP_NORMAL); + type, LOOKUP_NORMAL); return build_cplus_new (type, expr); } diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 080e5e9bfa9..2e5b89b5b0b 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1501,12 +1501,16 @@ finish_struct_bits (tree t) = TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (t); TYPE_POLYMORPHIC_P (variants) = TYPE_POLYMORPHIC_P (t); TYPE_USES_VIRTUAL_BASECLASSES (variants) = TYPE_USES_VIRTUAL_BASECLASSES (t); + + TYPE_BINFO (variants) = TYPE_BINFO (t); + /* Copy whatever these are holding today. */ TYPE_VFIELD (variants) = TYPE_VFIELD (t); TYPE_METHODS (variants) = TYPE_METHODS (t); TYPE_FIELDS (variants) = TYPE_FIELDS (t); TYPE_SIZE (variants) = TYPE_SIZE (t); TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t); + variants = TYPE_NEXT_VARIANT (variants); } diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 61e179ed1b6..34a21ec5ebb 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -748,7 +748,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags) ctor = build_special_member_call (NULL_TREE, complete_ctor_identifier, build_tree_list (NULL_TREE, ctor), - TYPE_BINFO (type), flags); + type, flags); if (ctor) return build_cplus_new (type, ctor); } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index cc905eb2511..39b0a17c28b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5852,6 +5852,8 @@ build_ptrmemfunc_type (tree type) = build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type)); t = make_aggr_type (RECORD_TYPE); + xref_basetypes (t, NULL_TREE); + /* Let the front-end know this is a pointer to member function... */ TYPE_PTRMEMFUNC_FLAG (t) = 1; /* ... and not really an aggregate. */ @@ -9037,13 +9039,8 @@ xref_basetypes (tree ref, tree base_list) if (ref == error_mark_node) return; - if (TREE_CODE (ref) == UNION_TYPE) - { - error ("derived union `%T' invalid", ref); - return; - } - - tag_code = (CLASSTYPE_DECLARED_CLASS (ref) ? class_type : record_type); + tag_code = TREE_CODE (ref) == UNION_TYPE ? union_type + : (CLASSTYPE_DECLARED_CLASS (ref) ? class_type : record_type); /* First, make sure that any templates in base-classes are instantiated. This ensures that if we call ourselves recursively @@ -9053,6 +9050,7 @@ xref_basetypes (tree ref, tree base_list) while (*basep) { tree basetype = TREE_VALUE (*basep); + if (!(processing_template_decl && uses_template_parms (basetype)) && !complete_type_or_else (basetype, NULL)) /* An incomplete type. Remove it from the list. */ @@ -9063,6 +9061,11 @@ xref_basetypes (tree ref, tree base_list) SET_CLASSTYPE_MARKED (ref); i = list_length (base_list); + /* The binfo slot should be empty, unless this is an (ill-formed) + redefinition. */ + my_friendly_assert (!TYPE_BINFO (ref) || TYPE_SIZE (ref), 20040706); + TYPE_BINFO (ref) = make_binfo (size_zero_node, ref, NULL_TREE, NULL_TREE); + if (i) { tree binfo = TYPE_BINFO (ref); @@ -9115,14 +9118,22 @@ xref_basetypes (tree ref, tree base_list) if (CLASS_TYPE_P (basetype)) { base_binfo = TYPE_BINFO (basetype); - /* This flag will be in the binfo of the base type, we must - clear it after copying the base binfos. */ - BINFO_DEPENDENT_BASE_P (base_binfo) - = dependent_type_p (basetype); + + if (dependent_type_p (basetype)) + { + base_binfo = make_binfo (size_zero_node, basetype, + NULL_TREE, NULL_TREE); + BINFO_DEPENDENT_BASE_P (base_binfo) = 1; + } + else + my_friendly_assert (base_binfo, 20040706); } else - base_binfo = make_binfo (size_zero_node, basetype, - NULL_TREE, NULL_TREE); + { + base_binfo = make_binfo (size_zero_node, basetype, + NULL_TREE, NULL_TREE); + BINFO_DEPENDENT_BASE_P (base_binfo) = 1; + } TREE_VEC_ELT (binfos, i) = base_binfo; TREE_VEC_ELT (accesses, i) = access; @@ -9182,6 +9193,12 @@ xref_basetypes (tree ref, tree base_list) inheritance order chain. */ copy_base_binfos (TYPE_BINFO (ref), ref, NULL_TREE); + if (TREE_CODE (ref) == UNION_TYPE) + { + if (i) + error ("derived union `%T' invalid", ref); + } + if (TYPE_FOR_JAVA (ref)) { if (TYPE_USES_MULTIPLE_INHERITANCE (ref)) @@ -9193,14 +9210,12 @@ xref_basetypes (tree ref, tree base_list) /* Unmark all the types. */ while (i--) { - tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (ref), i)); + tree binfo = BINFO_BASE_BINFO (TYPE_BINFO (ref), i); + tree basetype = BINFO_TYPE (binfo); CLEAR_CLASSTYPE_MARKED (basetype); - if (CLASS_TYPE_P (basetype)) - { - BINFO_VIRTUAL_P (TYPE_BINFO (basetype)) = 0; - BINFO_DEPENDENT_BASE_P (TYPE_BINFO (basetype)) = 0; - } + if (!BINFO_DEPENDENT_BASE_P (binfo)) + BINFO_VIRTUAL_P (TYPE_BINFO (basetype)) = 0; } CLEAR_CLASSTYPE_MARKED (ref); } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index e899b01f1f4..9b2a8f56c30 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1145,7 +1145,7 @@ build_init (tree decl, tree init, int flags) else if (CLASS_TYPE_P (TREE_TYPE (decl))) expr = build_special_member_call (decl, complete_ctor_identifier, build_tree_list (NULL_TREE, init), - TYPE_BINFO (TREE_TYPE (decl)), + TREE_TYPE (decl), LOOKUP_NORMAL|flags); else expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init); @@ -2088,7 +2088,7 @@ build_new_1 (tree exp) { init_expr = build_special_member_call (init_expr, complete_ctor_identifier, - init, TYPE_BINFO (true_type), + init, true_type, LOOKUP_NORMAL); stable = stabilize_init (init_expr, &init_preeval_expr); } diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 2e3bccdaac2..4b3ba7ac93f 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -782,8 +782,6 @@ cxx_make_type (enum tree_code code) presence of parse errors, the normal was of assuring this might not ever get executed, so we lay it out *immediately*. */ build_pointer_type (t); - - TYPE_BINFO (t) = make_binfo (size_zero_node, t, NULL_TREE, NULL_TREE); } else /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits. But, diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a7fe73db722..08ee8751c7d 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -12494,6 +12494,7 @@ cp_parser_class_head (cp_parser* parser, bool invalid_explicit_specialization_p = false; bool pop_p = false; unsigned num_templates; + tree bases; /* Assume no nested-name-specifier will be present. */ *nested_name_specifier_p = false; @@ -12770,17 +12771,16 @@ cp_parser_class_head (cp_parser* parser, is valid. */ if (nested_name_specifier) pop_p = push_scope (nested_name_specifier); - /* Now, look for the base-clause. */ - token = cp_lexer_peek_token (parser->lexer); - if (token->type == CPP_COLON) - { - tree bases; + + bases = NULL_TREE; + + /* Get the list of base-classes, if there is one. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) + bases = cp_parser_base_clause (parser); + + /* Process the base classes. */ + xref_basetypes (type, bases); - /* Get the list of base-classes. */ - bases = cp_parser_base_clause (parser); - /* Process them. */ - xref_basetypes (type, bases); - } /* Leave the scope given by the nested-name-specifier. We will enter the class scope itself while processing the members. */ if (pop_p) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 20f7a0179f6..3d46883aee8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5286,6 +5286,7 @@ instantiate_class_template (tree type) tree template, args, pattern, t, member; tree typedecl; tree pbinfo; + tree base_list; if (type == error_mark_node) return error_mark_node; @@ -5419,9 +5420,9 @@ instantiate_class_template (tree type) abort (); #endif + base_list = NULL_TREE; if (BINFO_BASE_BINFOS (pbinfo)) { - tree base_list = NULL_TREE; tree pbases = BINFO_BASE_BINFOS (pbinfo); tree paccesses = BINFO_BASE_ACCESSES (pbinfo); tree context = TYPE_CONTEXT (type); @@ -5457,13 +5458,13 @@ instantiate_class_template (tree type) /* The list is now in reverse order; correct that. */ base_list = nreverse (base_list); - /* Now call xref_basetypes to set up all the base-class - information. */ - xref_basetypes (type, base_list); - if (pop_p) pop_scope (context ? context : global_namespace); } + /* Now call xref_basetypes to set up all the base-class + information. */ + xref_basetypes (type, base_list); + /* Now that our base classes are set up, enter the scope of the class, so that name lookups into base classes, etc. will work @@ -5647,11 +5648,18 @@ instantiate_class_template (tree type) tree r; if (TREE_CODE (t) == TEMPLATE_DECL) - ++processing_template_decl; + { + ++processing_template_decl; + push_deferring_access_checks (dk_no_check); + } + r = tsubst_friend_function (t, args); - if (TREE_CODE (t) == TEMPLATE_DECL) - --processing_template_decl; add_friend (type, r, /*complain=*/false); + if (TREE_CODE (t) == TEMPLATE_DECL) + { + pop_deferring_access_checks (); + --processing_template_decl; + } } } } diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c index c9eccf2239b..ba5533a36dd 100644 --- a/gcc/cp/ptree.c +++ b/gcc/cp/ptree.c @@ -128,7 +128,12 @@ cxx_print_type (FILE *file, tree node, int indent) if (TREE_CODE (node) == RECORD_TYPE) { - fprintf (file, " n_parents %d", BINFO_N_BASE_BINFOS (TYPE_BINFO (node))); + if (TYPE_BINFO (node)) + fprintf (file, " n_parents=%d", + BINFO_N_BASE_BINFOS (TYPE_BINFO (node))); + else + fprintf (file, " no-binfo"); + fprintf (file, " use_template=%d", CLASSTYPE_USE_TEMPLATE (node)); if (CLASSTYPE_INTERFACE_ONLY (node)) fprintf (file, " interface-only"); diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 8e0b9622a57..dbc3e40340e 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -20,7 +20,6 @@ along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - #include "config.h" #include "system.h" #include "coretypes.h" diff --git a/gcc/cp/search.c b/gcc/cp/search.c index da9a7cfdc7f..83925b8d2fd 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -270,8 +270,8 @@ accessible_base_p (tree t, tree base) tree lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr) { - tree binfo = NULL; /* The binfo we've found so far. */ - tree t_binfo = NULL; + tree binfo = NULL_TREE; /* The binfo we've found so far. */ + tree t_binfo = NULL_TREE; base_kind bk; if (t == error_mark_node || base == error_mark_node) @@ -287,14 +287,18 @@ lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr) t_binfo = t; t = BINFO_TYPE (t); } - else - t_binfo = TYPE_BINFO (t); - - /* Ensure that the types are instantiated. */ - t = complete_type (TYPE_MAIN_VARIANT (t)); - base = complete_type (TYPE_MAIN_VARIANT (base)); + else + { + t = complete_type (TYPE_MAIN_VARIANT (t)); + t_binfo = TYPE_BINFO (t); + } - bk = lookup_base_r (t_binfo, base, access, 0, &binfo); + base = complete_type (TYPE_MAIN_VARIANT (base)); + + if (t_binfo) + bk = lookup_base_r (t_binfo, base, access, 0, &binfo); + else + bk = bk_not_base; /* Check that the base is unambiguous and accessible. */ if (access != ba_any) @@ -1256,8 +1260,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type) { my_friendly_assert (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)), 20030624); type = xbasetype; - basetype_path = TYPE_BINFO (type); - my_friendly_assert (!BINFO_INHERITANCE_CHAIN (basetype_path), 980827); + xbasetype = NULL_TREE; } if (type == current_class_type && TYPE_BEING_DEFINED (type) @@ -1271,7 +1274,12 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type) return field; } - complete_type (type); + type = complete_type (type); + if (!basetype_path) + basetype_path = TYPE_BINFO (type); + + if (!basetype_path) + return NULL_TREE; #ifdef GATHER_STATISTICS n_calls_lookup_field++; @@ -2239,6 +2247,11 @@ push_class_decls (tree type) { search_stack = push_search_level (search_stack, &search_obstack); + if (!TYPE_BINFO (type)) + /* This occurs when parsing an invalid declarator id where the + scope is incomplete. */ + return; + /* Enter type declarations and mark. */ dfs_walk (TYPE_BINFO (type), dfs_push_type_decls, unmarked_pushdecls_p, 0); @@ -2351,7 +2364,8 @@ lookup_conversions (tree type) tree conversions = NULL_TREE; complete_type (type); - bfs_walk (TYPE_BINFO (type), add_conversions, 0, &conversions); + if (TYPE_BINFO (type)) + bfs_walk (TYPE_BINFO (type), add_conversions, 0, &conversions); for (t = conversions; t; t = TREE_CHAIN (t)) IDENTIFIER_MARKED (DECL_NAME (OVL_CURRENT (TREE_VALUE (t)))) = 0; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index e7502260e4d..929a0e632a1 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1490,7 +1490,7 @@ finish_stmt_expr_expr (tree expr, tree stmt_expr) expr = build_special_member_call (NULL_TREE, complete_ctor_identifier, build_tree_list (NULL_TREE, expr), - TYPE_BINFO (type), LOOKUP_NORMAL); + type, LOOKUP_NORMAL); expr = build_cplus_new (type, expr); my_friendly_assert (TREE_CODE (expr) == TARGET_EXPR, 20030729); } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 35679eb5215..b463fc1bea5 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -602,7 +602,7 @@ copy_base_binfos (tree binfo, tree t, tree prev) tree base_binfo = TREE_VEC_ELT (binfos, ix); tree new_binfo = NULL_TREE; - if (!CLASS_TYPE_P (BINFO_TYPE (base_binfo))) + if (BINFO_DEPENDENT_BASE_P (base_binfo)) { my_friendly_assert (binfo == TYPE_BINFO (t), 20030204); @@ -777,13 +777,12 @@ make_binfo (tree offset, tree binfo, tree vtable, tree virtuals) if (TREE_CODE (binfo) == TREE_BINFO) { type = BINFO_TYPE (binfo); - BINFO_DEPENDENT_BASE_P (new_binfo) = BINFO_DEPENDENT_BASE_P (binfo); + my_friendly_assert (!BINFO_DEPENDENT_BASE_P (binfo), 20040706); } else { type = binfo; binfo = NULL_TREE; - BINFO_DEPENDENT_BASE_P (new_binfo) = 1; } TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type); @@ -791,8 +790,7 @@ make_binfo (tree offset, tree binfo, tree vtable, tree virtuals) BINFO_VTABLE (new_binfo) = vtable; BINFO_VIRTUALS (new_binfo) = virtuals; - if (binfo && !BINFO_DEPENDENT_BASE_P (binfo) - && BINFO_BASE_BINFOS (binfo) != NULL_TREE) + if (binfo && BINFO_BASE_BINFOS (binfo)) { BINFO_BASE_BINFOS (new_binfo) = copy_node (BINFO_BASE_BINFOS (binfo)); /* We do not need to copy the accesses, as they are read only. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index d1792d4ddfb..651067adb9b 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5071,8 +5071,7 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) { result = build_special_member_call (lhs, complete_ctor_identifier, build_tree_list (NULL_TREE, rhs), - TYPE_BINFO (lhstype), - LOOKUP_NORMAL); + lhstype, LOOKUP_NORMAL); if (result == NULL_TREE) return error_mark_node; return result; diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 6e32377c4a3..21bca0025dd 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -954,7 +954,7 @@ process_init_constructor (tree type, tree init, tree* elts) return error_mark_node; } - if (BINFO_BASE_BINFOS (TYPE_BINFO (type))) + if (TYPE_BINFO (type) && BINFO_BASE_BINFOS (TYPE_BINFO (type))) { sorry ("initializer list for object of class with base classes"); return error_mark_node; @@ -1304,6 +1304,7 @@ build_m_component_ref (tree datum, tree component) tree objtype; tree type; tree binfo; + tree ctype; datum = decay_conversion (datum); @@ -1327,16 +1328,28 @@ build_m_component_ref (tree datum, tree component) } type = TYPE_PTRMEM_POINTED_TO_TYPE (ptrmem_type); - binfo = lookup_base (objtype, TYPE_PTRMEM_CLASS_TYPE (ptrmem_type), - ba_check, NULL); - if (!binfo) + ctype = complete_type (TYPE_PTRMEM_CLASS_TYPE (ptrmem_type)); + + if (!COMPLETE_TYPE_P (ctype)) { - error ("member type `%T::' incompatible with object type `%T'", - type, objtype); - return error_mark_node; + if (!same_type_p (ctype, objtype)) + goto mismatch; + binfo = NULL; + } + else + { + binfo = lookup_base (objtype, ctype, ba_check, NULL); + + if (!binfo) + { + mismatch: + error ("pointer to member type `%T' incompatible with object type `%T'", + type, objtype); + return error_mark_node; + } + else if (binfo == error_mark_node) + return error_mark_node; } - else if (binfo == error_mark_node) - return error_mark_node; if (TYPE_PTRMEM_P (ptrmem_type)) { @@ -1347,12 +1360,17 @@ build_m_component_ref (tree datum, tree component) type = cp_build_qualified_type (type, (cp_type_quals (type) | cp_type_quals (TREE_TYPE (datum)))); + + datum = build_address (datum); + + /* Convert object to the correct base. */ + if (binfo) + datum = build_base_path (PLUS_EXPR, datum, binfo, 1); + /* Build an expression for "object + offset" where offset is the value stored in the pointer-to-data-member. */ datum = build (PLUS_EXPR, build_pointer_type (type), - build_base_path (PLUS_EXPR, build_address (datum), - binfo, 1), - build_nop (ptrdiff_type_node, component)); + datum, build_nop (ptrdiff_type_node, component)); return build_indirect_ref (datum, 0); } else @@ -1420,7 +1438,7 @@ build_functional_cast (tree exp, tree parms) } exp = build_special_member_call (NULL_TREE, complete_ctor_identifier, parms, - TYPE_BINFO (type), LOOKUP_NORMAL); + type, LOOKUP_NORMAL); if (exp == error_mark_node) return error_mark_node;