isl_basic_set_opt: avoid invalid access on error path
[platform/upstream/isl.git] / isl_map.c
index 5821130..c4636c1 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -1145,6 +1145,13 @@ int isl_basic_set_drop_equality(struct isl_basic_set *bset, unsigned pos)
        return isl_basic_map_drop_equality((struct isl_basic_map *)bset, pos);
 }
 
+/* Turn inequality "pos" of "bmap" into an equality.
+ *
+ * In particular, we move the inequality in front of the equalities
+ * and move the last inequality in the position of the moved inequality.
+ * Note that isl_tab_make_equalities_explicit depends on this particular
+ * change in the ordering of the constraints.
+ */
 void isl_basic_map_inequality_to_equality(
                struct isl_basic_map *bmap, unsigned pos)
 {
@@ -3045,6 +3052,7 @@ __isl_give isl_basic_map *isl_basic_map_insert_dims(
                res = isl_basic_map_set_rational(res);
        if (isl_basic_map_plain_is_empty(bmap)) {
                isl_basic_map_free(bmap);
+               free(dim_map);
                return isl_basic_map_set_to_empty(res);
        }
        res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
@@ -3220,6 +3228,8 @@ __isl_give isl_basic_map *isl_basic_map_move_dims(
        res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
                        bmap->n_div, bmap->n_eq, bmap->n_ineq);
        bmap = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
+       if (!bmap)
+               goto error;
 
        bmap->dim = isl_space_move_dims(bmap->dim, dst_type, dst_pos,
                                        src_type, src_pos, n);
@@ -6331,7 +6341,11 @@ static struct isl_set *parameter_compute_divs(struct isl_basic_set *bset)
        if (bset->n_eq == 0)
                return isl_basic_set_lexmin(bset);
 
-       isl_basic_set_gauss(bset, NULL);
+       bset = isl_basic_set_gauss(bset, NULL);
+       if (!bset)
+               return NULL;
+       if (isl_basic_set_plain_is_empty(bset))
+               return isl_set_from_basic_set(bset);
 
        nparam = isl_basic_set_dim(bset, isl_dim_param);
        n_div = isl_basic_set_dim(bset, isl_dim_div);
@@ -6827,8 +6841,10 @@ struct isl_basic_set *isl_basic_map_deltas(struct isl_basic_map *bmap)
        for (i = 0; i < dim; ++i) {
                int j = isl_basic_map_alloc_equality(
                                            (struct isl_basic_map *)bset);
-               if (j < 0)
-                       goto error;
+               if (j < 0) {
+                       bset = isl_basic_set_free(bset);
+                       break;
+               }
                isl_seq_clr(bset->eq[j], 1 + isl_basic_set_total_dim(bset));
                isl_int_set_si(bset->eq[j][1+nparam+i], 1);
                isl_int_set_si(bset->eq[j][1+nparam+dim+i], 1);
@@ -7421,7 +7437,7 @@ int isl_basic_map_is_empty(struct isl_basic_map *bmap)
        if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) {
                struct isl_basic_map *copy = isl_basic_map_copy(bmap);
                copy = isl_basic_map_remove_redundancies(copy);
-               empty = ISL_F_ISSET(copy, ISL_BASIC_MAP_EMPTY);
+               empty = isl_basic_map_plain_is_empty(copy);
                isl_basic_map_free(copy);
                return empty;
        }
@@ -7577,11 +7593,11 @@ __isl_give isl_basic_set *isl_basic_set_expand_divs(
                isl_die(isl_mat_get_ctx(div), isl_error_invalid,
                        "not an expansion", goto error);
 
+       n_div = bset->n_div;
        bset = isl_basic_map_extend_space(bset, isl_space_copy(bset->dim),
-                                       div->n_row - bset->n_div, 0,
-                                       2 * (div->n_row - bset->n_div));
+                                           div->n_row - n_div, 0,
+                                           2 * (div->n_row - n_div));
 
-       n_div = bset->n_div;
        for (i = n_div; i < div->n_row; ++i)
                if (isl_basic_set_alloc_div(bset) < 0)
                        goto error;
@@ -7838,19 +7854,20 @@ static enum isl_lp_result basic_set_maximal_difference_at(
        total = isl_basic_map_total_dim(bmap1);
        ctx = bmap1->ctx;
        obj = isl_vec_alloc(ctx, 1 + total);
+       if (!obj)
+               goto error2;
        isl_seq_clr(obj->block.data, 1 + total);
        isl_int_set_si(obj->block.data[1+nparam+pos], 1);
        isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1);
-       if (!obj)
-               goto error;
        res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
                                        opt, NULL, NULL);
        isl_basic_map_free(bmap1);
        isl_vec_free(obj);
        return res;
 error:
-       isl_basic_map_free(bmap1);
        isl_basic_map_free(bmap2);
+error2:
+       isl_basic_map_free(bmap1);
        return isl_lp_error;
 }
 
@@ -8188,13 +8205,13 @@ static int qsort_constraint_cmp(const void *p1, const void *p2)
        int l1, l2;
        unsigned size = isl_min(c1->size, c2->size);
 
-       l1 = isl_seq_last_non_zero(c1->c, size);
-       l2 = isl_seq_last_non_zero(c2->c, size);
+       l1 = isl_seq_last_non_zero(c1->c + 1, size);
+       l2 = isl_seq_last_non_zero(c2->c + 1, size);
 
        if (l1 != l2)
                return l1 - l2;
 
-       return isl_seq_cmp(c1->c, c2->c, size);
+       return isl_seq_cmp(c1->c + 1, c2->c + 1, size);
 }
 
 static struct isl_basic_map *isl_basic_map_sort_constraints(
@@ -8239,7 +8256,8 @@ struct isl_basic_map *isl_basic_map_normalize(struct isl_basic_map *bmap)
                return bmap;
        bmap = isl_basic_map_remove_redundancies(bmap);
        bmap = isl_basic_map_sort_constraints(bmap);
-       ISL_F_SET(bmap, ISL_BASIC_MAP_NORMALIZED);
+       if (bmap)
+               ISL_F_SET(bmap, ISL_BASIC_MAP_NORMALIZED);
        return bmap;
 }
 
@@ -10383,6 +10401,9 @@ __isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap)
        if (!isl_basic_map_can_curry(bmap))
                isl_die(bmap->ctx, isl_error_invalid,
                        "basic map cannot be curried", goto error);
+       bmap = isl_basic_map_cow(bmap);
+       if (!bmap)
+               return NULL;
        bmap->dim = isl_space_curry(bmap->dim);
        if (!bmap->dim)
                goto error;
@@ -10461,6 +10482,9 @@ __isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap)
                isl_die(bmap->ctx, isl_error_invalid,
                        "basic map cannot be uncurried",
                        return isl_basic_map_free(bmap));
+       bmap = isl_basic_map_cow(bmap);
+       if (!bmap)
+               return NULL;
        bmap->dim = isl_space_uncurry(bmap->dim);
        if (!bmap->dim)
                return isl_basic_map_free(bmap);