[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
kcl bug - equalp for vectors with fill pointers + FIX
- To: ut-sally!cli.com!kcl
- Subject: kcl bug - equalp for vectors with fill pointers + FIX
- From: David S. Lim <ut-sally!ames!elroy!david@ametek.COM>
- Date: Tue, 22 Mar 88 16:37:33 PST
- Cc: ut-sally!daytona!peggy, ut-sally!daytona!david
- Posted-date: Tue, 22 Mar 88 16:37:33 PST
- Reply-to: ut-sally!ames!ametek.com!david
----------------------------------------------------------------------
There appears to be a bug in kcl when performing an equalp on vectors
(strings, bitvectors) with fill pointers. Rather than comparing only up to the
fill pointer [CtLt p.81], the comparison is done up to the dimension of the
vector.
----------------------------------------------------------------------
KCl (Kyoto Common Lisp) June 3, 1987
>(lisp-implementation-version)
"June 3, 1987"
>(setf a (make-array 5 :initial-element 0 :fill-pointer 5))
#(0 0 0 0 0)
>(setf b (make-array 5 :initial-element 1 :fill-pointer 5))
#(1 1 1 1 1)
>(setf (fill-pointer b) 2)
2
>(pprint b)
#(1 1)
>(setf (aref b 0) 0)
0
>(setf (aref b 1) 0)
0
>(pprint b)
#(0 0)
>(pprint a)
#(0 0 0 0 0)
>(equalp a b)
NIL
----------------------------------------------------------------------
equalp should have returned T.
I believe the bug is in the file c/predicate.c in the routine equalp. There is
a block with label ARRAY: that performs the equalp for arrays.
Approximately lines 523-544 in KCL, or lines 540-561 in AKCL:
----------------------------------------------------------------------
Original code:
ARRAY:
{
int i, j;
if (x->a.a_dim != y->a.a_dim)
return(FALSE);
vs_push(Cnil);
vs_push(Cnil);
for (i = 0, j = x->a.a_dim; i < j; i++) {
vs_top[-2] = aref(x, i);
vs_top[-1] = aref(y, i);
if (!equalp(vs_top[-2], vs_top[-1])) {
vs_pop;
vs_pop;
return(FALSE);
}
}
vs_pop;
vs_pop;
return(TRUE);
}
----------------------------------------------------------------------
New Code:
ARRAY:
{
int i, j;
if (x->a.a_dim != y->a.a_dim)
return(FALSE);
vs_push(Cnil);
vs_push(Cnil);
/* correction to code for equalp of two vector, strings or bit vectors. */
/* should compare only up to fill pointer */
if (ty == t_vector || ty == t_string || ty == t_bitvector){
j = x->v.v_fillp;
if( j > y->v.v_fillp )
j = y->v.v_fillp;
} else {
j = x->a.a_dim;
}
/* for (i = 0, j = x->a.a_dim; i < j; i++) {*/
for (i = 0; i < j; i++) {
/* End of correction */
vs_top[-2] = aref(x, i);
vs_top[-1] = aref(y, i);
if (!equalp(vs_top[-2], vs_top[-1])) {
vs_pop;
vs_pop;
return(FALSE);
}
}
vs_pop;
vs_pop;
return(TRUE);
}
----------------------------------------------------------------------
David Lim
david@ametek.com