isl_tab.c: push_union: handle NULL input
[platform/upstream/isl.git] / isl_tab_pip.c
index 74564db..9663979 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright 2008-2009 Katholieke Universiteit Leuven
  * Copyright 2010      INRIA Saclay
  *
- * Use of this software is governed by the GNU LGPLv2.1 license
+ * Use of this software is governed by the MIT license
  *
  * Written by Sven Verdoolaege, K.U.Leuven, Departement
  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
@@ -102,6 +102,8 @@ struct isl_context_op {
        void *(*save)(struct isl_context *context);
        /* restore saved context */
        void (*restore)(struct isl_context *context, void *);
+       /* discard saved context */
+       void (*discard)(void *);
        /* invalidate context */
        void (*invalidate)(struct isl_context *context);
        /* free context */
@@ -201,6 +203,7 @@ static void sol_push_sol(struct isl_sol *sol,
        return;
 error:
        isl_basic_set_free(dom);
+       isl_mat_free(M);
        sol->error = 1;
 }
 
@@ -306,6 +309,8 @@ static void sol_pop(struct isl_sol *sol)
                        struct isl_basic_set *bset;
 
                        bset = sol_domain(sol);
+                       if (!bset)
+                               goto error;
 
                        isl_basic_set_free(partial->next->dom);
                        partial->next->dom = bset;
@@ -318,6 +323,9 @@ static void sol_pop(struct isl_sol *sol)
                }
        } else
                sol_pop_one(sol);
+
+       if (0)
+error:         sol->error = 1;
 }
 
 static void sol_dec_level(struct isl_sol *sol)
@@ -789,8 +797,8 @@ static struct isl_vec *get_row_parameter_div(struct isl_tab *tab, int row)
 
        isl_int_set(div->el[0], tab->mat->row[row][0]);
        get_row_parameter_line(tab, row, div->el + 1);
-       normalize_div(div);
        isl_seq_neg(div->el + 1, div->el + 1, div->size - 1);
+       normalize_div(div);
        isl_seq_fdiv_r(div->el + 1, div->el + 1, div->el[0], div->size - 1);
 
        return div;
@@ -1957,6 +1965,7 @@ static int add_parametric_cut(struct isl_tab *tab, int row,
 
        n = tab->n_div;
        d = context->op->get_div(context, tab, div);
+       isl_vec_free(div);
        if (d < 0)
                return -1;
 
@@ -2022,8 +2031,6 @@ static int add_parametric_cut(struct isl_tab *tab, int row,
        if (tab->row_sign)
                tab->row_sign[tab->con[r].index] = isl_tab_row_neg;
 
-       isl_vec_free(div);
-
        row = tab->con[r].index;
 
        if (d >= n && context->op->detect_equalities(context, tab) < 0)
@@ -2418,6 +2425,10 @@ static void context_lex_restore(struct isl_context *context, void *save)
        }
 }
 
+static void context_lex_discard(void *save)
+{
+}
+
 static int context_lex_is_ok(struct isl_context *context)
 {
        struct isl_context_lex *clex = (struct isl_context_lex *)context;
@@ -2537,6 +2548,7 @@ struct isl_context_op isl_context_lex_op = {
        context_lex_is_ok,
        context_lex_save,
        context_lex_restore,
+       context_lex_discard,
        context_lex_invalidate,
        context_lex_free,
 };
@@ -3225,6 +3237,12 @@ error:
        cgbr->tab = NULL;
 }
 
+static void context_gbr_discard(void *save)
+{
+       struct isl_gbr_tab_undo *snap = (struct isl_gbr_tab_undo *)save;
+       free(snap);
+}
+
 static int context_gbr_is_ok(struct isl_context *context)
 {
        struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
@@ -3263,6 +3281,7 @@ struct isl_context_op isl_context_gbr_op = {
        context_gbr_is_ok,
        context_gbr_save,
        context_gbr_restore,
+       context_gbr_discard,
        context_gbr_invalidate,
        context_gbr_free,
 };
@@ -3561,6 +3580,8 @@ static void find_in_pos(struct isl_sol *sol, struct isl_tab *tab, isl_int *ineq)
 
        if (!sol->error)
                sol->context->op->restore(sol->context, saved);
+       else
+               sol->context->op->discard(saved);
        return;
 error:
        sol->error = 1;
@@ -4521,7 +4542,7 @@ static union isl_lex_res basic_map_partial_lexopt_symm(
        bmap = isl_basic_map_finalize(bmap);
 
        n_div = isl_basic_set_dim(dom, isl_dim_div);
-       dom = isl_basic_set_add(dom, isl_dim_set, 1);
+       dom = isl_basic_set_add_dims(dom, isl_dim_set, 1);
        dom = isl_basic_set_extend_constraints(dom, 0, n);
        for (i = 0; i < n; ++i) {
                k = isl_basic_set_alloc_inequality(dom);
@@ -4763,11 +4784,13 @@ int isl_basic_map_foreach_lexopt(__isl_keep isl_basic_map *bmap, int max,
        struct isl_sol_for *sol_for = NULL;
 
        bmap = isl_basic_map_copy(bmap);
+       bmap = isl_basic_map_detect_equalities(bmap);
        if (!bmap)
                return -1;
 
-       bmap = isl_basic_map_detect_equalities(bmap);
        sol_for = sol_for_init(bmap, max, fn, user);
+       if (!sol_for)
+               goto error;
 
        if (isl_basic_map_plain_is_empty(bmap))
                /* nothing */;