summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wiebe <mwwiebe@gmail.com>2011-04-23 13:06:12 -0700
committerMark Wiebe <mwwiebe@gmail.com>2011-04-23 13:07:00 -0700
commit5eae1f468fdcd1654e985ebfe5cd37479d41a06c (patch)
treee026bd992cf9148ab3edc4920bfc1f50419c2946
parent566ace25f63985e0739bcc600c35336d3c66508c (diff)
downloadnumpy-5eae1f468fdcd1654e985ebfe5cd37479d41a06c.tar.gz
BUG: Fix signed char assumption in einsum label parsing
-rw-r--r--numpy/core/src/multiarray/einsum.c.src27
1 files changed, 22 insertions, 5 deletions
diff --git a/numpy/core/src/multiarray/einsum.c.src b/numpy/core/src/multiarray/einsum.c.src
index 98a26c322..9898d00fa 100644
--- a/numpy/core/src/multiarray/einsum.c.src
+++ b/numpy/core/src/multiarray/einsum.c.src
@@ -1917,6 +1917,10 @@ parse_operand_subscripts(char *subscripts, int length,
/*
* Find any labels duplicated for this operand, and turn them
* into negative offets to the axis to merge with.
+ *
+ * In C, the char type may be signed or unsigned, but with
+ * twos complement arithmetic the char is ok either way here, and
+ * later where it matters the char is cast to a signed char.
*/
for (idim = 0; idim < ndim-1; ++idim) {
char *next;
@@ -1928,7 +1932,7 @@ parse_operand_subscripts(char *subscripts, int length,
ndim-idim-1);
while (next != NULL) {
/* The offset from next to out_labels[idim] (negative) */
- *next = (out_labels+idim)-next;
+ *next = (char)((out_labels+idim)-next);
/* Search for the next matching label */
next = (char *)memchr(next+1, label,
out_labels+ndim-1-next);
@@ -2128,7 +2132,11 @@ get_single_op_view(PyArrayObject *op, int iop, char *labels,
/* Match the labels in the operand with the output labels */
for (idim = 0; idim < ndim; ++idim) {
- label = labels[idim];
+ /*
+ * The char type may be either signed or unsigned, we
+ * need it to be signed here.
+ */
+ label = (signed char)labels[idim];
/* If this label says to merge axes, get the actual label */
if (label < 0) {
label = labels[idim+label];
@@ -2226,7 +2234,11 @@ get_combined_dims_view(PyArrayObject *op, int iop, char *labels)
/* Copy the dimensions and strides, except when collapsing */
icombine = 0;
for (idim = 0; idim < ndim; ++idim) {
- label = labels[idim];
+ /*
+ * The char type may be either signed or unsigned, we
+ * need it to be signed here.
+ */
+ label = (signed char)labels[idim];
/* If this label says to merge axes, get the actual label */
if (label < 0) {
combineoffset = label;
@@ -2877,10 +2889,15 @@ PyArray_EinsteinSum(char *subscripts, npy_intp nop,
}
}
- /* Check whether any dimensions need to be combined */
+ /*
+ * Check whether any dimensions need to be combined
+ *
+ * The char type may be either signed or unsigned, we
+ * need it to be signed here.
+ */
combine = 0;
for (idim = 0; idim < ndim; ++idim) {
- if (labels[idim] < 0) {
+ if ((signed char)labels[idim] < 0) {
combine = 1;
}
}