Bug Summary

File:polly/lib/External/isl/isl_ctx.c
Warning:line 170, column 12
Dereference of null pointer

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name isl_ctx.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=gnu99 -fconst-strings -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0=. -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-08-28-193554-24367-1 -x c /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_ctx.c
1/*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 *
4 * Use of this software is governed by the MIT license
5 *
6 * Written by Sven Verdoolaege, K.U.Leuven, Departement
7 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
8 */
9
10#include <isl_ctx_private.h>
11#include <isl/vec.h>
12#include <isl_options_private.h>
13
14#define __isl_calloc(type,size)((type *)calloc(1, size)) ((type *)calloc(1, size))
15#define __isl_calloc_type(type)((type *)calloc(1, sizeof(type))) __isl_calloc(type,sizeof(type))((type *)calloc(1, sizeof(type)))
16
17/* Construct an isl_stat indicating whether "obj" is non-NULL.
18 *
19 * That is, return isl_stat_ok if "obj" is non_NULL and
20 * isl_stat_error otherwise.
21 */
22isl_stat isl_stat_non_null(void *obj)
23{
24 if (obj != NULL((void*)0))
25 return isl_stat_ok;
26 return isl_stat_error;
27}
28
29/* Return the negation of "b", where the negation of isl_bool_error
30 * is isl_bool_error again.
31 */
32isl_bool isl_bool_not(isl_bool b)
33{
34 if (b < 0)
35 return isl_bool_error;
36 if (b == isl_bool_false)
37 return isl_bool_true;
38 return isl_bool_false;
39}
40
41/* Create an isl_bool from an integer.
42 *
43 * Return isl_bool_false if b is zero, otherwise return isl_bool_true.
44 * This function never returns isl_bool_error.
45 */
46isl_bool isl_bool_ok(int b)
47{
48 if (b)
49 return isl_bool_true;
50 return isl_bool_false;
51}
52
53/* Check that the result of an allocation ("p") is not NULL and
54 * complain if it is.
55 * The only exception is when allocation size ("size") is equal to zero.
56 */
57static void *check_non_null(isl_ctx *ctx, void *p, size_t size)
58{
59 if (p || size == 0)
60 return p;
61 isl_die(ctx, isl_error_alloc, "allocation failure", return NULL)do { isl_handle_error(ctx, isl_error_alloc, "allocation failure"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_ctx.c"
, 61); return ((void*)0); } while (0)
;
62}
63
64/* Prepare for performing the next "operation" in the context.
65 * Return 0 if we are allowed to perform this operation and
66 * return -1 if we should abort the computation.
67 *
68 * In particular, we should stop if the user has explicitly aborted
69 * the computation or if the maximal number of operations has been exceeded.
70 */
71int isl_ctx_next_operation(isl_ctx *ctx)
72{
73 if (!ctx)
74 return -1;
75 if (ctx->abort) {
76 isl_ctx_set_error(ctx, isl_error_abort);
77 return -1;
78 }
79 if (ctx->max_operations && ctx->operations >= ctx->max_operations)
80 isl_die(ctx, isl_error_quota,do { isl_handle_error(ctx, isl_error_quota, "maximal number of operations exceeded"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_ctx.c"
, 81); return -1; } while (0)
81 "maximal number of operations exceeded", return -1)do { isl_handle_error(ctx, isl_error_quota, "maximal number of operations exceeded"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_ctx.c"
, 81); return -1; } while (0)
;
82 ctx->operations++;
83 return 0;
84}
85
86/* Call malloc and complain if it fails.
87 * If ctx is NULL, then return NULL.
88 */
89void *isl_malloc_or_die(isl_ctx *ctx, size_t size)
90{
91 if (isl_ctx_next_operation(ctx) < 0)
92 return NULL((void*)0);
93 return ctx ? check_non_null(ctx, malloc(size), size) : NULL((void*)0);
94}
95
96/* Call calloc and complain if it fails.
97 * If ctx is NULL, then return NULL.
98 */
99void *isl_calloc_or_die(isl_ctx *ctx, size_t nmemb, size_t size)
100{
101 if (isl_ctx_next_operation(ctx) < 0)
102 return NULL((void*)0);
103 return ctx ? check_non_null(ctx, calloc(nmemb, size), nmemb) : NULL((void*)0);
104}
105
106/* Call realloc and complain if it fails.
107 * If ctx is NULL, then return NULL.
108 */
109void *isl_realloc_or_die(isl_ctx *ctx, void *ptr, size_t size)
110{
111 if (isl_ctx_next_operation(ctx) < 0)
112 return NULL((void*)0);
113 return ctx ? check_non_null(ctx, realloc(ptr, size), size) : NULL((void*)0);
114}
115
116/* Keep track of all information about the current error ("error", "msg",
117 * "file", "line") in "ctx".
118 */
119void isl_ctx_set_full_error(isl_ctx *ctx, enum isl_error error, const char *msg,
120 const char *file, int line)
121{
122 if (!ctx)
123 return;
124 ctx->error = error;
125 ctx->error_msg = msg;
126 ctx->error_file = file;
127 ctx->error_line = line;
128}
129
130void isl_handle_error(isl_ctx *ctx, enum isl_error error, const char *msg,
131 const char *file, int line)
132{
133 if (!ctx)
134 return;
135
136 isl_ctx_set_full_error(ctx, error, msg, file, line);
137
138 switch (ctx->opt->on_error) {
139 case ISL_ON_ERROR_WARN0:
140 fprintf(stderrstderr, "%s:%d: %s\n", file, line, msg);
141 return;
142 case ISL_ON_ERROR_CONTINUE1:
143 return;
144 case ISL_ON_ERROR_ABORT2:
145 fprintf(stderrstderr, "%s:%d: %s\n", file, line, msg);
146 abort();
147 return;
148 }
149}
150
151static struct isl_options *find_nested_options(struct isl_args *args,
152 void *opt, struct isl_args *wanted)
153{
154 int i;
155 struct isl_options *options;
156
157 if (args == wanted)
7
Assuming 'args' is not equal to 'wanted'
8
Taking false branch
16
Assuming 'args' is equal to 'wanted'
17
Taking true branch
158 return opt;
18
Returning pointer (loaded from 'opt'), which participates in a condition later
159
160 for (i = 0; args->args[i].type != isl_arg_end; ++i) {
9
Assuming field 'type' is not equal to isl_arg_end
10
Loop condition is true. Entering loop body
22
Assuming field 'type' is not equal to isl_arg_end
23
Loop condition is true. Entering loop body
161 struct isl_arg *arg = &args->args[i];
162 void *child;
163
164 if (arg->type != isl_arg_child)
11
Assuming field 'type' is equal to isl_arg_child
12
Taking false branch
24
Assuming field 'type' is equal to isl_arg_child
25
Taking false branch
165 continue;
166
167 if (arg->offset == ISL_ARG_OFFSET_NONE((size_t) -1))
13
Assuming the condition is true
14
Taking true branch
26
Assuming the condition is false
27
Taking false branch
168 child = opt;
169 else
170 child = *(void **)(((char *)opt) + arg->offset);
28
Dereference of null pointer
171
172 options = find_nested_options(arg->u.child.child,
15
Calling 'find_nested_options'
19
Returning from 'find_nested_options'
173 child, wanted);
174 if (options)
20
Assuming 'options' is null
21
Taking false branch
175 return options;
176 }
177
178 return NULL((void*)0);
179}
180
181static struct isl_options *find_nested_isl_options(struct isl_args *args,
182 void *opt)
183{
184 return find_nested_options(args, opt, &isl_options_args);
185}
186
187void *isl_ctx_peek_options(isl_ctx *ctx, struct isl_args *args)
188{
189 if (!ctx)
1
Assuming 'ctx' is non-null
2
Taking false branch
190 return NULL((void*)0);
191 if (args == &isl_options_args)
3
Assuming the condition is false
4
Taking false branch
192 return ctx->opt;
193 return find_nested_options(ctx->user_args, ctx->user_opt, args);
5
Passing value via 2nd parameter 'opt'
6
Calling 'find_nested_options'
194}
195
196isl_ctx *isl_ctx_alloc_with_options(struct isl_args *args, void *user_opt)
197{
198 struct isl_ctx *ctx = NULL((void*)0);
199 struct isl_options *opt = NULL((void*)0);
200 int opt_allocated = 0;
201
202 if (!user_opt)
203 return NULL((void*)0);
204
205 opt = find_nested_isl_options(args, user_opt);
206 if (!opt) {
207 opt = isl_options_new_with_defaults();
208 if (!opt)
209 goto error;
210 opt_allocated = 1;
211 }
212
213 ctx = __isl_calloc_type(struct isl_ctx)((struct isl_ctx *)calloc(1, sizeof(struct isl_ctx)));
214 if (!ctx)
215 goto error;
216
217 if (isl_hash_table_init(ctx, &ctx->id_table, 0))
218 goto error;
219
220 ctx->stats = isl_calloc_type(ctx, struct isl_stats)((struct isl_stats *)isl_calloc_or_die(ctx, 1, sizeof(struct isl_stats
)))
;
221 if (!ctx->stats)
222 goto error;
223
224 ctx->user_args = args;
225 ctx->user_opt = user_opt;
226 ctx->opt_allocated = opt_allocated;
227 ctx->opt = opt;
228 ctx->ref = 0;
229
230 isl_int_init(ctx->zero)isl_sioimath_init((ctx->zero));
231 isl_int_set_si(ctx->zero, 0)isl_sioimath_set_si((ctx->zero), 0);
232
233 isl_int_init(ctx->one)isl_sioimath_init((ctx->one));
234 isl_int_set_si(ctx->one, 1)isl_sioimath_set_si((ctx->one), 1);
235
236 isl_int_init(ctx->two)isl_sioimath_init((ctx->two));
237 isl_int_set_si(ctx->two, 2)isl_sioimath_set_si((ctx->two), 2);
238
239 isl_int_init(ctx->negone)isl_sioimath_init((ctx->negone));
240 isl_int_set_si(ctx->negone, -1)isl_sioimath_set_si((ctx->negone), -1);
241
242 isl_int_init(ctx->normalize_gcd)isl_sioimath_init((ctx->normalize_gcd));
243
244 ctx->n_cached = 0;
245 ctx->n_miss = 0;
246
247 isl_ctx_reset_error(ctx);
248
249 ctx->operations = 0;
250 isl_ctx_set_max_operations(ctx, ctx->opt->max_operations);
251
252 return ctx;
253error:
254 isl_args_free(args, user_opt);
255 if (opt_allocated)
256 isl_options_free(opt);
257 free(ctx);
258 return NULL((void*)0);
259}
260
261struct isl_ctx *isl_ctx_alloc()
262{
263 struct isl_options *opt;
264
265 opt = isl_options_new_with_defaults();
266
267 return isl_ctx_alloc_with_options(&isl_options_args, opt);
268}
269
270void isl_ctx_ref(struct isl_ctx *ctx)
271{
272 ctx->ref++;
273}
274
275void isl_ctx_deref(struct isl_ctx *ctx)
276{
277 isl_assert(ctx, ctx->ref > 0, return)do { if (ctx->ref > 0) break; do { isl_handle_error(ctx
, isl_error_unknown, "Assertion \"" "ctx->ref > 0" "\" failed"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_ctx.c"
, 277); return; } while (0); } while (0)
;
278 ctx->ref--;
279}
280
281/* Print statistics on usage.
282 */
283static void print_stats(isl_ctx *ctx)
284{
285 fprintf(stderrstderr, "operations: %lu\n", ctx->operations);
286}
287
288void isl_ctx_free(struct isl_ctx *ctx)
289{
290 if (!ctx)
291 return;
292 if (ctx->ref != 0)
293 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "isl_ctx freed, but some objects still reference it"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_ctx.c"
, 295); return; } while (0)
294 "isl_ctx freed, but some objects still reference it",do { isl_handle_error(ctx, isl_error_invalid, "isl_ctx freed, but some objects still reference it"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_ctx.c"
, 295); return; } while (0)
295 return)do { isl_handle_error(ctx, isl_error_invalid, "isl_ctx freed, but some objects still reference it"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_ctx.c"
, 295); return; } while (0)
;
296
297 if (ctx->opt->print_stats)
298 print_stats(ctx);
299
300 isl_hash_table_clear(&ctx->id_table);
301 isl_blk_clear_cache(ctx);
302 isl_int_clear(ctx->zero)isl_sioimath_clear((ctx->zero));
303 isl_int_clear(ctx->one)isl_sioimath_clear((ctx->one));
304 isl_int_clear(ctx->two)isl_sioimath_clear((ctx->two));
305 isl_int_clear(ctx->negone)isl_sioimath_clear((ctx->negone));
306 isl_int_clear(ctx->normalize_gcd)isl_sioimath_clear((ctx->normalize_gcd));
307 isl_args_free(ctx->user_args, ctx->user_opt);
308 if (ctx->opt_allocated)
309 isl_options_free(ctx->opt);
310 free(ctx->stats);
311 free(ctx);
312}
313
314struct isl_options *isl_ctx_options(isl_ctx *ctx)
315{
316 if (!ctx)
317 return NULL((void*)0);
318 return ctx->opt;
319}
320
321enum isl_error isl_ctx_last_error(isl_ctx *ctx)
322{
323 return ctx ? ctx->error : isl_error_invalid;
324}
325
326/* Return the error message of the last error in "ctx".
327 */
328const char *isl_ctx_last_error_msg(isl_ctx *ctx)
329{
330 return ctx ? ctx->error_msg : NULL((void*)0);
331}
332
333/* Return the file name where the last error in "ctx" occurred.
334 */
335const char *isl_ctx_last_error_file(isl_ctx *ctx)
336{
337 return ctx ? ctx->error_file : NULL((void*)0);
338}
339
340/* Return the line number where the last error in "ctx" occurred.
341 */
342int isl_ctx_last_error_line(isl_ctx *ctx)
343{
344 return ctx ? ctx->error_line : -1;
345}
346
347void isl_ctx_reset_error(isl_ctx *ctx)
348{
349 if (!ctx)
350 return;
351 ctx->error = isl_error_none;
352 ctx->error_msg = NULL((void*)0);
353 ctx->error_file = NULL((void*)0);
354 ctx->error_line = -1;
355}
356
357void isl_ctx_set_error(isl_ctx *ctx, enum isl_error error)
358{
359 isl_ctx_set_full_error(ctx, error, NULL((void*)0), NULL((void*)0), -1);
360}
361
362void isl_ctx_abort(isl_ctx *ctx)
363{
364 if (ctx)
365 ctx->abort = 1;
366}
367
368void isl_ctx_resume(isl_ctx *ctx)
369{
370 if (ctx)
371 ctx->abort = 0;
372}
373
374int isl_ctx_aborted(isl_ctx *ctx)
375{
376 return ctx ? ctx->abort : -1;
377}
378
379int isl_ctx_parse_options(isl_ctx *ctx, int argc, char **argv, unsigned flags)
380{
381 if (!ctx)
382 return -1;
383 return isl_args_parse(ctx->user_args, argc, argv, ctx->user_opt, flags);
384}
385
386/* Set the maximal number of iterations of "ctx" to "max_operations".
387 */
388void isl_ctx_set_max_operations(isl_ctx *ctx, unsigned long max_operations)
389{
390 if (!ctx)
391 return;
392 ctx->max_operations = max_operations;
393}
394
395/* Return the maximal number of iterations of "ctx".
396 */
397unsigned long isl_ctx_get_max_operations(isl_ctx *ctx)
398{
399 return ctx ? ctx->max_operations : 0;
400}
401
402/* Reset the number of operations performed by "ctx".
403 */
404void isl_ctx_reset_operations(isl_ctx *ctx)
405{
406 if (!ctx)
407 return;
408 ctx->operations = 0;
409}