diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8ae7c023e9a4..65ca03d9e563 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,25 @@ +2003-06-24 Nathan Sidwell + + * call.c (enforce_access): Assert we get a binfo. + (build_op_delete_call): Pass a binfo to + perform_or_defer_access_check. + * class.c (alter_access): Likewise. + * decl.c (make_typename_type): Likewise. + (make_unbound_class_template): Likewise. + * lex.c (do_identifier): Likewise. + * method.c (hack_identifier): Likewise. + * parser.c (cp_parser_lookup_name): Likewise. + * search.c (lookup_member): Likewise. Move IDENTIFIER_CLASS_VALUE + test. + * semantics.c (finish_non_static_data_member): Likewise. + (perform_or_defer_access_check): Expect a binfo. + * typeck.c (comptypes): Expect types. + + * mangle.c (find_substitution): Don't pass a non-type to same_type_p + * friend.c (make_friend_class): Likewise. + * pt.c (check_default_tmpl_args): Likewise. + (lookup_template_class): Likewise. + Tue Jun 24 15:30:05 CEST 2003 Jan Hubicka * method.c (thunk_labelno): Move outside ifdef block to make garbage @@ -41,7 +63,7 @@ Mon Jun 23 19:41:27 CEST 2003 Jan Hubicka 2003-06-23 Jakub Jelinek - * mangle.c (hash_type): val is the TREE_LIST itself, not a pointer + * mangle.c (hash_type): Val is the TREE_LIST itself, not a pointer to it. 2003-06-21 Gabriel Dos Reis diff --git a/gcc/cp/call.c b/gcc/cp/call.c index bb1ad5b91bce..77ed3e8686ff 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4071,7 +4071,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, /* If the FN is a member function, make sure that it is accessible. */ if (DECL_CLASS_SCOPE_P (fn)) - perform_or_defer_access_check (type, fn); + perform_or_defer_access_check (TYPE_BINFO (type), fn); if (pass == 0) args = tree_cons (NULL_TREE, addr, args); @@ -4098,6 +4098,8 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, bool enforce_access (tree basetype_path, tree decl) { + my_friendly_assert (TREE_CODE (basetype_path) == TREE_VEC, 20030624); + if (!accessible_p (basetype_path, decl)) { if (TREE_PRIVATE (decl)) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 12c206854564..b5eb245f4f29 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1064,8 +1064,7 @@ alter_access (tree t, tree fdecl, tree access) if (!DECL_LANG_SPECIFIC (fdecl)) retrofit_lang_decl (fdecl); - if (DECL_DISCRIMINATOR_P (fdecl)) - abort (); + my_friendly_assert (!DECL_DISCRIMINATOR_P (fdecl), 20030624); elem = purpose_member (t, DECL_ACCESS (fdecl)); if (elem) @@ -1087,7 +1086,7 @@ alter_access (tree t, tree fdecl, tree access) } else { - perform_or_defer_access_check (t, fdecl); + perform_or_defer_access_check (TYPE_BINFO (t), fdecl); DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl)); return 1; } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9e3a9ce9957e..b9c59af6cc72 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5525,7 +5525,7 @@ make_typename_type (tree context, tree name, tsubst_flags_t complain) } if (complain & tf_error) - perform_or_defer_access_check (context, tmpl); + perform_or_defer_access_check (TYPE_BINFO (context), tmpl); return lookup_template_class (tmpl, TREE_OPERAND (fullname, 1), @@ -5555,7 +5555,7 @@ make_typename_type (tree context, tree name, tsubst_flags_t complain) } if (complain & tf_error) - perform_or_defer_access_check (context, t); + perform_or_defer_access_check (TYPE_BINFO (context), t); if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl)) t = TREE_TYPE (t); @@ -5612,7 +5612,7 @@ make_unbound_class_template (tree context, tree name, tsubst_flags_t complain) } if (complain & tf_error) - perform_or_defer_access_check (context, tmpl); + perform_or_defer_access_check (TYPE_BINFO (context), tmpl); return tmpl; } diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index 3ecd3177195a..0a0e82c7fcdb 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -264,17 +264,34 @@ make_friend_class (type, friend_type) if (is_template_friend) friend_type = CLASSTYPE_TI_TEMPLATE (friend_type); - classes = CLASSTYPE_FRIEND_CLASSES (type); - while (classes - /* Stop if we find the same type on the list. */ - && !(TREE_CODE (TREE_VALUE (classes)) == TEMPLATE_DECL ? - friend_type == TREE_VALUE (classes) : - same_type_p (TREE_VALUE (classes), friend_type))) - classes = TREE_CHAIN (classes); - if (classes) - warning ("`%T' is already a friend of `%T'", - TREE_VALUE (classes), type); - else + /* See if it is already a friend. */ + for (classes = CLASSTYPE_FRIEND_CLASSES (type); + classes; + classes = TREE_CHAIN (classes)) + { + tree probe = TREE_VALUE (classes); + + if (TREE_CODE (friend_type) == TEMPLATE_DECL) + { + if (friend_type == probe) + { + warning ("`%D' is already a friend of `%T'", + probe, type); + break; + } + } + else if (TREE_CODE (probe) != TEMPLATE_DECL) + { + if (same_type_p (probe, friend_type)) + { + warning ("`%T' is already a friend of `%T'", + probe, type); + break; + } + } + } + + if (!classes) { maybe_add_class_template_decl_list (type, friend_type, /*friend_p=*/1); diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 1f8cb0672a39..b378dc1724a6 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -777,7 +777,7 @@ do_identifier (register tree token, tree args) { /* Check access. */ if (IDENTIFIER_CLASS_VALUE (token) == id) - perform_or_defer_access_check (CP_DECL_CONTEXT(id), id); + perform_or_defer_access_check (TYPE_BINFO (DECL_CONTEXT (id)), id); if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id)) id = DECL_INITIAL (id); } diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index e4c75b473c6b..b5d0a645af49 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -546,6 +546,7 @@ find_substitution (tree node) args > . */ tree args = CLASSTYPE_TI_ARGS (type); if (TREE_VEC_LENGTH (args) == 2 + && TYPE_P (TREE_VEC_ELT (args, 0)) && same_type_p (TREE_VEC_ELT (args, 0), char_type_node) && is_std_substitution_char (TREE_VEC_ELT (args, 1), SUBID_CHAR_TRAITS)) diff --git a/gcc/cp/method.c b/gcc/cp/method.c index d02d0243f87d..cb2c864bfca8 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -182,7 +182,7 @@ hack_identifier (tree value, tree name) { tree path; path = currently_open_derived_class (DECL_CONTEXT (value)); - perform_or_defer_access_check (path, value); + perform_or_defer_access_check (TYPE_BINFO (path), value); } } else if (TREE_CODE (value) == TREE_LIST diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4799944b9948..6240c244607a 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -13353,7 +13353,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, object_type, parser->scope); if (qualifying_type) - perform_or_defer_access_check (qualifying_type, decl); + perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl); } return decl; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7ce9031e0333..e29d434c0009 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2528,14 +2528,15 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) && DECL_LANG_SPECIFIC (decl) /* If this is either a friend defined in the scope of the class or a member function. */ - && ((DECL_CONTEXT (decl) - && same_type_p (DECL_CONTEXT (decl), current_class_type)) - || (DECL_FRIEND_CONTEXT (decl) - && same_type_p (DECL_FRIEND_CONTEXT (decl), - current_class_type))) + && (DECL_FUNCTION_MEMBER_P (decl) + ? same_type_p (DECL_CONTEXT (decl), current_class_type) + : DECL_FRIEND_CONTEXT (decl) + ? same_type_p (DECL_FRIEND_CONTEXT (decl), current_class_type) + : false) /* And, if it was a member function, it really was defined in the scope of the class. */ - && (!DECL_FUNCTION_MEMBER_P (decl) || DECL_INITIALIZED_IN_CLASS_P (decl))) + && (!DECL_FUNCTION_MEMBER_P (decl) + || DECL_INITIALIZED_IN_CLASS_P (decl))) /* We already checked these parameters when the template was declared, so there's no need to do it again now. This function was defined in class scope, but we're processing it's body now @@ -4234,21 +4235,20 @@ lookup_template_class (tree d1, { tree ctx; - /* Note that we use DECL_CONTEXT, rather than - CP_DECL_CONTEXT, so that the termination test is - always just `ctx'. We're not interested in namespace - scopes. */ for (ctx = current_class_type; ctx; - ctx = (TYPE_P (ctx)) ? TYPE_CONTEXT (ctx) : DECL_CONTEXT (ctx)) - if (same_type_p (ctx, template_type)) - break; + ctx = TYPE_CONTEXT (ctx)) + { + if (TREE_CODE (ctx) == NAMESPACE_DECL) + break; + if (same_type_p (ctx, template_type)) + goto found_ctx; + } - if (!ctx) - /* We're not in the scope of the class, so the - TEMPLATE_TYPE is not the type we want after - all. */ - found = NULL_TREE; + /* We're not in the scope of the class, so the + TEMPLATE_TYPE is not the type we want after all. */ + found = NULL_TREE; + found_ctx:; } } if (found) diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 3df6f733f74c..a853c208bdf5 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1226,11 +1226,22 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type) const char *errstr = 0; - /* Sanity check. */ - if (TREE_CODE (name) != IDENTIFIER_NODE) - abort (); + my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 20030624); - if (xbasetype == current_class_type && TYPE_BEING_DEFINED (xbasetype) + if (TREE_CODE (xbasetype) == TREE_VEC) + { + type = BINFO_TYPE (xbasetype); + basetype_path = xbasetype; + } + else + { + 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); + } + + if (type == current_class_type && TYPE_BEING_DEFINED (type) && IDENTIFIER_CLASS_VALUE (name)) { tree field = IDENTIFIER_CLASS_VALUE (name); @@ -1241,21 +1252,6 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type) return field; } - if (TREE_CODE (xbasetype) == TREE_VEC) - { - type = BINFO_TYPE (xbasetype); - basetype_path = xbasetype; - } - else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype))) - { - type = xbasetype; - basetype_path = TYPE_BINFO (type); - my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE, - 980827); - } - else - abort (); - complete_type (type); #ifdef GATHER_STATISTICS @@ -1291,7 +1287,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type) In the case of overloaded function names, access control is applied to the function selected by overloaded resolution. */ if (rval && protect && !is_overloaded_fn (rval)) - perform_or_defer_access_check (xbasetype, rval); + perform_or_defer_access_check (basetype_path, rval); if (errstr && protect) { diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index bb55b75af88b..3272284d9c7a 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -262,16 +262,18 @@ void perform_deferred_access_checks (void) } /* Defer checking the accessibility of DECL, when looked up in - CLASS_TYPE. */ + BINFO. */ -void perform_or_defer_access_check (tree class_type, tree decl) +void perform_or_defer_access_check (tree binfo, tree decl) { tree check; + my_friendly_assert (TREE_CODE (binfo) == TREE_VEC, 20030623); + /* If we are not supposed to defer access checks, just check now. */ if (deferred_access_stack->deferring_access_checks_kind == dk_no_deferred) { - enforce_access (class_type, decl); + enforce_access (binfo, decl); return; } /* Exit if we are in a context that no access checking is performed. */ @@ -282,13 +284,11 @@ void perform_or_defer_access_check (tree class_type, tree decl) for (check = deferred_access_stack->deferred_access_checks; check; check = TREE_CHAIN (check)) - if (TREE_VALUE (check) == decl - && TYPE_P (TREE_PURPOSE (check)) - && same_type_p (TREE_PURPOSE (check), class_type)) + if (TREE_VALUE (check) == decl && TREE_PURPOSE (check) == binfo) return; /* If not, record the check. */ deferred_access_stack->deferred_access_checks - = tree_cons (class_type, decl, + = tree_cons (binfo, decl, deferred_access_stack->deferred_access_checks); } @@ -1255,7 +1255,7 @@ finish_non_static_data_member (tree decl, tree qualifying_scope) return error_mark_node; } - perform_or_defer_access_check (access_type, decl); + perform_or_defer_access_check (TYPE_BINFO (access_type), decl); /* If the data member was named `C::M', convert `*this' to `C' first. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index c80ca6b44d04..be53d4515459 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -883,7 +883,9 @@ comptypes (tree t1, tree t2, int strict) /* Suppress errors caused by previously reported errors */ if (t2 == error_mark_node) return false; - + + my_friendly_assert (TYPE_P (t1) && TYPE_P (t2), 20030623); + /* TYPENAME_TYPEs should be resolved if the qualifying scope is the current instantiation. */ if (TREE_CODE (t1) == TYPENAME_TYPE)