re PR c++/29475 (incomplete template diagnostics.)
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. 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. From-SVN: r119027
This commit is contained in:
parent
903ff2758b
commit
02022f3a70
13 changed files with 92 additions and 30 deletions
|
@ -1,3 +1,28 @@
|
|||
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
|
||||
|
|
|
@ -4097,7 +4097,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_BINFO (type), fn);
|
||||
perform_or_defer_access_check (TYPE_BINFO (type), fn, fn);
|
||||
|
||||
if (pass == 0)
|
||||
args = tree_cons (NULL_TREE, addr, args);
|
||||
|
@ -4128,21 +4128,22 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
|
|||
|
||||
/* 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;
|
||||
}
|
||||
|
@ -4771,9 +4772,9 @@ build_over_call (struct z_candidate *cand, int flags)
|
|||
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)
|
||||
|
|
|
@ -1129,7 +1129,7 @@ alter_access (tree t, tree fdecl, tree access)
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
@ -5958,7 +5958,7 @@ resolve_address_of_overloaded_function (tree target_type,
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3772,7 +3772,7 @@ extern tree build_op_delete_call (enum tree_code, tree, tree, bool, tree, tree)
|
|||
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);
|
||||
|
@ -4209,7 +4209,7 @@ extern tree get_deferred_access_checks (void);
|
|||
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);
|
||||
|
|
|
@ -2858,7 +2858,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
|
|||
}
|
||||
|
||||
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),
|
||||
|
@ -2921,7 +2921,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list,
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ add_friend (tree type, tree decl, bool complain)
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
@ -1383,9 +1383,9 @@ build_offset_ref (tree type, tree member, bool address_p)
|
|||
(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;
|
||||
|
@ -1398,7 +1398,7 @@ build_offset_ref (tree type, tree member, bool address_p)
|
|||
/* 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)
|
||||
{
|
||||
|
|
|
@ -8759,6 +8759,7 @@ cp_parser_template_id (cp_parser *parser,
|
|||
/* 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);
|
||||
|
@ -16643,7 +16644,9 @@ cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
|
|||
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);
|
||||
|
|
|
@ -1273,7 +1273,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type)
|
|||
&& !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)
|
||||
{
|
||||
|
|
|
@ -234,7 +234,7 @@ pop_to_parent_deferring_access_checks (void)
|
|||
/* Check access. */
|
||||
for (; checks; checks = TREE_CHAIN (checks))
|
||||
enforce_access (TREE_PURPOSE (checks),
|
||||
TREE_VALUE (checks));
|
||||
TREE_VALUE (checks), TREE_VALUE (checks));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -271,7 +271,7 @@ perform_access_checks (tree checks)
|
|||
while (checks)
|
||||
{
|
||||
enforce_access (TREE_PURPOSE (checks),
|
||||
TREE_VALUE (checks));
|
||||
TREE_VALUE (checks), TREE_VALUE (checks));
|
||||
checks = TREE_CHAIN (checks);
|
||||
}
|
||||
}
|
||||
|
@ -299,10 +299,10 @@ perform_deferred_access_checks (void)
|
|||
}
|
||||
|
||||
/* 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;
|
||||
|
@ -319,7 +319,7 @@ perform_or_defer_access_check (tree binfo, tree decl)
|
|||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -1432,7 +1432,8 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
|
|||
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. */
|
||||
|
@ -1511,7 +1512,8 @@ check_accessibility_of_qualified_id (tree decl,
|
|||
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
|
||||
|
@ -2839,7 +2841,7 @@ finish_id_expression (tree id_expression,
|
|||
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);
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
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
|
||||
|
|
24
gcc/testsuite/g++.dg/template/access19.C
Executable file
24
gcc/testsuite/g++.dg/template/access19.C
Executable file
|
@ -0,0 +1,24 @@
|
|||
/* PR c++/29475 The error diagnostic contained "U = U" instead of "U = char" */
|
||||
/* { dg-do "compile" } */
|
||||
|
||||
template< class T >
|
||||
class explicit_t
|
||||
{
|
||||
public:
|
||||
explicit_t( const T& c ): value( c ) { }
|
||||
operator T&() { return value; }
|
||||
private:
|
||||
template< class U >
|
||||
explicit_t( U t ); /* { dg-error "with U = char, T = int|is private" } */
|
||||
T value;
|
||||
};
|
||||
|
||||
int foo( int x, explicit_t< int > y )
|
||||
{
|
||||
return x + y;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
return foo( 5, 'c' ); /* { dg-error "this context" } */
|
||||
}
|
|
@ -5,12 +5,12 @@
|
|||
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()
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue