isl_basic_set_opt: avoid invalid access on error path
[platform/upstream/isl.git] / isl_obj.c
1 /*
2  * Copyright 2010      INRIA Saclay
3  *
4  * Use of this software is governed by the MIT license
5  *
6  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
8  * 91893 Orsay, France 
9  */
10
11 #include <isl/set.h>
12 #include <isl/map.h>
13 #include <isl/polynomial.h>
14 #include <isl/obj.h>
15
16 struct isl_int_obj {
17         int ref;
18         isl_ctx *ctx;
19         isl_int v;
20 };
21
22 __isl_give isl_int_obj *isl_int_obj_alloc(isl_ctx *ctx, isl_int v)
23 {
24         isl_int_obj *i;
25
26         i = isl_alloc_type(ctx, isl_int_obj);
27         if (!i)
28                 return NULL;
29         
30         i->ctx = ctx;
31         isl_ctx_ref(ctx);
32         i->ref = 1;
33         isl_int_init(i->v);
34         isl_int_set(i->v, v);
35
36         return i;
37 }
38
39 __isl_give isl_int_obj *isl_int_obj_copy(__isl_keep isl_int_obj *i)
40 {
41         if (!i)
42                 return NULL;
43
44         i->ref++;
45         return i;
46 }
47
48 __isl_give isl_int_obj *isl_int_obj_dup(__isl_keep isl_int_obj *i)
49 {
50         if (!i)
51                 return NULL;
52
53         return isl_int_obj_alloc(i->ctx, i->v);
54 }
55
56 __isl_give isl_int_obj *isl_int_obj_cow(__isl_take isl_int_obj *i)
57 {
58         if (!i)
59                 return NULL;
60
61         if (i->ref == 1)
62                 return i;
63         i->ref--;
64         return isl_int_obj_dup(i);
65 }
66
67 void isl_int_obj_free(__isl_take isl_int_obj *i)
68 {
69         if (!i)
70                 return;
71
72         if (--i->ref > 0)
73                 return;
74
75         isl_ctx_deref(i->ctx);
76         isl_int_clear(i->v);
77         free(i);
78 }
79
80 __isl_give isl_int_obj *isl_int_obj_add(__isl_take isl_int_obj *i1,
81         __isl_take isl_int_obj *i2)
82 {
83         i1 = isl_int_obj_cow(i1);
84         if (!i1 || !i2)
85                 goto error;
86         
87         isl_int_add(i1->v, i1->v, i2->v);
88
89         isl_int_obj_free(i2);
90         return i1;
91 error:
92         isl_int_obj_free(i1);
93         isl_int_obj_free(i2);
94         return NULL;
95 }
96
97 __isl_give isl_int_obj *isl_int_obj_sub(__isl_take isl_int_obj *i1,
98         __isl_take isl_int_obj *i2)
99 {
100         i1 = isl_int_obj_cow(i1);
101         if (!i1 || !i2)
102                 goto error;
103         
104         isl_int_sub(i1->v, i1->v, i2->v);
105
106         isl_int_obj_free(i2);
107         return i1;
108 error:
109         isl_int_obj_free(i1);
110         isl_int_obj_free(i2);
111         return NULL;
112 }
113
114 __isl_give isl_int_obj *isl_int_obj_mul(__isl_take isl_int_obj *i1,
115         __isl_take isl_int_obj *i2)
116 {
117         i1 = isl_int_obj_cow(i1);
118         if (!i1 || !i2)
119                 goto error;
120         
121         isl_int_mul(i1->v, i1->v, i2->v);
122
123         isl_int_obj_free(i2);
124         return i1;
125 error:
126         isl_int_obj_free(i1);
127         isl_int_obj_free(i2);
128         return NULL;
129 }
130
131 void isl_int_obj_get_int(__isl_keep isl_int_obj *i, isl_int *v)
132 {
133         if (!i)
134                 return;
135         isl_int_set(*v, i->v);
136 }
137
138 static void *isl_obj_int_copy(void *v)
139 {
140         return isl_int_obj_copy((isl_int_obj *)v);
141 }
142
143 static void isl_obj_int_free(void *v)
144 {
145         isl_int_obj_free((isl_int_obj *)v);
146 }
147
148 static __isl_give isl_printer *isl_obj_int_print(__isl_take isl_printer *p,
149         void *v)
150 {
151         isl_int_obj *i = v;
152         return isl_printer_print_isl_int(p, i->v);
153 }
154
155 static void *isl_obj_int_add(void *v1, void *v2)
156 {
157         return isl_int_obj_add((isl_int_obj *)v1, (isl_int_obj *)v2);
158 }
159
160 struct isl_obj_vtable isl_obj_int_vtable = {
161         isl_obj_int_copy,
162         isl_obj_int_add,
163         isl_obj_int_print,
164         isl_obj_int_free
165 };
166
167 static void *isl_obj_map_copy(void *v)
168 {
169         return isl_map_copy((struct isl_map *)v);
170 }
171
172 static void isl_obj_map_free(void *v)
173 {
174         isl_map_free((struct isl_map *)v);
175 }
176
177 static __isl_give isl_printer *isl_obj_map_print(__isl_take isl_printer *p,
178         void *v)
179 {
180         return isl_printer_print_map(p, (struct isl_map *)v);
181 }
182
183 static void *isl_obj_map_add(void *v1, void *v2)
184 {
185         return isl_map_union((struct isl_map *)v1, (struct isl_map *)v2);
186 }
187
188 struct isl_obj_vtable isl_obj_map_vtable = {
189         isl_obj_map_copy,
190         isl_obj_map_add,
191         isl_obj_map_print,
192         isl_obj_map_free
193 };
194
195 static void *isl_obj_union_map_copy(void *v)
196 {
197         return isl_union_map_copy((isl_union_map *)v);
198 }
199
200 static void isl_obj_union_map_free(void *v)
201 {
202         isl_union_map_free((isl_union_map *)v);
203 }
204
205 static __isl_give isl_printer *isl_obj_union_map_print(__isl_take isl_printer *p,
206         void *v)
207 {
208         return isl_printer_print_union_map(p, (isl_union_map *)v);
209 }
210
211 static void *isl_obj_union_map_add(void *v1, void *v2)
212 {
213         return isl_union_map_union((isl_union_map *)v1, (isl_union_map *)v2);
214 }
215
216 struct isl_obj_vtable isl_obj_union_map_vtable = {
217         isl_obj_union_map_copy,
218         isl_obj_union_map_add,
219         isl_obj_union_map_print,
220         isl_obj_union_map_free
221 };
222
223 static void *isl_obj_set_copy(void *v)
224 {
225         return isl_set_copy((struct isl_set *)v);
226 }
227
228 static void isl_obj_set_free(void *v)
229 {
230         isl_set_free((struct isl_set *)v);
231 }
232
233 static __isl_give isl_printer *isl_obj_set_print(__isl_take isl_printer *p,
234         void *v)
235 {
236         return isl_printer_print_set(p, (struct isl_set *)v);
237 }
238
239 static void *isl_obj_set_add(void *v1, void *v2)
240 {
241         return isl_set_union((struct isl_set *)v1, (struct isl_set *)v2);
242 }
243
244 struct isl_obj_vtable isl_obj_set_vtable = {
245         isl_obj_set_copy,
246         isl_obj_set_add,
247         isl_obj_set_print,
248         isl_obj_set_free
249 };
250
251 static void *isl_obj_union_set_copy(void *v)
252 {
253         return isl_union_set_copy((isl_union_set *)v);
254 }
255
256 static void isl_obj_union_set_free(void *v)
257 {
258         isl_union_set_free((isl_union_set *)v);
259 }
260
261 static __isl_give isl_printer *isl_obj_union_set_print(__isl_take isl_printer *p,
262         void *v)
263 {
264         return isl_printer_print_union_set(p, (isl_union_set *)v);
265 }
266
267 static void *isl_obj_union_set_add(void *v1, void *v2)
268 {
269         return isl_union_set_union((isl_union_set *)v1, (isl_union_set *)v2);
270 }
271
272 struct isl_obj_vtable isl_obj_union_set_vtable = {
273         isl_obj_union_set_copy,
274         isl_obj_union_set_add,
275         isl_obj_union_set_print,
276         isl_obj_union_set_free
277 };
278
279 static void *isl_obj_none_copy(void *v)
280 {
281         return v;
282 }
283
284 static void isl_obj_none_free(void *v)
285 {
286 }
287
288 static __isl_give isl_printer *isl_obj_none_print(__isl_take isl_printer *p,
289         void *v)
290 {
291         return p;
292 }
293
294 static void *isl_obj_none_add(void *v1, void *v2)
295 {
296         return NULL;
297 }
298
299 struct isl_obj_vtable isl_obj_none_vtable = {
300         isl_obj_none_copy,
301         isl_obj_none_add,
302         isl_obj_none_print,
303         isl_obj_none_free
304 };
305
306 static void *isl_obj_pw_qp_copy(void *v)
307 {
308         return isl_pw_qpolynomial_copy((struct isl_pw_qpolynomial *)v);
309 }
310
311 static void isl_obj_pw_qp_free(void *v)
312 {
313         isl_pw_qpolynomial_free((struct isl_pw_qpolynomial *)v);
314 }
315
316 static __isl_give isl_printer *isl_obj_pw_qp_print(__isl_take isl_printer *p,
317         void *v)
318 {
319         return isl_printer_print_pw_qpolynomial(p,
320                                                 (struct isl_pw_qpolynomial *)v);
321 }
322
323 static void *isl_obj_pw_qp_add(void *v1, void *v2)
324 {
325         return isl_pw_qpolynomial_add((struct isl_pw_qpolynomial *)v1,
326                                         (struct isl_pw_qpolynomial *)v2);
327 }
328
329 struct isl_obj_vtable isl_obj_pw_qpolynomial_vtable = {
330         isl_obj_pw_qp_copy,
331         isl_obj_pw_qp_add,
332         isl_obj_pw_qp_print,
333         isl_obj_pw_qp_free
334 };
335
336 static void *isl_obj_union_pw_qp_copy(void *v)
337 {
338         return isl_union_pw_qpolynomial_copy((struct isl_union_pw_qpolynomial *)v);
339 }
340
341 static void isl_obj_union_pw_qp_free(void *v)
342 {
343         isl_union_pw_qpolynomial_free((struct isl_union_pw_qpolynomial *)v);
344 }
345
346 static __isl_give isl_printer *isl_obj_union_pw_qp_print(
347         __isl_take isl_printer *p, void *v)
348 {
349         return isl_printer_print_union_pw_qpolynomial(p,
350                                         (struct isl_union_pw_qpolynomial *)v);
351 }
352
353 static void *isl_obj_union_pw_qp_add(void *v1, void *v2)
354 {
355         return isl_union_pw_qpolynomial_add(
356                                         (struct isl_union_pw_qpolynomial *)v1,
357                                         (struct isl_union_pw_qpolynomial *)v2);
358 }
359
360 struct isl_obj_vtable isl_obj_union_pw_qpolynomial_vtable = {
361         isl_obj_union_pw_qp_copy,
362         isl_obj_union_pw_qp_add,
363         isl_obj_union_pw_qp_print,
364         isl_obj_union_pw_qp_free
365 };
366
367 static void *isl_obj_pw_qpf_copy(void *v)
368 {
369         return isl_pw_qpolynomial_fold_copy((struct isl_pw_qpolynomial_fold *)v);
370 }
371
372 static void isl_obj_pw_qpf_free(void *v)
373 {
374         isl_pw_qpolynomial_fold_free((struct isl_pw_qpolynomial_fold *)v);
375 }
376
377 static __isl_give isl_printer *isl_obj_pw_qpf_print(__isl_take isl_printer *p,
378         void *v)
379 {
380         return isl_printer_print_pw_qpolynomial_fold(p,
381                                         (struct isl_pw_qpolynomial_fold *)v);
382 }
383
384 static void *isl_obj_pw_qpf_add(void *v1, void *v2)
385 {
386         return isl_pw_qpolynomial_fold_fold((struct isl_pw_qpolynomial_fold *)v1,
387                                             (struct isl_pw_qpolynomial_fold *)v2);
388 }
389
390 struct isl_obj_vtable isl_obj_pw_qpolynomial_fold_vtable = {
391         isl_obj_pw_qpf_copy,
392         isl_obj_pw_qpf_add,
393         isl_obj_pw_qpf_print,
394         isl_obj_pw_qpf_free
395 };
396
397 static void *isl_obj_union_pw_qpf_copy(void *v)
398 {
399         return isl_union_pw_qpolynomial_fold_copy((struct isl_union_pw_qpolynomial_fold *)v);
400 }
401
402 static void isl_obj_union_pw_qpf_free(void *v)
403 {
404         isl_union_pw_qpolynomial_fold_free((struct isl_union_pw_qpolynomial_fold *)v);
405 }
406
407 static __isl_give isl_printer *isl_obj_union_pw_qpf_print(
408         __isl_take isl_printer *p, void *v)
409 {
410         return isl_printer_print_union_pw_qpolynomial_fold(p,
411                                     (struct isl_union_pw_qpolynomial_fold *)v);
412 }
413
414 static void *isl_obj_union_pw_qpf_add(void *v1, void *v2)
415 {
416         return isl_union_pw_qpolynomial_fold_fold(
417                                     (struct isl_union_pw_qpolynomial_fold *)v1,
418                                     (struct isl_union_pw_qpolynomial_fold *)v2);
419 }
420
421 struct isl_obj_vtable isl_obj_union_pw_qpolynomial_fold_vtable = {
422         isl_obj_union_pw_qpf_copy,
423         isl_obj_union_pw_qpf_add,
424         isl_obj_union_pw_qpf_print,
425         isl_obj_union_pw_qpf_free
426 };