isl_tab_pip.c: sol_map_add: fix double free on error path
[platform/upstream/isl.git] / isl_tab_pip.c
index 62b4cd1..78f71f2 100644 (file)
@@ -16,6 +16,8 @@
 #include "isl_tab.h"
 #include "isl_sample.h"
 #include <isl_mat_private.h>
+#include <isl_aff_private.h>
+#include <isl_config.h>
 
 /*
  * The implementation of parametric integer linear programming in this file
@@ -420,7 +422,7 @@ static void sol_add(struct isl_sol *sol, struct isl_tab *tab)
        struct isl_basic_set *bset = NULL;
        struct isl_mat *mat = NULL;
        unsigned off;
-       int row, i;
+       int row;
        isl_int m;
 
        if (sol->error || !tab)
@@ -585,7 +587,6 @@ static void sol_map_add(struct isl_sol_map *sol,
 {
        int i;
        struct isl_basic_map *bmap = NULL;
-       isl_basic_set *context_bset;
        unsigned n_eq;
        unsigned n_ineq;
        unsigned nparam;
@@ -649,10 +650,10 @@ static void sol_map_add(struct isl_sol_map *sol,
        bmap = isl_basic_map_finalize(bmap);
        sol->map = isl_map_grow(sol->map, 1);
        sol->map = isl_map_add_basic_map(sol->map, bmap);
-       if (!sol->map)
-               goto error;
        isl_basic_set_free(dom);
        isl_mat_free(M);
+       if (!sol->map)
+               sol->sol.error = 1;
        return;
 error:
        isl_basic_set_free(dom);
@@ -1117,6 +1118,7 @@ static int first_neg(struct isl_tab *tab)
  * is satisfied.  This function is not called from the current code
  * but is useful during debugging.
  */
