aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2006-08-26 16:23:33 +0000
committerMark Mitchell <mark@codesourcery.com>2006-08-26 16:23:33 +0000
commit00847d3b2d3ab32f75ab634eceb338c153d6e4bc (patch)
tree0365ed4c2d70b546d5308383eda316cb067b2b23
parent5fc1f062059d1570f7259d36109473fb71f37adc (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@116468 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog26
-rw-r--r--gcc/cp/class.c161
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/mangle.c6
-rw-r--r--gcc/cp/parser.c5
-rw-r--r--gcc/cp/pt.c16
-rw-r--r--gcc/cp/search.c22
-rw-r--r--gcc/cp/semantics.c60
-rw-r--r--gcc/cp/tree.c33
-rw-r--r--gcc/testsuite/ChangeLog10
-rw-r--r--gcc/testsuite/g++.dg/inherit/access6.C15
-rw-r--r--gcc/testsuite/g++.dg/inherit/access7.C15
-rw-r--r--gcc/testsuite/g++.dg/template/array15.C13
-rw-r--r--gcc/testsuite/g++.dg/template/crash2.C2
14 files changed, 215 insertions, 172 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 171103beca5..d7c952dd880 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 06f8cbceb53..673b07fb3d0 100644
--- a/gcc/cp/class.c
+++ b/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))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 713d3711420..c50836b0be0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 8c8eff92805..74ff8543eb4 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -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)
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 729d0ca488c..4e62340a0e9 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 749291c63e3..e078149fa77 100644
--- a/gcc/cp/pt.c
+++ b/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:
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index d54e6078cb1..45a5ea3d10b 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -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)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 56dbe6fddad..94e6dfd312c 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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
{
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 1cedec55f8d..db7e40a9cd4 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b9ddcf0ba93..017de891864 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/inherit/access6.C b/gcc/testsuite/g++.dg/inherit/access6.C
new file mode 100644
index 00000000000..7645c2d5e0d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/inherit/access6.C
@@ -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" }
+}
diff --git a/gcc/testsuite/g++.dg/inherit/access7.C b/gcc/testsuite/g++.dg/inherit/access7.C
new file mode 100644
index 00000000000..4e2db1479b7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/inherit/access7.C
@@ -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();
+}
diff --git a/gcc/testsuite/g++.dg/template/array15.C b/gcc/testsuite/g++.dg/template/array15.C
new file mode 100644
index 00000000000..b1e047d1d00
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/array15.C
@@ -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;
diff --git a/gcc/testsuite/g++.dg/template/crash2.C b/gcc/testsuite/g++.dg/template/crash2.C
index a02787a46fa..47c95ab067f 100644
--- a/gcc/testsuite/g++.dg/template/crash2.C
+++ b/gcc/testsuite/g++.dg/template/crash2.C
@@ -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;