isl_basic_set_opt: avoid invalid access on error path
[platform/upstream/isl.git] / isl_map_subtract.c
index d43cf3d..2c958c7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2008-2009 Katholieke Universiteit Leuven
  *
- * 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
 #include "isl_tab.h"
 #include <isl_point_private.h>
 
+/* Expand the constraint "c" into "v".  The initial "dim" dimensions
+ * are the same, but "v" may have more divs than "c" and the divs of "c"
+ * may appear in different positions in "v".
+ * The number of divs in "c" is given by "n_div" and the mapping
+ * of divs in "c" to divs in "v" is given by "div_map".
+ *
+ * Although it shouldn't happen in practice, it is theoretically
+ * possible that two or more divs in "c" are mapped to the same div in "v".
+ * These divs are then necessarily the same, so we simply add their
+ * coefficients.
+ */
 static void expand_constraint(isl_vec *v, unsigned dim,
        isl_int *c, int *div_map, unsigned n_div)
 {
@@ -22,8 +33,10 @@ static void expand_constraint(isl_vec *v, unsigned dim,
        isl_seq_cpy(v->el, c, 1 + dim);
        isl_seq_clr(v->el + 1 + dim, v->size - (1 + dim));
 
-       for (i = 0; i < n_div; ++i)
-               isl_int_set(v->el[1 + dim + div_map[i]], c[1 + dim + i]);
+       for (i = 0; i < n_div; ++i) {
+               int pos = 1 + dim + div_map[i];
+               isl_int_add(v->el[pos], v->el[pos], c[1 + dim + i]);
+       }
 }
 
 /* Add all constraints of bmap to tab.  The equalities of bmap
@@ -313,6 +326,8 @@ static int basic_map_collect_diff(__isl_take isl_basic_map *bmap,
        map = isl_map_order_divs(map);
 
        tab = isl_tab_from_basic_map(bmap, 1);
+       if (!tab)
+               goto error;
 
        modified = 0;
        level = 0;
@@ -762,6 +777,8 @@ static int map_is_singleton_subset(__isl_keep isl_map *map1,
 static int map_is_subset(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
 {
        int is_subset = 0;
+       int empty;
+       int rat1, rat2;
 
        if (!map1 || !map2)
                return -1;
@@ -769,10 +786,23 @@ static int map_is_subset(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
        if (!isl_map_has_equal_space(map1, map2))
                return 0;
 
-       if (isl_map_is_empty(map1))
+       empty = isl_map_is_empty(map1);
+       if (empty < 0)
+               return -1;
+       if (empty)
                return 1;
 
-       if (isl_map_is_empty(map2))
+       empty = isl_map_is_empty(map2);
+       if (empty < 0)
+               return -1;
+       if (empty)
+               return 0;
+
+       rat1 = isl_map_has_rational(map1);
+       rat2 = isl_map_has_rational(map2);
+       if (rat1 < 0 || rat2 < 0)
+               return -1;
+       if (rat1 && !rat2)
                return 0;
 
        if (isl_map_plain_is_universe(map2))