+static void check_lexpos(struct isl_tab *tab) __attribute__ ((unused));
 static void check_lexpos(struct isl_tab *tab)
 {
        unsigned off = 2 + tab->M;
@@ -1728,7 +1730,6 @@ static int sample_is_finite(struct isl_tab *tab)
 static struct isl_tab *check_integer_feasible(struct isl_tab *tab)
 {
        struct isl_tab_undo *snap;
-       int feasible;
 
        if (!tab)
                return NULL;
@@ -2182,17 +2183,6 @@ static struct isl_tab *context_lex_peek_tab(struct isl_context *context)
        return clex->tab;
 }
 
-static void context_lex_extend(struct isl_context *context, int n)
-{
-       struct isl_context_lex *clex = (struct isl_context_lex *)context;
-       if (!clex->tab)
-               return;
-       if (isl_tab_extend_cons(clex->tab, n) >= 0)
-               return;
-       isl_tab_free(clex->tab);
-       clex->tab = NULL;
-}
-
 static void context_lex_add_eq(struct isl_context *context, isl_int *eq,
                int check, int update)
 {
@@ -2778,8 +2768,6 @@ error:
 
 static struct isl_tab *add_gbr_eq(struct isl_tab *tab, isl_int *eq)
 {
-       int r;
-
        if (!tab)
                return NULL;
 
@@ -2966,7 +2954,6 @@ static int last_non_zero_var_col(struct isl_tab *tab, isl_int *p)
 {
        int i;
        int col;
-       unsigned dim = tab->n_var - tab->n_param - tab->n_div;
 
        if (tab->n_var == 0)
                return -1;
@@ -3058,8 +3045,6 @@ static int context_gbr_detect_equalities(struct isl_context *context,
 {
        struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
        struct isl_ctx *ctx;
-       int i;
-       enum isl_lp_result res;
        unsigned n_ineq;
 
        ctx = cgbr->tab->mat->ctx;
@@ -4523,7 +4508,7 @@ error:
 struct isl_sol_for {
        struct isl_sol  sol;
        int             (*fn)(__isl_take isl_basic_set *dom,
-                               __isl_take isl_mat *map, void *user);
+                               __isl_take isl_aff_list *list, void *user);
        void            *user;
 };
 
@@ -4545,23 +4530,39 @@ static void sol_for_free_wrap(struct isl_sol *sol)
  *
  * Instead of constructing a basic map, this function calls a user
  * defined function with the current context as a basic set and
- * an affine matrix representing the relation between the input and output.
- * The number of rows in this matrix is equal to one plus the number
- * of output variables.  The number of columns is equal to one plus
- * the total dimension of the context, i.e., the number of parameters,
- * input variables and divs.  Since some of the columns in the matrix
- * may refer to the divs, the basic set is not simplified.
- * (Simplification may reorder or remove divs.)
+ * a list of affine expressions representing the relation between
+ * the input and output.  The space over which the affine expressions
+ * are defined is the same as that of the domain.  The number of
+ * affine expressions in the list is equal to the number of output variables.
  */
 static void sol_for_add(struct isl_sol_for *sol,
        struct isl_basic_set *dom, struct isl_mat *M)
 {
+       int i;
+       isl_ctx *ctx;
+       isl_local_space *ls;
+       isl_aff *aff;
+       isl_aff_list *list;
+
        if (sol->sol.error || !dom || !M)
                goto error;
 
+       ctx = isl_basic_set_get_ctx(dom);
+       ls = isl_basic_set_get_local_space(dom);
+       list = isl_aff_list_alloc(ctx, M->n_row - 1);
+       for (i = 1; i < M->n_row; ++i) {
+               aff = isl_aff_alloc(isl_local_space_copy(ls));
+               if (aff) {
+                       isl_int_set_si(aff->v->el[0], 1);
+                       isl_seq_cpy(aff->v->el + 1, M->row[i], M->n_col);
+               }
+               list = isl_aff_list_add(list, aff);
+       }
+       isl_local_space_free(ls);
+
        dom = isl_basic_set_finalize(dom);
 
-       if (sol->fn(isl_basic_set_copy(dom), isl_mat_copy(M), sol->user) < 0)
+       if (sol->fn(isl_basic_set_copy(dom), list, sol->user) < 0)
                goto error;
 
        isl_basic_set_free(dom);
@@ -4580,7 +4581,7 @@ static void sol_for_add_wrap(struct isl_sol *sol,
 }
 
 static struct isl_sol_for *sol_for_init(struct isl_basic_map *bmap, int max,
-       int (*fn)(__isl_take isl_basic_set *dom, __isl_take isl_mat *map,
+       int (*fn)(__isl_take isl_basic_set *dom, __isl_take isl_aff_list *list,
                  void *user),
        void *user)
 {
@@ -4625,7 +4626,7 @@ static void sol_for_find_solutions(struct isl_sol_for *sol_for,
 }
 
 int isl_basic_map_foreach_lexopt(__isl_keep isl_basic_map *bmap, int max,
-       int (*fn)(__isl_take isl_basic_set *dom, __isl_take isl_mat *map,
+       int (*fn)(__isl_take isl_basic_set *dom, __isl_take isl_aff_list *list,
                  void *user),
        void *user)
 {
@@ -4661,7 +4662,7 @@ error:
 }
 
 int isl_basic_map_foreach_lexmin(__isl_keep isl_basic_map *bmap,
-       int (*fn)(__isl_take isl_basic_set *dom, __isl_take isl_mat *map,
+       int (*fn)(__isl_take isl_basic_set *dom, __isl_take isl_aff_list *list,
                  void *user),
        void *user)
 {
@@ -4669,13 +4670,21 @@ int isl_basic_map_foreach_lexmin(__isl_keep isl_basic_map *bmap,
 }
 
 int isl_basic_map_foreach_lexmax(__isl_keep isl_basic_map *bmap,
-       int (*fn)(__isl_take isl_basic_set *dom, __isl_take isl_mat *map,
+       int (*fn)(__isl_take isl_basic_set *dom, __isl_take isl_aff_list *list,
                  void *user),
        void *user)
 {
        return isl_basic_map_foreach_lexopt(bmap, 1, fn, user);
 }
 
+int isl_basic_set_foreach_lexmax(__isl_keep isl_basic_set *bset,
+       int (*fn)(__isl_take isl_basic_set *dom, __isl_take isl_aff_list *list,
+                 void *user),
+       void *user)
+{
+       return isl_basic_map_foreach_lexmax(bset, fn, user);
+}
+
 /* Check if the given sequence of len variables starting at pos
  * represents a trivial (i.e., zero) solution.
  * The variables are assumed to be non-negative and to come in pairs,
@@ -4842,7 +4851,6 @@ __isl_give isl_vec *isl_tab_basic_set_non_trivial_lexmin(
        int (*conflict)(int con, void *user), void *user)
 {
        int i, j;
-       int need_update = 0;
        int r;
        isl_ctx *ctx = isl_basic_set_get_ctx(bset);
        isl_vec *v = NULL;