* 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.
From-SVN: r68424
+2003-06-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * 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 <jh@suse.cz>
* method.c (thunk_labelno): Move outside ifdef block to make garbage
2003-06-23 Jakub Jelinek <jakub@redhat.com>
- * 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 <gdr@integrable-solutions.net>
/* 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);
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))
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)
}
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;
}
}
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),
}
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);
}
if (complain & tf_error)
- perform_or_defer_access_check (context, tmpl);
+ perform_or_defer_access_check (TYPE_BINFO (context), tmpl);
return tmpl;
}
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);
{
/* 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);
}
args <char, std::char_traits<char> > . */
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))
{
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
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;
&& 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
{
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)
const char *errstr = 0;
- /* Sanity check. */
- if (TREE_CODE (name) != IDENTIFIER_NODE)
- abort ();
-
- if (xbasetype == current_class_type && TYPE_BEING_DEFINED (xbasetype)
- && IDENTIFIER_CLASS_VALUE (name))
- {
- tree field = IDENTIFIER_CLASS_VALUE (name);
- if (! is_overloaded_fn (field)
- && ! (want_type && TREE_CODE (field) != TYPE_DECL))
- /* We're in the scope of this class, and the value has already
- been looked up. Just return the cached value. */
- return field;
- }
+ my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 20030624);
if (TREE_CODE (xbasetype) == TREE_VEC)
{
type = BINFO_TYPE (xbasetype);
basetype_path = xbasetype;
}
- else if (IS_AGGR_TYPE_CODE (TREE_CODE (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) == NULL_TREE,
- 980827);
+ 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);
+ if (! is_overloaded_fn (field)
+ && ! (want_type && TREE_CODE (field) != TYPE_DECL))
+ /* We're in the scope of this class, and the value has already
+ been looked up. Just return the cached value. */
+ return field;
}
- else
- abort ();
complete_type (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)
{
}
/* 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. */
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);
}
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. */
/* 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)