mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-28 11:15:40 +08:00
c++: Add some conversion sanity checking.
Another change I was working on revealed that for complex numbers we were building a ck_identity with build_conv, leading to the wrong active member in the union being set. Rather than add another enumeration of the appropriate conversion codes, I factored that out. gcc/cp/ChangeLog: * call.c (has_next): Factor out from... (next_conversion): ...here. (strip_standard_conversion): And here. (is_subseq): And here. (build_conv): Check it. (standard_conversion): Don't call build_conv for ck_identity.
This commit is contained in:
parent
b7c3f201be
commit
4d65a07d54
@ -761,12 +761,26 @@ alloc_conversions (size_t n)
|
||||
return (conversion **) conversion_obstack_alloc (n * sizeof (conversion *));
|
||||
}
|
||||
|
||||
/* True iff the active member of conversion::u for code CODE is NEXT. */
|
||||
|
||||
static inline bool
|
||||
has_next (conversion_kind code)
|
||||
{
|
||||
return !(code == ck_identity
|
||||
|| code == ck_ambig
|
||||
|| code == ck_list
|
||||
|| code == ck_aggr);
|
||||
}
|
||||
|
||||
static conversion *
|
||||
build_conv (conversion_kind code, tree type, conversion *from)
|
||||
{
|
||||
conversion *t;
|
||||
conversion_rank rank = CONVERSION_RANK (from);
|
||||
|
||||
/* Only call this function for conversions that use u.next. */
|
||||
gcc_assert (from == NULL || has_next (code));
|
||||
|
||||
/* Note that the caller is responsible for filling in t->cand for
|
||||
user-defined conversions. */
|
||||
t = alloc_conversion (code);
|
||||
@ -863,10 +877,7 @@ static conversion *
|
||||
next_conversion (conversion *conv)
|
||||
{
|
||||
if (conv == NULL
|
||||
|| conv->kind == ck_identity
|
||||
|| conv->kind == ck_ambig
|
||||
|| conv->kind == ck_list
|
||||
|| conv->kind == ck_aggr)
|
||||
|| !has_next (conv->kind))
|
||||
return NULL;
|
||||
return conv->u.next;
|
||||
}
|
||||
@ -879,10 +890,7 @@ strip_standard_conversion (conversion *conv)
|
||||
{
|
||||
while (conv
|
||||
&& conv->kind != ck_user
|
||||
&& conv->kind != ck_ambig
|
||||
&& conv->kind != ck_list
|
||||
&& conv->kind != ck_aggr
|
||||
&& conv->kind != ck_identity)
|
||||
&& has_next (conv->kind))
|
||||
conv = next_conversion (conv);
|
||||
return conv;
|
||||
}
|
||||
@ -1266,13 +1274,15 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
|
||||
(TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, c_cast_p, flags,
|
||||
complain);
|
||||
|
||||
if (part_conv)
|
||||
if (!part_conv)
|
||||
conv = NULL;
|
||||
else if (part_conv->kind == ck_identity)
|
||||
/* Leave conv alone. */;
|
||||
else
|
||||
{
|
||||
conv = build_conv (part_conv->kind, to, conv);
|
||||
conv->rank = part_conv->rank;
|
||||
}
|
||||
else
|
||||
conv = NULL;
|
||||
|
||||
return conv;
|
||||
}
|
||||
@ -10619,10 +10629,7 @@ is_subseq (conversion *ics1, conversion *ics2)
|
||||
ics2 = next_conversion (ics2);
|
||||
|
||||
if (ics2->kind == ck_user
|
||||
|| ics2->kind == ck_ambig
|
||||
|| ics2->kind == ck_aggr
|
||||
|| ics2->kind == ck_list
|
||||
|| ics2->kind == ck_identity)
|
||||
|| !has_next (ics2->kind))
|
||||
/* At this point, ICS1 cannot be a proper subsequence of
|
||||
ICS2. We can get a USER_CONV when we are comparing the
|
||||
second standard conversion sequence of two user conversion
|
||||
|
Loading…
Reference in New Issue
Block a user