aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-05-22 01:30:11 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-05-22 01:30:11 +0000
commitb928a6517e21c8f8929cd21cb78075418a4c3666 (patch)
tree3a205f0cf17eb8c1639d2bf054726a1987381549 /gcc/cp
parent4d49638c24e1f1e9f0f363913f20109b6829dbe7 (diff)
downloadgcc-b928a6517e21c8f8929cd21cb78075418a4c3666.zip
gcc-b928a6517e21c8f8929cd21cb78075418a4c3666.tar.gz
gcc-b928a6517e21c8f8929cd21cb78075418a4c3666.tar.bz2
cp-tree.h (cplus_expand_constant): Declare.
* cp-tree.h (cplus_expand_constant): Declare. * cvt.c (convert_to_pointer): Expand PTRMEM_CSTs when they're converted from one pointer-to-object type to another. * expr.c (cplus_expand_constant): Don't make it static. * typeck.c (build_component_ref): Don't crash when presented with a component which is a TEMPLATE_DECL. (build_ptrmemfunc): Tidy. Clarify comment. Make sure that even a cast from a pointer-to-member constant to its own type does not result in a valid non-type template argument. From-SVN: r27092
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/cvt.c18
-rw-r--r--gcc/cp/expr.c2
-rw-r--r--gcc/cp/typeck.c52
5 files changed, 57 insertions, 28 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6c64408..39cec74 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+1999-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cplus_expand_constant): Declare.
+ * cvt.c (convert_to_pointer): Expand PTRMEM_CSTs when they're
+ converted from one pointer-to-object type to another.
+ * expr.c (cplus_expand_constant): Don't make it static.
+ * typeck.c (build_component_ref): Don't crash when presented with
+ a component which is a TEMPLATE_DECL.
+ (build_ptrmemfunc): Tidy. Clarify comment. Make sure that even a
+ cast from a pointer-to-member constant to its own type does not
+ result in a valid non-type template argument.
+
1999-05-21 Mark Mitchell <mark@codesourcery.com>
Nathan Sidwell <nathan@acm.org>
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b2b6313..ec5ef45 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3007,6 +3007,7 @@ extern void init_cplus_expand PROTO((void));
extern void fixup_result_decl PROTO((tree, struct rtx_def *));
extern int extract_init PROTO((tree, tree));
extern void do_case PROTO((tree, tree));
+extern tree cplus_expand_constant PROTO((tree));
/* friend.c */
extern int is_friend PROTO((tree, tree));
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 7082726..d24dbf1 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -179,19 +179,29 @@ cp_convert_to_pointer (type, expr)
if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
{
- tree b1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (type));
- tree b2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (intype));
- tree binfo = get_binfo (b2, b1, 1);
- enum tree_code code = PLUS_EXPR;
+ tree b1;
+ tree b2;
+ tree binfo;
+ enum tree_code code;
+
+ b1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (type));
+ b2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (intype));
+ binfo = get_binfo (b2, b1, 1);
if (binfo == NULL_TREE)
{
binfo = get_binfo (b1, b2, 1);
code = MINUS_EXPR;
}
+ else
+ code = PLUS_EXPR;
if (binfo == error_mark_node)
return error_mark_node;
+
+ if (TREE_CODE (expr) == PTRMEM_CST)
+ expr = cplus_expand_constant (expr);
+
if (binfo && ! TREE_VIA_VIRTUAL (binfo))
expr = size_binop (code, expr, BINFO_OFFSET (binfo));
}
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index 83bdff9..d5250ae 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -39,7 +39,7 @@ static rtx cplus_expand_expr PROTO((tree, rtx, enum machine_mode,
/* Hook used by output_constant to expand language-specific
constants. */
-static tree
+tree
cplus_expand_constant (cst)
tree cst;
{
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 17147b9..1514ed7 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2138,6 +2138,11 @@ build_component_ref (datum, component, basetype_path, protect)
cp_error ("invalid use of type decl `%#D' as expression", component);
return error_mark_node;
}
+ else if (TREE_CODE (component) == TEMPLATE_DECL)
+ {
+ cp_error ("invalid use of template `%#D' as expression", component);
+ return error_mark_node;
+ }
else
{
tree name = component;
@@ -6516,7 +6521,9 @@ build_ptrmemfunc (type, pfn, force)
int force;
{
tree fn;
-
+ tree pfn_type = TREE_TYPE (pfn);
+ tree to_type = build_ptrmemfunc_type (type);
+
/* Handle multiple conversions of pointer to member functions. */
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (pfn)))
{
@@ -6526,27 +6533,21 @@ build_ptrmemfunc (type, pfn, force)
tree npfn = NULL_TREE;
tree ndelta, ndelta2;
tree e1, e2, e3, n;
- tree pfn_type;
- /* Is is already the right type? */
- if (type == TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn)))
- return pfn;
-
- pfn_type = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn));
- if (!force
- && comp_target_types (type, pfn_type, 1) != 1)
- cp_error ("conversion to `%T' from `%T'", type, pfn_type);
+ if (!force
+ && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn))
+ cp_error ("conversion to `%T' from `%T'",
+ to_type, pfn_type);
if (TREE_CODE (pfn) == PTRMEM_CST)
{
/* We could just build the resulting CONSTRUCTOR now, but we
don't, relying on the general machinery below, together
with constant-folding, to do the right thing. We don't
- want to return a PTRMEM_CST here, even though we could,
- because a pointer-to-member constant ceases to be a
- constant (from the point of view of the language) when it
- is cast to another type. */
-
+ want to return a PTRMEM_CST here, since a
+ pointer-to-member constant is no longer a valid template
+ argument once it is cast to any type, including its
+ original type. */
expand_ptrmemfunc_cst (pfn, &ndelta, &idx, &npfn, &ndelta2);
if (npfn)
/* This constant points to a non-virtual function.
@@ -6554,6 +6555,12 @@ build_ptrmemfunc (type, pfn, force)
matter since we won't use it anyhow. */
ndelta2 = integer_zero_node;
}
+ else if (same_type_p (to_type, pfn_type))
+ /* We don't have to do any conversion. Note that we do this
+ after checking for a PTRMEM_CST so that a PTRMEM_CST, cast
+ to its own type, will not be considered a legal non-type
+ template argument. */
+ return pfn;
else
{
ndelta = cp_convert (ptrdiff_type_node,
@@ -6565,15 +6572,15 @@ build_ptrmemfunc (type, pfn, force)
idx = build_component_ref (pfn, index_identifier, NULL_TREE, 0);
}
- n = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (pfn_type)),
- TYPE_METHOD_BASETYPE (TREE_TYPE (type)),
+ n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type),
+ TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type),
force);
delta = build_binary_op (PLUS_EXPR, ndelta, n);
delta2 = build_binary_op (PLUS_EXPR, ndelta2, n);
e1 = fold (build (GT_EXPR, boolean_type_node, idx, integer_zero_node));
/* If it's a virtual function, this is what we want. */
- e2 = build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta, idx,
+ e2 = build_ptrmemfunc1 (to_type, delta, idx,
NULL_TREE, delta2);
pfn = PFN_FROM_PTRMEMFUNC (pfn);
@@ -6582,7 +6589,7 @@ build_ptrmemfunc (type, pfn, force)
/* But if it's a non-virtual function, or NULL, we use this
instead. */
- e3 = build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta,
+ e3 = build_ptrmemfunc1 (to_type, delta,
idx, npfn, NULL_TREE);
return build_conditional_expr (e1, e2, e3);
}
@@ -6591,7 +6598,7 @@ build_ptrmemfunc (type, pfn, force)
if (integer_zerop (pfn))
{
pfn = build_c_cast (type, integer_zero_node);
- return build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type),
+ return build_ptrmemfunc1 (to_type,
integer_zero_node, integer_zero_node,
pfn, NULL_TREE);
}
@@ -6601,7 +6608,7 @@ build_ptrmemfunc (type, pfn, force)
fn = TREE_OPERAND (pfn, 0);
my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
- return make_ptrmem_cst (build_ptrmemfunc_type (type), fn);
+ return make_ptrmem_cst (to_type, fn);
}
/* Return the DELTA, IDX, PFN, and DELTA2 values for the PTRMEM_CST
@@ -6621,8 +6628,7 @@ expand_ptrmemfunc_cst (cst, delta, idx, pfn, delta2)
my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
*delta
- = get_delta_difference (TYPE_METHOD_BASETYPE
- (TREE_TYPE (fn)),
+ = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (fn)),
TYPE_PTRMEMFUNC_OBJECT_TYPE (type),
/*force=*/0);
if (!DECL_VIRTUAL_P (fn))