mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-20 15:20:59 +08:00
re PR c++/28588 (static private function)
PR c++/28588 * class.c (resolve_address_of_overloaded_function): Add access_path parameter. Perform access checks. (instantiate_type): Adjust call to resolve_address_of_overloaded_function. Remove unnecessary code. * tree.c (is_overloaded_fn): Document. Return 2 when there are acutally multiple functions. (really_overloaded_fn): Use is_overloaded_fn. * mangle.c (write_expression): Handle BASELINKs. * cp-tree.h (really_overloaded_fn): Return bool. (baselink_for_fns): Declare. * search.c (lookup_member): Check access for single static functions here. * pt.c (convert_nontype_argument_function): Handle BASELINKs. (tsubst_copy_and_build): Generate BASELINKs for template-ids. * semantics.c (finish_call_expr): Use baselink_for_fns. (baselink_for_fns): New function. (finish_id_expression): Use it. * parser.c (cp_parser_template_argument): Don't strip BASELINKs. PR c++/28595 * pt.c (tsubst): Issue errors about attempts to create VLAs at template-instantiation time. PR c++/28588 * g++.dg/inherit/access6.C: New test. * g++.dg/inherit/access7.C: Likewise. PR c++/28595 * g++.dg/template/array15.C: New test. * g++.dg/template/crash2.C: Tweak error markers. From-SVN: r116468
This commit is contained in:
parent
fa1ff4eb8c
commit
eff3a27644
@ -1,3 +1,29 @@
|
||||
2006-08-26 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/28588
|
||||
* class.c (resolve_address_of_overloaded_function): Add
|
||||
access_path parameter. Perform access checks.
|
||||
(instantiate_type): Adjust call to
|
||||
resolve_address_of_overloaded_function. Remove unnecessary code.
|
||||
* tree.c (is_overloaded_fn): Document. Return 2 when there are
|
||||
acutally multiple functions.
|
||||
(really_overloaded_fn): Use is_overloaded_fn.
|
||||
* mangle.c (write_expression): Handle BASELINKs.
|
||||
* cp-tree.h (really_overloaded_fn): Return bool.
|
||||
(baselink_for_fns): Declare.
|
||||
* search.c (lookup_member): Check access for single static
|
||||
functions here.
|
||||
* pt.c (convert_nontype_argument_function): Handle BASELINKs.
|
||||
(tsubst_copy_and_build): Generate BASELINKs for template-ids.
|
||||
* semantics.c (finish_call_expr): Use baselink_for_fns.
|
||||
(baselink_for_fns): New function.
|
||||
(finish_id_expression): Use it.
|
||||
* parser.c (cp_parser_template_argument): Don't strip BASELINKs.
|
||||
|
||||
PR c++/28595
|
||||
* pt.c (tsubst): Issue errors about attempts to create VLAs at
|
||||
template-instantiation time.
|
||||
|
||||
2006-08-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
PR c++/28853
|
||||
|
161
gcc/cp/class.c
161
gcc/cp/class.c
@ -134,8 +134,6 @@ static int method_name_cmp (const void *, const void *);
|
||||
static int resort_method_name_cmp (const void *, const void *);
|
||||
static void add_implicitly_declared_members (tree, int, int);
|
||||
static tree fixed_type_or_null (tree, int *, int *);
|
||||
static tree resolve_address_of_overloaded_function (tree, tree, tsubst_flags_t,
|
||||
bool, tree);
|
||||
static tree build_simple_base_path (tree expr, tree binfo);
|
||||
static tree build_vtbl_ref_1 (tree, tree);
|
||||
static tree build_vtbl_initializer (tree, tree, tree, tree, int *);
|
||||
@ -5673,18 +5671,21 @@ pop_lang_context (void)
|
||||
|
||||
/* Given an OVERLOAD and a TARGET_TYPE, return the function that
|
||||
matches the TARGET_TYPE. If there is no satisfactory match, return
|
||||
error_mark_node, and issue an error & warning messages under control
|
||||
of FLAGS. Permit pointers to member function if FLAGS permits. If
|
||||
TEMPLATE_ONLY, the name of the overloaded function was a
|
||||
template-id, and EXPLICIT_TARGS are the explicitly provided
|
||||
template arguments. */
|
||||
error_mark_node, and issue an error & warning messages under
|
||||
control of FLAGS. Permit pointers to member function if FLAGS
|
||||
permits. If TEMPLATE_ONLY, the name of the overloaded function was
|
||||
a template-id, and EXPLICIT_TARGS are the explicitly provided
|
||||
template arguments. If OVERLOAD is for one or more member
|
||||
functions, then ACCESS_PATH is the base path used to reference
|
||||
those member functions. */
|
||||
|
||||
static tree
|
||||
resolve_address_of_overloaded_function (tree target_type,
|
||||
tree overload,
|
||||
tsubst_flags_t flags,
|
||||
bool template_only,
|
||||
tree explicit_targs)
|
||||
tree explicit_targs,
|
||||
tree access_path)
|
||||
{
|
||||
/* Here's what the standard says:
|
||||
|
||||
@ -5935,7 +5936,17 @@ resolve_address_of_overloaded_function (tree target_type,
|
||||
function used. If this conversion sequence is selected, the
|
||||
function will be marked as used at this point. */
|
||||
if (!(flags & tf_conv))
|
||||
mark_used (fn);
|
||||
{
|
||||
mark_used (fn);
|
||||
/* We could not check access when this expression was originally
|
||||
created since we did not know at that time to which function
|
||||
the expression referred. */
|
||||
if (DECL_FUNCTION_MEMBER_P (fn))
|
||||
{
|
||||
gcc_assert (access_path);
|
||||
perform_or_defer_access_check (access_path, fn);
|
||||
}
|
||||
}
|
||||
|
||||
if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
|
||||
return build_unary_op (ADDR_EXPR, fn, 0);
|
||||
@ -5964,6 +5975,7 @@ tree
|
||||
instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
|
||||
{
|
||||
tsubst_flags_t flags_in = flags;
|
||||
tree access_path = NULL_TREE;
|
||||
|
||||
flags &= ~tf_ptrmem_ok;
|
||||
|
||||
@ -5994,7 +6006,10 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
|
||||
}
|
||||
|
||||
if (TREE_CODE (rhs) == BASELINK)
|
||||
rhs = BASELINK_FUNCTIONS (rhs);
|
||||
{
|
||||
access_path = BASELINK_ACCESS_BINFO (rhs);
|
||||
rhs = BASELINK_FUNCTIONS (rhs);
|
||||
}
|
||||
|
||||
/* If we are in a template, and have a NON_DEPENDENT_EXPR, we cannot
|
||||
deduce any type information. */
|
||||
@ -6005,6 +6020,13 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* There only a few kinds of expressions that may have a type
|
||||
dependent on overload resolution. */
|
||||
gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
|
||||
|| TREE_CODE (rhs) == COMPONENT_REF
|
||||
|| TREE_CODE (rhs) == COMPOUND_EXPR
|
||||
|| really_overloaded_fn (rhs));
|
||||
|
||||
/* We don't overwrite rhs if it is an overloaded function.
|
||||
Copying it would destroy the tree link. */
|
||||
if (TREE_CODE (rhs) != OVERLOAD)
|
||||
@ -6017,32 +6039,6 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
|
||||
|
||||
switch (TREE_CODE (rhs))
|
||||
{
|
||||
case TYPE_EXPR:
|
||||
case CONVERT_EXPR:
|
||||
case SAVE_EXPR:
|
||||
case CONSTRUCTOR:
|
||||
gcc_unreachable ();
|
||||
|
||||
case INDIRECT_REF:
|
||||
case ARRAY_REF:
|
||||
{
|
||||
tree new_rhs;
|
||||
|
||||
new_rhs = instantiate_type (build_pointer_type (lhstype),
|
||||
TREE_OPERAND (rhs, 0), flags);
|
||||
if (new_rhs == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
TREE_TYPE (rhs) = lhstype;
|
||||
TREE_OPERAND (rhs, 0) = new_rhs;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
case NOP_EXPR:
|
||||
rhs = copy_node (TREE_OPERAND (rhs, 0));
|
||||
TREE_TYPE (rhs) = unknown_type_node;
|
||||
return instantiate_type (lhstype, rhs, flags);
|
||||
|
||||
case COMPONENT_REF:
|
||||
{
|
||||
tree member = TREE_OPERAND (rhs, 1);
|
||||
@ -6059,7 +6055,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
|
||||
case OFFSET_REF:
|
||||
rhs = TREE_OPERAND (rhs, 1);
|
||||
if (BASELINK_P (rhs))
|
||||
return instantiate_type (lhstype, BASELINK_FUNCTIONS (rhs), flags_in);
|
||||
return instantiate_type (lhstype, rhs, flags_in);
|
||||
|
||||
/* This can happen if we are forming a pointer-to-member for a
|
||||
member template. */
|
||||
@ -6075,7 +6071,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
|
||||
return
|
||||
resolve_address_of_overloaded_function (lhstype, fns, flags_in,
|
||||
/*template_only=*/true,
|
||||
args);
|
||||
args, access_path);
|
||||
}
|
||||
|
||||
case OVERLOAD:
|
||||
@ -6083,14 +6079,9 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
|
||||
return
|
||||
resolve_address_of_overloaded_function (lhstype, rhs, flags_in,
|
||||
/*template_only=*/false,
|
||||
/*explicit_targs=*/NULL_TREE);
|
||||
/*explicit_targs=*/NULL_TREE,
|
||||
access_path);
|
||||
|
||||
case CALL_EXPR:
|
||||
/* This is too hard for now. */
|
||||
gcc_unreachable ();
|
||||
|
||||
case PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
case COMPOUND_EXPR:
|
||||
TREE_OPERAND (rhs, 0)
|
||||
= instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
|
||||
@ -6104,86 +6095,6 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
|
||||
TREE_TYPE (rhs) = lhstype;
|
||||
return rhs;
|
||||
|
||||
case MULT_EXPR:
|
||||
case TRUNC_DIV_EXPR:
|
||||
case FLOOR_DIV_EXPR:
|
||||
case CEIL_DIV_EXPR:
|
||||
case ROUND_DIV_EXPR:
|
||||
case RDIV_EXPR:
|
||||
case TRUNC_MOD_EXPR:
|
||||
case FLOOR_MOD_EXPR:
|
||||
case CEIL_MOD_EXPR:
|
||||
case ROUND_MOD_EXPR:
|
||||
case FIX_ROUND_EXPR:
|
||||
case FIX_FLOOR_EXPR:
|
||||
case FIX_CEIL_EXPR:
|
||||
case FIX_TRUNC_EXPR:
|
||||
case FLOAT_EXPR:
|
||||
case NEGATE_EXPR:
|
||||
case ABS_EXPR:
|
||||
case MAX_EXPR:
|
||||
case MIN_EXPR:
|
||||
|
||||
case BIT_AND_EXPR:
|
||||
case BIT_IOR_EXPR:
|
||||
case BIT_XOR_EXPR:
|
||||
case LSHIFT_EXPR:
|
||||
case RSHIFT_EXPR:
|
||||
case LROTATE_EXPR:
|
||||
case RROTATE_EXPR:
|
||||
|
||||
case PREINCREMENT_EXPR:
|
||||
case PREDECREMENT_EXPR:
|
||||
case POSTINCREMENT_EXPR:
|
||||
case POSTDECREMENT_EXPR:
|
||||
if (flags & tf_error)
|
||||
error ("invalid operation on uninstantiated type");
|
||||
return error_mark_node;
|
||||
|
||||
case TRUTH_AND_EXPR:
|
||||
case TRUTH_OR_EXPR:
|
||||
case TRUTH_XOR_EXPR:
|
||||
case LT_EXPR:
|
||||
case LE_EXPR:
|
||||
case GT_EXPR:
|
||||
case GE_EXPR:
|
||||
case EQ_EXPR:
|
||||
case NE_EXPR:
|
||||
case TRUTH_ANDIF_EXPR:
|
||||
case TRUTH_ORIF_EXPR:
|
||||
case TRUTH_NOT_EXPR:
|
||||
if (flags & tf_error)
|
||||
error ("not enough type information");
|
||||
return error_mark_node;
|
||||
|
||||
case COND_EXPR:
|
||||
if (type_unknown_p (TREE_OPERAND (rhs, 0)))
|
||||
{
|
||||
if (flags & tf_error)
|
||||
error ("not enough type information");
|
||||
return error_mark_node;
|
||||
}
|
||||
TREE_OPERAND (rhs, 1)
|
||||
= instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
|
||||
if (TREE_OPERAND (rhs, 1) == error_mark_node)
|
||||
return error_mark_node;
|
||||
TREE_OPERAND (rhs, 2)
|
||||
= instantiate_type (lhstype, TREE_OPERAND (rhs, 2), flags);
|
||||
if (TREE_OPERAND (rhs, 2) == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
TREE_TYPE (rhs) = lhstype;
|
||||
return rhs;
|
||||
|
||||
case MODIFY_EXPR:
|
||||
TREE_OPERAND (rhs, 1)
|
||||
= instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
|
||||
if (TREE_OPERAND (rhs, 1) == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
TREE_TYPE (rhs) = lhstype;
|
||||
return rhs;
|
||||
|
||||
case ADDR_EXPR:
|
||||
{
|
||||
if (PTRMEM_OK_P (rhs))
|
||||
|
@ -4321,6 +4321,7 @@ extern tree cxx_omp_clause_copy_ctor (tree, tree, tree);
|
||||
extern tree cxx_omp_clause_assign_op (tree, tree, tree);
|
||||
extern tree cxx_omp_clause_dtor (tree, tree);
|
||||
extern bool cxx_omp_privatize_by_reference (tree);
|
||||
extern tree baselink_for_fns (tree);
|
||||
|
||||
/* in tree.c */
|
||||
extern void lang_check_failed (const char *, int,
|
||||
@ -4364,7 +4365,7 @@ extern bool decl_anon_ns_mem_p (tree);
|
||||
extern tree lvalue_type (tree);
|
||||
extern tree error_type (tree);
|
||||
extern int varargs_function_p (tree);
|
||||
extern int really_overloaded_fn (tree);
|
||||
extern bool really_overloaded_fn (tree);
|
||||
extern bool cp_tree_equal (tree, tree);
|
||||
extern tree no_linkage_check (tree, bool);
|
||||
extern void debug_binfo (tree);
|
||||
|
@ -2023,6 +2023,12 @@ write_expression (tree expr)
|
||||
code = TREE_CODE (expr);
|
||||
}
|
||||
|
||||
if (code == BASELINK)
|
||||
{
|
||||
expr = BASELINK_FUNCTIONS (expr);
|
||||
code = TREE_CODE (expr);
|
||||
}
|
||||
|
||||
/* Handle pointers-to-members by making them look like expression
|
||||
nodes. */
|
||||
if (code == PTRMEM_CST)
|
||||
|
@ -9237,11 +9237,6 @@ cp_parser_template_argument (cp_parser* parser)
|
||||
argument = TREE_OPERAND (argument, 0);
|
||||
}
|
||||
|
||||
if (TREE_CODE (argument) == BASELINK)
|
||||
/* We don't need the information about what class was used
|
||||
to name the overloaded functions. */
|
||||
argument = BASELINK_FUNCTIONS (argument);
|
||||
|
||||
if (TREE_CODE (argument) == VAR_DECL)
|
||||
{
|
||||
/* A variable without external linkage might still be a
|
||||
|
16
gcc/cp/pt.c
16
gcc/cp/pt.c
@ -3454,7 +3454,9 @@ convert_nontype_argument_function (tree type, tree expr)
|
||||
fn_no_ptr = fn;
|
||||
if (TREE_CODE (fn_no_ptr) == ADDR_EXPR)
|
||||
fn_no_ptr = TREE_OPERAND (fn_no_ptr, 0);
|
||||
|
||||
if (TREE_CODE (fn_no_ptr) == BASELINK)
|
||||
fn_no_ptr = BASELINK_FUNCTIONS (fn_no_ptr);
|
||||
|
||||
/* [temp.arg.nontype]/1
|
||||
|
||||
A template-argument for a non-type, non-template template-parameter
|
||||
@ -7192,6 +7194,15 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||
max = tsubst_template_arg (omax, args, complain, in_decl);
|
||||
max = fold_decl_constant_value (max);
|
||||
|
||||
if (TREE_CODE (max) != INTEGER_CST
|
||||
&& TREE_CODE (max) != TEMPLATE_PARM_INDEX
|
||||
&& !at_function_scope_p ())
|
||||
{
|
||||
if (complain & tf_error)
|
||||
error ("array bound is not an integer constant");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* [temp.deduct]
|
||||
|
||||
Type deduction may fail for any of the following
|
||||
@ -7204,7 +7215,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||
indicated by the state of complain), so that
|
||||
another substitution can be found. */
|
||||
return error_mark_node;
|
||||
|
||||
else if (TREE_CODE (max) == INTEGER_CST
|
||||
&& INT_CST_LT (max, integer_zero_node))
|
||||
{
|
||||
@ -8824,7 +8834,7 @@ tsubst_copy_and_build (tree t,
|
||||
return build3 (COMPONENT_REF, TREE_TYPE (template),
|
||||
object, template, NULL_TREE);
|
||||
else
|
||||
return template;
|
||||
return baselink_for_fns (template);
|
||||
}
|
||||
|
||||
case INDIRECT_REF:
|
||||
|
@ -1253,8 +1253,26 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type)
|
||||
/* [class.access]
|
||||
|
||||
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))
|
||||
applied to the function selected by overloaded resolution.
|
||||
|
||||
We cannot check here, even if RVAL is only a single non-static
|
||||
member function, since we do not know what the "this" pointer
|
||||
will be. For:
|
||||
|
||||
class A { protected: void f(); };
|
||||
class B : public A {
|
||||
void g(A *p) {
|
||||
f(); // OK
|
||||
p->f(); // Not OK.
|
||||
}
|
||||
};
|
||||
|
||||
only the first call to "f" is valid. However, if the function is
|
||||
static, we can check. */
|
||||
if (rval && protect
|
||||
&& !really_overloaded_fn (rval)
|
||||
&& !(TREE_CODE (rval) == FUNCTION_DECL
|
||||
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (rval)))
|
||||
perform_or_defer_access_check (basetype_path, rval);
|
||||
|
||||
if (errstr && protect)
|
||||
|
@ -1774,26 +1774,8 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
|
||||
args = build_non_dependent_args (orig_args);
|
||||
}
|
||||
|
||||
/* A reference to a member function will appear as an overloaded
|
||||
function (rather than a BASELINK) if an unqualified name was used
|
||||
to refer to it. */
|
||||
if (!BASELINK_P (fn) && is_overloaded_fn (fn))
|
||||
{
|
||||
tree f = fn;
|
||||
|
||||
if (TREE_CODE (f) == TEMPLATE_ID_EXPR)
|
||||
f = TREE_OPERAND (f, 0);
|
||||
f = get_first_fn (f);
|
||||
if (DECL_FUNCTION_MEMBER_P (f))
|
||||
{
|
||||
tree type = currently_open_derived_class (DECL_CONTEXT (f));
|
||||
if (!type)
|
||||
type = DECL_CONTEXT (f);
|
||||
fn = build_baselink (TYPE_BINFO (type),
|
||||
TYPE_BINFO (type),
|
||||
fn, /*optype=*/NULL_TREE);
|
||||
}
|
||||
}
|
||||
if (is_overloaded_fn (fn))
|
||||
fn = baselink_for_fns (fn);
|
||||
|
||||
result = NULL_TREE;
|
||||
if (BASELINK_P (fn))
|
||||
@ -2405,6 +2387,36 @@ qualified_name_lookup_error (tree scope, tree name, tree decl)
|
||||
error ("%<::%D%> has not been declared", name);
|
||||
}
|
||||
|
||||
/* If FNS is a member function, a set of member functions, or a
|
||||
template-id referring to one or more member functions, return a
|
||||
BASELINK for FNS, incorporating the current access context.
|
||||
Otherwise, return FNS unchanged. */
|
||||
|
||||
tree
|
||||
baselink_for_fns (tree fns)
|
||||
{
|
||||
tree fn;
|
||||
tree cl;
|
||||
|
||||
if (BASELINK_P (fns)
|
||||
|| processing_template_decl
|
||||
|| error_operand_p (fns))
|
||||
return fns;
|
||||
|
||||
fn = fns;
|
||||
if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
|
||||
fn = TREE_OPERAND (fn, 0);
|
||||
fn = get_first_fn (fn);
|
||||
if (!DECL_FUNCTION_MEMBER_P (fn))
|
||||
return fns;
|
||||
|
||||
cl = currently_open_derived_class (DECL_CONTEXT (fn));
|
||||
if (!cl)
|
||||
cl = DECL_CONTEXT (fn);
|
||||
cl = TYPE_BINFO (cl);
|
||||
return build_baselink (cl, cl, fns, /*optype=*/NULL_TREE);
|
||||
}
|
||||
|
||||
/* ID_EXPRESSION is a representation of parsed, but unprocessed,
|
||||
id-expression. (See cp_parser_id_expression for details.) SCOPE,
|
||||
if non-NULL, is the type or namespace used to explicitly qualify
|
||||
@ -2793,8 +2805,12 @@ finish_id_expression (tree id_expression,
|
||||
}
|
||||
else if (is_overloaded_fn (decl))
|
||||
{
|
||||
tree first_fn = OVL_CURRENT (decl);
|
||||
tree first_fn;
|
||||
|
||||
first_fn = decl;
|
||||
if (TREE_CODE (first_fn) == TEMPLATE_ID_EXPR)
|
||||
first_fn = TREE_OPERAND (first_fn, 0);
|
||||
first_fn = get_first_fn (first_fn);
|
||||
if (TREE_CODE (first_fn) == TEMPLATE_DECL)
|
||||
first_fn = DECL_TEMPLATE_RESULT (first_fn);
|
||||
|
||||
@ -2811,6 +2827,8 @@ finish_id_expression (tree id_expression,
|
||||
return finish_class_member_access_expr (decl, id_expression,
|
||||
/*template_p=*/false);
|
||||
}
|
||||
|
||||
decl = baselink_for_fns (decl);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -842,6 +842,13 @@ build_qualified_name (tree type, tree scope, tree name, bool template_p)
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Returns non-zero if X is an expression for a (possibly overloaded)
|
||||
function. If "f" is a function or function template, "f", "c->f",
|
||||
"c.f", "C::f", and "f<int>" will all be considered possibly
|
||||
overloaded functions. Returns 2 if the function is actually
|
||||
overloaded, i.e., if it is impossible to know the the type of the
|
||||
function without performing overload resolution. */
|
||||
|
||||
int
|
||||
is_overloaded_fn (tree x)
|
||||
{
|
||||
@ -850,24 +857,22 @@ is_overloaded_fn (tree x)
|
||||
x = TREE_OPERAND (x, 1);
|
||||
if (BASELINK_P (x))
|
||||
x = BASELINK_FUNCTIONS (x);
|
||||
return (TREE_CODE (x) == FUNCTION_DECL
|
||||
|| TREE_CODE (x) == TEMPLATE_ID_EXPR
|
||||
|| DECL_FUNCTION_TEMPLATE_P (x)
|
||||
|| TREE_CODE (x) == OVERLOAD);
|
||||
if (TREE_CODE (x) == TEMPLATE_ID_EXPR
|
||||
|| DECL_FUNCTION_TEMPLATE_P (OVL_CURRENT (x))
|
||||
|| (TREE_CODE (x) == OVERLOAD && OVL_CHAIN (x)))
|
||||
return 2;
|
||||
return (TREE_CODE (x) == FUNCTION_DECL
|
||||
|| TREE_CODE (x) == OVERLOAD);
|
||||
}
|
||||
|
||||
int
|
||||
/* Returns true iff X is an expression for an overloaded function
|
||||
whose type cannot be known without performing overload
|
||||
resolution. */
|
||||
|
||||
bool
|
||||
really_overloaded_fn (tree x)
|
||||
{
|
||||
if (TREE_CODE (x) == OFFSET_REF)
|
||||
x = TREE_OPERAND (x, 1);
|
||||
/* A baselink is also considered an overloaded function. */
|
||||
if (BASELINK_P (x))
|
||||
x = BASELINK_FUNCTIONS (x);
|
||||
|
||||
return ((TREE_CODE (x) == OVERLOAD && OVL_CHAIN (x))
|
||||
|| DECL_FUNCTION_TEMPLATE_P (OVL_CURRENT (x))
|
||||
|| TREE_CODE (x) == TEMPLATE_ID_EXPR);
|
||||
return is_overloaded_fn (x) == 2;
|
||||
}
|
||||
|
||||
tree
|
||||
|
@ -1,3 +1,13 @@
|
||||
2006-08-26 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/28588
|
||||
* g++.dg/inherit/access6.C: New test.
|
||||
* g++.dg/inherit/access7.C: Likewise.
|
||||
|
||||
PR c++/28595
|
||||
* g++.dg/template/array15.C: New test.
|
||||
* g++.dg/template/crash2.C: Tweak error markers.
|
||||
|
||||
2006-08-26 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/28683
|
||||
|
15
gcc/testsuite/g++.dg/inherit/access6.C
Normal file
15
gcc/testsuite/g++.dg/inherit/access6.C
Normal file
@ -0,0 +1,15 @@
|
||||
// PR c++/28588
|
||||
|
||||
class Foo {
|
||||
static void f(); // { dg-error "private" }
|
||||
static void f(int);
|
||||
static void g(); // { dg-error "private" }
|
||||
};
|
||||
|
||||
void h()
|
||||
{
|
||||
Foo foo;
|
||||
void (*f)();
|
||||
f = foo.f; // { dg-error "context" }
|
||||
f = foo.g; // { dg-error "context" }
|
||||
}
|
15
gcc/testsuite/g++.dg/inherit/access7.C
Normal file
15
gcc/testsuite/g++.dg/inherit/access7.C
Normal file
@ -0,0 +1,15 @@
|
||||
struct B {
|
||||
static void f();
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct D : private B {
|
||||
void g() {
|
||||
f();
|
||||
}
|
||||
};
|
||||
|
||||
void h() {
|
||||
D<int> d;
|
||||
d.g();
|
||||
}
|
13
gcc/testsuite/g++.dg/template/array15.C
Normal file
13
gcc/testsuite/g++.dg/template/array15.C
Normal file
@ -0,0 +1,13 @@
|
||||
// PR c++/28595
|
||||
|
||||
template<int> struct A
|
||||
{
|
||||
static const int i;
|
||||
};
|
||||
|
||||
template<int N> struct B
|
||||
{
|
||||
char c[A<N>::i], d; // { dg-error "constant" }
|
||||
};
|
||||
|
||||
B<0> b;
|
@ -5,7 +5,7 @@ class A
|
||||
{
|
||||
public:
|
||||
static const EnumType size = max; // { dg-error "" }
|
||||
int table[size];
|
||||
int table[size]; // { dg-error "constant" }
|
||||
};
|
||||
template <class EnumType>
|
||||
const EnumType A<EnumType>::size;
|
||||
|
Loading…
x
Reference in New Issue
Block a user