Bug Summary

File:src/table.c
Warning:line 283, column 18
Division by zero

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name table.c -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 -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/kfp/aldor/aldor/aldor/src -fcoverage-compilation-dir=/home/kfp/aldor/aldor/aldor/src -resource-dir /usr/local/lib/clang/18 -D PACKAGE_NAME="aldor" -D PACKAGE_TARNAME="aldor" -D PACKAGE_VERSION="1.4.0" -D PACKAGE_STRING="aldor 1.4.0" -D PACKAGE_BUGREPORT="aldor@xinutec.org" -D PACKAGE_URL="" -D PACKAGE="aldor" -D VERSION="1.4.0" -D YYTEXT_POINTER=1 -D HAVE_STDIO_H=1 -D HAVE_STDLIB_H=1 -D HAVE_STRING_H=1 -D HAVE_INTTYPES_H=1 -D HAVE_STDINT_H=1 -D HAVE_STRINGS_H=1 -D HAVE_SYS_STAT_H=1 -D HAVE_SYS_TYPES_H=1 -D HAVE_UNISTD_H=1 -D STDC_HEADERS=1 -D HAVE_LIBREADLINE=1 -D HAVE_READLINE_READLINE_H=1 -D HAVE_READLINE_HISTORY=1 -D HAVE_READLINE_HISTORY_H=1 -D USE_GLOOP_SHELL=1 -D GENERATOR_COROUTINES=0 -D HAVE_DLFCN_H=1 -D LT_OBJDIR=".libs/" -I . -D VCSVERSION="2c53e759f1e00e345f8b172e7139debda72fda13" -internal-isystem /usr/local/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-empty-body -Wno-enum-compare -Wno-missing-field-initializers -Wno-unused -Wno-unused-parameter -Wno-error=format -Wno-error=type-limits -Wno-error=strict-aliasing -Wno-sign-compare -Wno-error=shift-negative-value -Wno-error=clobbered -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2026-01-15-223856-845667-1 -x c table.c
1/*****************************************************************************
2 *
3 * table.c: Hash table data type.
4 *
5 * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org).
6 *
7 ****************************************************************************/
8
9#include "axlgen.h"
10#include "format.h"
11#include "store.h"
12#include "table.h"
13#include "util.h"
14
15# define TBL_InitBuckC7 7 /* Largest prime under 2**i, for some i. */
16# define TBL_MaxLoad5 5
17
18localstatic Table tblNew0 (TblHashFun, TblEqFun, int buckc);
19localstatic void tblEnlarge (Table);
20
21Table
22tblNew(TblHashFun hash, TblEqFun eq)
23{
24 return tblNew0(hash, eq, TBL_InitBuckC7);
25}
26
27localstatic Table
28tblNew0(TblHashFun hash, TblEqFun eq, int buckc)
29{
30 Length i;
31 Table t = (Table) stoAlloc((unsigned) OB_Table9, sizeof(*t));
32 t->hashFun = hash;
33 t->eqFun = eq;
34 t->info = 0;
35 t->count = 0;
36 t->buckc = buckc;
37 t->buckv = (struct TblSlot **)
38 stoAlloc((unsigned) OB_Other0, buckc*sizeof(struct TblSlot *));
39 for (i = 0; i < buckc; i++) t->buckv[i] = 0;
40 return t;
41}
42
43void
44tblFreeDeeply(Table t, TblFreeKeyFun fk, TblFreeEltFun fe)
45{
46
47 struct TblSlot *b, *nb;
48 int i;
49
50 for (i = 0; i < t->buckc; i++) {
51 for (b = t->buckv[i]; b; ) {
52 nb = b->next;
53 if (fk) fk(b->key);
54 if (fe) fe(b->elt);
55 stoFree((Pointer) b);
56 b = nb;
57 }
58 }
59 stoFree((Pointer) t->buckv);
60 stoFree((Pointer) t);
61}
62
63void
64tblFree(Table t)
65{
66 struct TblSlot *b, *nb;
67 int i;
68
69 for (i = 0; i < t->buckc; i++)
70 for (b = t->buckv[i]; b; ) {
71 nb = b->next;
72 stoFree((Pointer) b);
73 b = nb;
74 }
75 stoFree((Pointer) t->buckv);
76 stoFree((Pointer) t);
77}
78
79Table
80tblCopy(Table ot)
81{
82 Table nt;
83 struct TblSlot *ob, *nb, **pnb;
84 int i;
85
86 nt = tblNew0(ot->hashFun, ot->eqFun, ot->buckc);
87 nt->count = ot->count;
88 for (i = 0; i < ot->buckc; i++) {
89 pnb = nt->buckv + i;
90 for (ob = ot->buckv[i]; ob; ob = ob->next) {
91 nb = (struct TblSlot *)
92 stoAlloc((unsigned) OB_Other0, sizeof(*nb));
93 nb->key = ob->key;
94 nb->elt = ob->elt;
95 nb->hash = ob->hash;
96 *pnb = nb;
97 pnb = &(nb->next);
98 }
99 *pnb = 0;
100 }
101 return nt;
102}
103
104/* Given table, freeFun, testFun, apply freeFun to all (non-null) elements in
105 * table that satisfy testFun
106 */
107Table
108tblRemoveIf(Table t, TblFreeEltFun fe, TblTestEltFun f)
109{
110 struct TblSlot *b;
111 int i;
112
113 for (i = 0; i < t->buckc; i++)
114 for (b = t->buckv[i]; b; b = b->next)
115 if (b->elt && f(b->elt)) {
116 fe(b->elt);
117 b->elt = NULL((void*)0); /* !! */
118 }
119 return t;
120}
121
122Table
123tblNMap(TblMapEltFun f, Table t)
124{
125 struct TblSlot *b;
126 int i;
127
128 for (i = 0; i < t->buckc; i++)
129 for (b = t->buckv[i]; b; b = b->next)
130 b->elt = f(b->elt);
131 return t;
132}
133
134
135Length
136tblSize(Table t)
137{
138 return t->count;
139}
140
141#if 0
142#define BUCKET_SEARCH(t,x,b,h,k,efun,ACTION){ register struct TblSlot *p = 0; do { if (b->hash == h) if
(!efun || efun(k, b->key)) { if (p) { p->next = b->
next; b->next = t->buckv[x]; t->buckv[x] = b; } ACTION
; } p = b; b = b->next; } while (b); }
{ \
143 register struct TblSlot *p = 0; \
144 if (efun) { \
145 do { \
146 if (b->hash == h) \
147 if (efun(k, b->key)) { \
148 if (p) { \
149 /* Move to front */ \
150 p->next = b->next; \
151 b->next = t->buckv[x]; \
152 t->buckv[x] = b; \
153 } \
154 ACTION; \
155 } \
156 p = b; \
157 b = b->next; \
158 } while (b); \
159 } \
160 else { \
161 do { \
162 if (b->hash == h) { \
163 if (p) { \
164 /* Move to front */ \
165 p->next = b->next; \
166 b->next = t->buckv[x]; \
167 t->buckv[x] = b; \
168 } \
169 ACTION; \
170 } \
171 p = b; \
172 b = b->next; \
173 } while (b); \
174 } \
175}
176#endif
177
178#define BUCKET_SEARCH(t,x,b,h,k,efun,ACTION){ register struct TblSlot *p = 0; do { if (b->hash == h) if
(!efun || efun(k, b->key)) { if (p) { p->next = b->
next; b->next = t->buckv[x]; t->buckv[x] = b; } ACTION
; } p = b; b = b->next; } while (b); }
{ \
179 register struct TblSlot *p = 0; \
180 do { \
181 if (b->hash == h) \
182 if (!efun || efun(k, b->key)) { \
183 if (p) { \
184 /* Move to front */ \
185 p->next = b->next; \
186 b->next = t->buckv[x]; \
187 t->buckv[x] = b; \
188 } \
189 ACTION; \
190 } \
191 p = b; \
192 b = b->next; \
193 } while (b); \
194}
195
196TblElt
197tblElt(Table t, TblKey k, TblElt notFound)
198{
199 register Hash h;
200 register int x;
201 register struct TblSlot *b;
202 register TblHashFun hfun = t->hashFun;
203 register TblEqFun efun = t->eqFun;
204
205 h = hfun ? hfun(k) : (Hash) ptrCanon(k)((Pointer)(k));
206 x = h % t->buckc;
207 b = t->buckv[x];
208
209 if (b) BUCKET_SEARCH(t,x,b,h,k,efun, return b->elt){ register struct TblSlot *p = 0; do { if (b->hash == h) if
(!efun || efun(k, b->key)) { if (p) { p->next = b->
next; b->next = t->buckv[x]; t->buckv[x] = b; } return
b->elt; } p = b; b = b->next; } while (b); }
;
210
211 return notFound;
212}
213
214TblElt
215tblSetElt(Table t, TblKey k, TblElt e)
216{
217 register Hash h;
218 register int x;
219 register struct TblSlot *b;
220 register TblHashFun hfun = t->hashFun;
221 register TblEqFun efun = t->eqFun;
222
223 h = hfun ? hfun(k) : (Hash) ptrCanon(k)((Pointer)(k));
1
Assuming 'hfun' is null
2
'?' condition is false
224 x = h % t->buckc;
225 b = t->buckv[x];
226
227 if (b) BUCKET_SEARCH(t,x,b,h,k,efun, return b->elt = e){ register struct TblSlot *p = 0; do { if (b->hash == h) if
(!efun || efun(k, b->key)) { if (p) { p->next = b->
next; b->next = t->buckv[x]; t->buckv[x] = b; } return
b->elt = e; } p = b; b = b->next; } while (b); }
;
3
Assuming 'b' is null
4
Taking false branch
228
229 b = (struct TblSlot *) stoAlloc((unsigned) OB_Other0, sizeof(*b));
230 b->key = k;
231 b->elt = e;
232 b->hash = h;
233 b->next = t->buckv[x];
234 t->buckv[x] = b;
235 t->count++;
236
237 if (t->count > TBL_MaxLoad5 * t->buckc) tblEnlarge(t);
5
Assuming the condition is true
6
Taking true branch
7
Calling 'tblEnlarge'
238
239 return e;
240}
241
242
243Table
244tblDrop(Table t, TblKey k)
245{
246 register Hash h;
247 register int x;
248 register struct TblSlot *b;
249 register TblHashFun hfun = t->hashFun;
250 register TblEqFun efun = t->eqFun;
251
252 h = hfun ? hfun(k) : (Hash) ptrCanon(k)((Pointer)(k));
253 x = h % t->buckc;
254 b = t->buckv[x];
255
256 if (b) BUCKET_SEARCH(t,x,b,h,k,efun, {{ register struct TblSlot *p = 0; do { if (b->hash == h) if
(!efun || efun(k, b->key)) { if (p) { p->next = b->
next; b->next = t->buckv[x]; t->buckv[x] = b; } { t->
buckv[x] = b->next; t->count--; stoFree((Pointer) b); return
t; }; } p = b; b = b->next; } while (b); }
257 t->buckv[x] = b->next;{ register struct TblSlot *p = 0; do { if (b->hash == h) if
(!efun || efun(k, b->key)) { if (p) { p->next = b->
next; b->next = t->buckv[x]; t->buckv[x] = b; } { t->
buckv[x] = b->next; t->count--; stoFree((Pointer) b); return
t; }; } p = b; b = b->next; } while (b); }
258 t->count--;{ register struct TblSlot *p = 0; do { if (b->hash == h) if
(!efun || efun(k, b->key)) { if (p) { p->next = b->
next; b->next = t->buckv[x]; t->buckv[x] = b; } { t->
buckv[x] = b->next; t->count--; stoFree((Pointer) b); return
t; }; } p = b; b = b->next; } while (b); }
259 stoFree((Pointer) b);{ register struct TblSlot *p = 0; do { if (b->hash == h) if
(!efun || efun(k, b->key)) { if (p) { p->next = b->
next; b->next = t->buckv[x]; t->buckv[x] = b; } { t->
buckv[x] = b->next; t->count--; stoFree((Pointer) b); return
t; }; } p = b; b = b->next; } while (b); }
260 return t;{ register struct TblSlot *p = 0; do { if (b->hash == h) if
(!efun || efun(k, b->key)) { if (p) { p->next = b->
next; b->next = t->buckv[x]; t->buckv[x] = b; } { t->
buckv[x] = b->next; t->count--; stoFree((Pointer) b); return
t; }; } p = b; b = b->next; } while (b); }
261 }){ register struct TblSlot *p = 0; do { if (b->hash == h) if
(!efun || efun(k, b->key)) { if (p) { p->next = b->
next; b->next = t->buckv[x]; t->buckv[x] = b; } { t->
buckv[x] = b->next; t->count--; stoFree((Pointer) b); return
t; }; } p = b; b = b->next; } while (b); }
;
262
263 return t;
264}
265
266localstatic void
267tblEnlarge(Table t)
268{
269 register struct TblSlot **nbuckv, *b, *hd;
270 register int nbuckc, i, x;
271
272 nbuckc = binPrime(cielLg(t->buckc)+1);
8
Value assigned to 'nbuckc'
273 nbuckv = (struct TblSlot **)
274 stoAlloc((unsigned) OB_Other0, nbuckc*sizeof(struct TblSlot*));
275 for (i = 0; i < nbuckc; i++) nbuckv[i] = 0;
9
Assuming 'i' is >= 'nbuckc'
10
Loop condition is false. Execution continues on line 277
276
277 for (i = 0; i
10.1
'i' is < field 'buckc'
< t->buckc; i++) {
11
Loop condition is true. Entering loop body
278 b = t->buckv[i];
279 while (b) {
12
Loop condition is true. Entering loop body
280 hd = b;
281 b = b->next;
282
283 x = hd->hash % nbuckc;
13
Division by zero
284 hd->next = nbuckv[x];
285 nbuckv[x] = hd;
286 }
287 }
288 stoFree((Pointer) t->buckv);
289 t->buckc = nbuckc;
290 t->buckv = nbuckv;
291}
292
293int
294tblPrint(FILE *fout, Table t, TblPrKeyFun prk, TblPrEltFun pre)
295{
296 struct TblSlot *b;
297 int cc, i, j;
298
299 cc = fprintf(fout, "Table(");
300 for (i = 0; i < t->buckc; i++) {
301 cc += fprintf(fout, "[%d] ", i);
302 for (j = 0, b = t->buckv[i]; b; j++, b = b->next) {
303 if (j > 0)
304 cc += fprintf(fout, ", ");
305 if (prk)
306 cc += prk(fout, b->key);
307 if (pre) {
308 cc += fprintf(fout, "=");
309 cc += pre(fout, b->elt);
310 }
311 }
312 cc += fprintf(fout, ";");
313 }
314 cc += fprintf(fout, ")");
315 return cc;
316}
317
318#ifndef FOAM_RTS
319int
320tblColumnPrint(FILE *fout, Table t, TblPrKeyFun prk, TblPrEltFun pre)
321{
322 struct TblSlot *b;
323 int cc, i;
324
325 /* print table entries in a single column */
326
327 cc = fnewline(fout);
328 for (i = 0; i < t->buckc; i++) {
329 for (b = t->buckv[i]; b; b = b->next) {
330 if (prk)
331 cc += prk(fout, b->key);
332 if (pre) {
333 if (prk)
334 cc += fprintf(fout, "=");
335 cc += pre(fout, b->elt);
336 cc += fnewline(fout);
337 }
338 }
339 }
340 return cc;
341}
342
343#endif
344
345int
346_tblITER(TableIterator *pit, Table t)
347{
348 pit->curr = t->buckv;
349 pit->last = t->buckv + t->buckc - 1;
350 pit->link = t->buckv[0];
351
352 if (pit->link) return 1;
353
354 /* Skip over initial empty buckets. */
355 return _tblSTEP(pit);
356}
357
358int
359_tblSTEP(TableIterator *pit)
360{
361 /* Skip to next non-empty bucket. */
362 do {
363 pit->curr++;
364 if (pit->curr > pit->last) return 0;
365 } while (!pit->curr[0]);
366
367 pit->link = pit->curr[0];
368 return 1;
369}