Commit a5d1cd09 by Jason Merrill Committed by Jason Merrill

typeck.c (comp_cv_target_types): Split out...

	* typeck.c (comp_cv_target_types): Split out...
	(comp_target_types): From here.  Don't allow cv-qual changes under
	a pointer if nptrs == 0.  Fix OFFSET_TYPE handling.
	(build_ptrmemfunc): Pass 1 to nptrs.
	* cvt.c (perform_qualification_conversions): Use comp_ptr_ttypes.

From-SVN: r21974
parent e94bc5f2
1998-08-25 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (comp_cv_target_types): Split out...
(comp_target_types): From here. Don't allow cv-qual changes under
a pointer if nptrs == 0. Fix OFFSET_TYPE handling.
(build_ptrmemfunc): Pass 1 to nptrs.
* cvt.c (perform_qualification_conversions): Use comp_ptr_ttypes.
1998-08-25 Mark Mitchell <mark@markmitchell.com> 1998-08-25 Mark Mitchell <mark@markmitchell.com>
* search.c (dependent_base_p): Don't compare a binfo to * search.c (dependent_base_p): Don't compare a binfo to
......
...@@ -1094,7 +1094,6 @@ type_promotes_to (type) ...@@ -1094,7 +1094,6 @@ type_promotes_to (type)
return cp_build_type_variant (type, constp, volatilep); return cp_build_type_variant (type, constp, volatilep);
} }
/* The routines below this point are carefully written to conform to /* The routines below this point are carefully written to conform to
the standard. They use the same terminology, and follow the rules the standard. They use the same terminology, and follow the rules
closely. Although they are used only in pt.c at the moment, they closely. Although they are used only in pt.c at the moment, they
...@@ -1109,7 +1108,9 @@ perform_qualification_conversions (type, expr) ...@@ -1109,7 +1108,9 @@ perform_qualification_conversions (type, expr)
tree type; tree type;
tree expr; tree expr;
{ {
if (comp_target_types (type, TREE_TYPE (expr), 0) == 1) if (TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE
&& comp_ptr_ttypes (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (expr))))
return build1 (NOP_EXPR, type, expr); return build1 (NOP_EXPR, type, expr);
else else
return error_mark_node; return error_mark_node;
......
...@@ -912,6 +912,31 @@ comptypes (type1, type2, strict) ...@@ -912,6 +912,31 @@ comptypes (type1, type2, strict)
return attrval == 2 && val == 1 ? 2 : val; return attrval == 2 && val == 1 ? 2 : val;
} }
/* Subroutine of comp_target-types. Make sure that the cv-quals change
only in the same direction as the target type. */
static int
comp_cv_target_types (ttl, ttr, nptrs)
tree ttl, ttr;
int nptrs;
{
int t;
int c = TYPE_READONLY (ttl) - TYPE_READONLY (ttr);
int v = TYPE_VOLATILE (ttl) - TYPE_VOLATILE (ttr);
if ((c > 0 && v < 0) || (c < 0 && v > 0))
return 0;
if (TYPE_MAIN_VARIANT (ttl) == TYPE_MAIN_VARIANT (ttr))
return (c + v < 0) ? -1 : 1;
t = comp_target_types (ttl, ttr, nptrs);
if ((t == 1 && c + v >= 0) || (t == -1 && c + v <= 0))
return t;
return 0;
}
/* Return 1 or -1 if TTL and TTR are pointers to types that are equivalent, /* Return 1 or -1 if TTL and TTR are pointers to types that are equivalent,
ignoring their qualifiers, 0 if not. Return 1 means that TTR can be ignoring their qualifiers, 0 if not. Return 1 means that TTR can be
converted to TTL. Return -1 means that TTL can be converted to TTR but converted to TTL. Return -1 means that TTL can be converted to TTR but
...@@ -937,15 +962,20 @@ comp_target_types (ttl, ttr, nptrs) ...@@ -937,15 +962,20 @@ comp_target_types (ttl, ttr, nptrs)
if (TREE_CODE (ttr) != TREE_CODE (ttl)) if (TREE_CODE (ttr) != TREE_CODE (ttl))
return 0; return 0;
if (TREE_CODE (ttr) == POINTER_TYPE if ((TREE_CODE (ttr) == POINTER_TYPE
|| (TREE_CODE (ttr) == REFERENCE_TYPE)) || TREE_CODE (ttr) == REFERENCE_TYPE)
/* If we get a pointer with nptrs == 0, we don't allow any tweaking
of the type pointed to. This is necessary for reference init
semantics. We won't get here from a previous call with nptrs == 1;
for multi-level pointers we end up in comp_ptr_ttypes. */
&& nptrs > 0)
{ {
int is_ptr = TREE_CODE (ttr) == POINTER_TYPE; int is_ptr = TREE_CODE (ttr) == POINTER_TYPE;
ttl = TREE_TYPE (ttl); ttl = TREE_TYPE (ttl);
ttr = TREE_TYPE (ttr); ttr = TREE_TYPE (ttr);
if (nptrs > 0 && is_ptr) if (is_ptr)
{ {
if (TREE_CODE (ttl) == UNKNOWN_TYPE if (TREE_CODE (ttl) == UNKNOWN_TYPE
|| TREE_CODE (ttr) == UNKNOWN_TYPE) || TREE_CODE (ttr) == UNKNOWN_TYPE)
...@@ -976,25 +1006,7 @@ comp_target_types (ttl, ttr, nptrs) ...@@ -976,25 +1006,7 @@ comp_target_types (ttl, ttr, nptrs)
if (TREE_CODE (ttl) == FUNCTION_TYPE || TREE_CODE (ttl) == METHOD_TYPE) if (TREE_CODE (ttl) == FUNCTION_TYPE || TREE_CODE (ttl) == METHOD_TYPE)
return comp_target_types (ttl, ttr, nptrs - 1); return comp_target_types (ttl, ttr, nptrs - 1);
/* Make sure that the cv-quals change only in the same direction as return comp_cv_target_types (ttl, ttr, nptrs - 1);
the target type. */
{
int t;
int c = TYPE_READONLY (ttl) - TYPE_READONLY (ttr);
int v = TYPE_VOLATILE (ttl) - TYPE_VOLATILE (ttr);
if ((c > 0 && v < 0) || (c < 0 && v > 0))
return 0;
if (TYPE_MAIN_VARIANT (ttl) == TYPE_MAIN_VARIANT (ttr))
return (c + v < 0) ? -1 : 1;
t = comp_target_types (ttl, ttr, nptrs - 1);
if ((t == 1 && c + v >= 0) || (t == -1 && c + v <= 0))
return t;
return 0;
}
} }
if (TREE_CODE (ttr) == ARRAY_TYPE) if (TREE_CODE (ttr) == ARRAY_TYPE)
...@@ -1054,16 +1066,42 @@ comp_target_types (ttl, ttr, nptrs) ...@@ -1054,16 +1066,42 @@ comp_target_types (ttl, ttr, nptrs)
/* for C++ */ /* for C++ */
else if (TREE_CODE (ttr) == OFFSET_TYPE) else if (TREE_CODE (ttr) == OFFSET_TYPE)
{ {
int base;
tree tmp;
/* Contravariance: we can assign a pointer to base member to a pointer /* Contravariance: we can assign a pointer to base member to a pointer
to derived member. Note difference from simple pointer case, where to derived member. Note difference from simple pointer case, where
we can pass a pointer to derived to a pointer to base. */ we can pass a pointer to derived to a pointer to base. */
if (comptypes (TYPE_OFFSET_BASETYPE (ttr), if (comptypes (TYPE_OFFSET_BASETYPE (ttr),
TYPE_OFFSET_BASETYPE (ttl), 0)) TYPE_OFFSET_BASETYPE (ttl), 0))
return comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs); base = 1;
else if (comptypes (TYPE_OFFSET_BASETYPE (ttl), else if (comptypes (TYPE_OFFSET_BASETYPE (ttl),
TYPE_OFFSET_BASETYPE (ttr), 0) TYPE_OFFSET_BASETYPE (ttr), 0))
&& comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs)) {
return -1; tree tmp = ttl;
ttl = ttr;
ttr = tmp;
base = -1;
}
else
return 0;
ttl = TREE_TYPE (ttl);
ttr = TREE_TYPE (ttr);
if (TREE_CODE (ttl) == POINTER_TYPE
|| TREE_CODE (ttl) == ARRAY_TYPE)
{
if (comp_ptr_ttypes (ttl, ttr))
return base;
return 0;
}
else
{
if (comp_cv_target_types (ttl, ttr, nptrs) == 1)
return base;
return 0;
}
} }
else if (IS_AGGR_TYPE (ttl)) else if (IS_AGGR_TYPE (ttl))
{ {
...@@ -6515,7 +6553,7 @@ build_ptrmemfunc (type, pfn, force) ...@@ -6515,7 +6553,7 @@ build_ptrmemfunc (type, pfn, force)
pfn_type = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn)); pfn_type = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn));
if (!force if (!force
&& comp_target_types (type, pfn_type, 0) != 1) && comp_target_types (type, pfn_type, 1) != 1)
cp_error ("conversion to `%T' from `%T'", type, pfn_type); cp_error ("conversion to `%T' from `%T'", type, pfn_type);
ndelta = cp_convert (ptrdiff_type_node, build_component_ref (pfn, delta_identifier, NULL_TREE, 0)); ndelta = cp_convert (ptrdiff_type_node, build_component_ref (pfn, delta_identifier, NULL_TREE, 0));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment