* cp-tree.h (enforce_access, perform_or_defer_access_check): Added an
extra argument that represents the declaration to use to print
potential error messages.
* init.c (build_offset_ref): Adjusted the call to
perform_or_defer_access_check.
* class.c (alter_access, resolve_address_of_overloaded_function):
Likewise.
* decl.c (make_typename_type, make_unbound_class_template): Likewise.
* search.c (lookup_member): Likewise.
* friend.c (add_friend): Likewise.
* parser.c (cp_parser_template_id,
cp_parser_pre_parsed_nested_name_specifier): Likewise.
* semantics.c (finish_non_static_data_member,
check_accessibility_of_qualified_id, finish_id_expression): Likewise.
(pop_to_parent_deferring_access_checks, perform_access_checks,
perform_or_defer_access_check): Adjusted the call to enforce_access.
* call.c (enforce_access): Use the new extra argument to build the
error message.
(build_op_delete_call): Adjusted the call to
perform_or_defer_access_check.
(build_over_call): Likewise.
PR c++/29475
* g++.dg/template/access19.C: New test.
* g++.old-deja/g++.other/access11.C: Adjusted the line where the
error is reported.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119027
138bc75d-0d04-0410-961f-
82ee72b054a4
+2006-11-20 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/29475
+ * cp-tree.h (enforce_access, perform_or_defer_access_check): Added an
+ extra argument that represents the declaration to use to print
+ potential error messages.
+ * init.c (build_offset_ref): Adjusted the call to
+ perform_or_defer_access_check.
+ * class.c (alter_access, resolve_address_of_overloaded_function):
+ Likewise.
+ * decl.c (make_typename_type, make_unbound_class_template): Likewise.
+ * search.c (lookup_member): Likewise.
+ * friend.c (add_friend): Likewise.
+ * parser.c (cp_parser_template_id,
+ cp_parser_pre_parsed_nested_name_specifier): Likewise.
+ * semantics.c (finish_non_static_data_member,
+ check_accessibility_of_qualified_id, finish_id_expression): Likewise.
+ (pop_to_parent_deferring_access_checks, perform_access_checks,
+ perform_or_defer_access_check): Adjusted the call to enforce_access.
+ * call.c (enforce_access): Use the new extra argument to build the
+ error message.
+ (build_op_delete_call): Adjusted the call to
+ perform_or_defer_access_check.
+ (build_over_call): Likewise.
+
2006-11-16 Dirk Mueller <dmueller@suse.de>
* name-lookup.c (begin_scope): Use GGC_CNEW instead of
/* 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_BINFO (type), fn);
+ perform_or_defer_access_check (TYPE_BINFO (type), fn, fn);
if (pass == 0)
args = tree_cons (NULL_TREE, addr, args);
/* If the current scope isn't allowed to access DECL along
BASETYPE_PATH, give an error. The most derived class in
- BASETYPE_PATH is the one used to qualify DECL. */
+ BASETYPE_PATH is the one used to qualify DECL. DIAG_DECL is
+ the declaration to use in the error diagnostic. */
bool
-enforce_access (tree basetype_path, tree decl)
+enforce_access (tree basetype_path, tree decl, tree diag_decl)
{
gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO);
if (!accessible_p (basetype_path, decl, true))
{
if (TREE_PRIVATE (decl))
- error ("%q+#D is private", decl);
+ error ("%q+#D is private", diag_decl);
else if (TREE_PROTECTED (decl))
- error ("%q+#D is protected", decl);
+ error ("%q+#D is protected", diag_decl);
else
- error ("%q+#D is inaccessible", decl);
+ error ("%q+#D is inaccessible", diag_decl);
error ("within this context");
return false;
}
if (DECL_TEMPLATE_INFO (fn)
&& DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (fn)))
perform_or_defer_access_check (cand->access_path,
- DECL_TI_TEMPLATE (fn));
+ DECL_TI_TEMPLATE (fn), fn);
else
- perform_or_defer_access_check (cand->access_path, fn);
+ perform_or_defer_access_check (cand->access_path, fn, fn);
}
if (args && TREE_CODE (args) != TREE_LIST)
}
else
{
- perform_or_defer_access_check (TYPE_BINFO (t), fdecl);
+ perform_or_defer_access_check (TYPE_BINFO (t), fdecl, fdecl);
DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
return 1;
}
if (DECL_FUNCTION_MEMBER_P (fn))
{
gcc_assert (access_path);
- perform_or_defer_access_check (access_path, fn);
+ perform_or_defer_access_check (access_path, fn, fn);
}
}
extern bool can_convert (tree, tree);
extern bool can_convert_arg (tree, tree, tree, int);
extern bool can_convert_arg_bad (tree, tree, tree);
-extern bool enforce_access (tree, tree);
+extern bool enforce_access (tree, tree, tree);
extern tree convert_default_arg (tree, tree, tree, int);
extern tree convert_arg_to_ellipsis (tree);
extern tree build_x_va_arg (tree, tree);
extern void pop_to_parent_deferring_access_checks (void);
extern void perform_access_checks (tree);
extern void perform_deferred_access_checks (void);
-extern void perform_or_defer_access_check (tree, tree);
+extern void perform_or_defer_access_check (tree, tree, tree);
extern int stmts_are_full_exprs_p (void);
extern void init_cp_semantics (void);
extern tree do_poplevel (tree);
}
if (complain & tf_error)
- perform_or_defer_access_check (TYPE_BINFO (context), t);
+ perform_or_defer_access_check (TYPE_BINFO (context), t, t);
if (want_template)
return lookup_template_class (t, TREE_OPERAND (fullname, 1),
}
if (complain & tf_error)
- perform_or_defer_access_check (TYPE_BINFO (context), tmpl);
+ perform_or_defer_access_check (TYPE_BINFO (context), tmpl, tmpl);
return tmpl;
}
ctx = DECL_CONTEXT (decl);
if (ctx && CLASS_TYPE_P (ctx) && !uses_template_parms (ctx))
- perform_or_defer_access_check (TYPE_BINFO (ctx), decl);
+ perform_or_defer_access_check (TYPE_BINFO (ctx), decl, decl);
maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
(or any class derived from that class). */
if (address_p && DECL_P (t)
&& DECL_NONSTATIC_MEMBER_P (t))
- perform_or_defer_access_check (TYPE_BINFO (type), t);
+ perform_or_defer_access_check (TYPE_BINFO (type), t, t);
else
- perform_or_defer_access_check (basebinfo, t);
+ perform_or_defer_access_check (basebinfo, t, t);
if (DECL_STATIC_FUNCTION_P (t))
return t;
/* We need additional test besides the one in
check_accessibility_of_qualified_id in case it is
a pointer to non-static member. */
- perform_or_defer_access_check (TYPE_BINFO (type), member);
+ perform_or_defer_access_check (TYPE_BINFO (type), member, member);
if (!address_p)
{
/* Perform any access checks that were deferred. */
for (check = TREE_PURPOSE (value); check; check = TREE_CHAIN (check))
perform_or_defer_access_check (TREE_PURPOSE (check),
+ TREE_VALUE (check),
TREE_VALUE (check));
/* Return the stored value. */
return TREE_VALUE (value);
value = cp_lexer_consume_token (parser->lexer)->value;
/* Perform any access checks that were deferred. */
for (check = TREE_PURPOSE (value); check; check = TREE_CHAIN (check))
- perform_or_defer_access_check (TREE_PURPOSE (check), TREE_VALUE (check));
+ perform_or_defer_access_check (TREE_PURPOSE (check),
+ TREE_VALUE (check),
+ TREE_VALUE (check));
/* Set the scope from the stored value. */
parser->scope = TREE_VALUE (value);
parser->qualifying_scope = TREE_TYPE (value);
&& !really_overloaded_fn (rval)
&& !(TREE_CODE (rval) == FUNCTION_DECL
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (rval)))
- perform_or_defer_access_check (basetype_path, rval);
+ perform_or_defer_access_check (basetype_path, rval, rval);
if (errstr && protect)
{
/* Check access. */
for (; checks; checks = TREE_CHAIN (checks))
enforce_access (TREE_PURPOSE (checks),
- TREE_VALUE (checks));
+ TREE_VALUE (checks), TREE_VALUE (checks));
}
else
{
while (checks)
{
enforce_access (TREE_PURPOSE (checks),
- TREE_VALUE (checks));
+ TREE_VALUE (checks), TREE_VALUE (checks));
checks = TREE_CHAIN (checks);
}
}
}
/* Defer checking the accessibility of DECL, when looked up in
- BINFO. */
+ BINFO. DIAG_DECL is the declaration to use to print diagnostics. */
void
-perform_or_defer_access_check (tree binfo, tree decl)
+perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl)
{
tree check;
deferred_access *ptr;
/* If we are not supposed to defer access checks, just check now. */
if (ptr->deferring_access_checks_kind == dk_no_deferred)
{
- enforce_access (binfo, decl);
+ enforce_access (binfo, decl, diag_decl);
return;
}
DECL_NAME (decl),
/*template_p=*/false);
- perform_or_defer_access_check (TYPE_BINFO (access_type), decl);
+ perform_or_defer_access_check (TYPE_BINFO (access_type), decl,
+ decl);
/* If the data member was named `C::M', convert `*this' to `C'
first. */
or similar in a default argument value. */
&& CLASS_TYPE_P (qualifying_type)
&& !dependent_type_p (qualifying_type))
- perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl);
+ perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl,
+ decl);
}
/* EXPR is the result of a qualified-id. The QUALIFYING_CLASS was the
tree path;
path = currently_open_derived_class (DECL_CONTEXT (decl));
- perform_or_defer_access_check (TYPE_BINFO (path), decl);
+ perform_or_defer_access_check (TYPE_BINFO (path), decl, decl);
}
decl = convert_from_reference (decl);
+2006-11-20 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/29475
+ * g++.dg/template/access19.C: New test.
+ * g++.old-deja/g++.other/access11.C: Adjusted the line where the
+ error is reported.
+
2006-11-20 Andrew Pinski <andrew_pinski@playstation.sony.com>
PR tree-opt/25500
--- /dev/null
+/* PR c++/29475 The error diagnostic contained "U = U" instead of "U = char" */\r
+/* { dg-do "compile" } */\r
+\r
+template< class T >\r
+class explicit_t\r
+{\r
+public:\r
+ explicit_t( const T& c ): value( c ) { }\r
+ operator T&() { return value; }\r
+private:\r
+ template< class U >\r
+ explicit_t( U t ); /* { dg-error "with U = char, T = int|is private" } */\r
+ T value;\r
+};\r
+\r
+int foo( int x, explicit_t< int > y )\r
+{\r
+ return x + y;\r
+}\r
+\r
+int main()\r
+{\r
+ return foo( 5, 'c' ); /* { dg-error "this context" } */\r
+}\r
class A
{
private:
- template <class T> void g(T t) {} // { dg-error "" } private
+ template <class T> void g(T t) {}
int i;
};
template <>
-void A::g<int>(int t) { i = 1; }
+void A::g<int>(int t) { i = 1; } // { dg-error "" } private
int main()
{