Bug Summary

File:src/yldlocs.c
Warning:line 100, column 2
Value stored to 'i' is never read

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 yldlocs.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 yldlocs.c
1
2#include "axlobs.h"
3#include "bitv.h"
4#include "debug.h"
5#include "dflow.h"
6#include "flog.h"
7#include "foam.h"
8#include "store.h"
9#include "yldlocs.h"
10
11Bool ylDebug = false((int) 0);
12#define ylDEBUGif (!ylDebug) { } else afprintf DEBUG_IF(yl)if (!ylDebug) { } else afprintf
13
14#define ylDF_CUTOFF(100) (100)
15/*
16 * Local splitting for yields.
17 * We want to identify locals whose definition/use does not cross a yield statement
18 * Basic idea is dataflow analysis.
19 *
20 * Loc 1 --> Yld --> Usage
21 *
22 * 1. Assign a number to each local assignment
23 * 2. Associate an implied bit vector to each statement
24 * - The bitvector will mean 'From this point, assignment X is visible' and concurrently, 'assignment X has hit a yield'
25 * 3. Iterate over by bblock and statement
26 * - from an empty bitvector,
27 * - assignment X will set bit 'X_s', and clear other sets of that local + yields
28 * - yield => set yld flag for that local
29 * 4. Magic of dataflow; hd and tl of each BB will give source of each assignment, plus if a yield was encountered for that source.
30 *
31 * Simple version:
32 * For each BB find candidates (Def/Use in same BB, dropping yields), and fails (fail == use without set, use after yield).
33 * If a given local is always a candidate, then mark as local
34 */
35
36typedef struct ylState {
37 BitvClass bitvClass;
38 Foam prog;
39 FlowGraph flog;
40 Bitv result;
41 int nLocals;
42} *YlState;
43
44static YlState ylProgState;
45
46localstatic void ylFlowInitBlock0(FlowGraph flog);
47localstatic void ylFlowFillGenKillBB(FlowGraph flog, BBlock bb);
48localstatic void ylFlowFillGenKillStmt(BBlock bb, Foam stmt, Bitv gen, Bitv kill);
49localstatic void ylSet(BBlock bb, Foam lhs, Bitv gen, Bitv kill);
50localstatic void ylYield(BBlock bb, Foam lhs, Bitv gen, Bitv kill);
51localstatic void ylComputeResult(BBlock bb);
52localstatic void ylFindUses(BBlock bb, Bitv bitv, Foam foam);
53localstatic void ylFindUsesLhs(BBlock bb, Bitv bitv, Foam foam);
54localstatic void ylCheckLoc(BBlock bb, Bitv bitv, AInt idx);
55localstatic void ylMarkLoc(YlState state, AInt idx);
56
57localstatic YlState ylStateNew(Foam prog, FlowGraph flog, int nLocals);
58localstatic void ylStateFree(YlState);
59localstatic void ylStateToResult(YlState);
60localstatic YldLocResult ylLocResultFrState(YlState state);
61
62YldLocResult
63ylProg0(Foam prog)
64{
65 AInt locCount = foamDDeclArgc(prog->foamProg.locals)(((prog->foamProg.locals)->hdr.argc) - (1));
66 AIntList reclocs = listNil(AInt)((AIntList) 0);
67 YldLocResult result = (YldLocResult) stoAlloc(OB_Other0, sizeof(*result));
68
69 for (int i=0; i<locCount; i++) {
70 reclocs = listCons(AInt)(AInt_listPointer->Cons)(i, reclocs);
71 }
72
73 result->locs = listNil(AInt)((AIntList) 0);
74 result->reclocs = listNReverse(AInt)(AInt_listPointer->NReverse)(reclocs);
75 return result;
76
77}
78
79YldLocResult
80ylProg(Foam prog)
81{
82 FlowGraph flog;
83 BBlock bb;
84 AInt locCount = foamDDeclArgc(prog->foamProg.locals)(((prog->foamProg.locals)->hdr.argc) - (1));
85 int i, k;
86
87 ylDEBUGif (!ylDebug) { } else afprintf(dbOut, "Starting\n %pFoam\n", prog);
88
89 flog = flogFrProg(prog, FLOG_UniqueExit);
90 ylProgState = ylStateNew(prog, flog, locCount);
91
92 flogBitvClass(flog)((flog)->bitvClass) = bitvClassCreate(locCount * 2);
93
94 for (i = 0; i < flogBlockC(flog)((flog)->blocks->pos); i++) {
95 bb = flogBlock(flog, i)bbufBlockFn((flog)->blocks,i);
96 dflowNewBlockInfo(bb, locCount * 2, ylFlowFillGenKillBB);
97 }
98
99 // Run dflow...
100 i = dflowFwdIterate(flog, DFLOW_Union, ylDF_CUTOFF(100), &k,
Value stored to 'i' is never read
101 (DFlowInitFun) ylFlowInitBlock0);
102
103 // Find the result
104 for (i = 0; i < flogBlockC(flog)((flog)->blocks->pos); i++) {
105 bb = flogBlock(flog, i)bbufBlockFn((flog)->blocks,i);
106 if (bb != NULL((void*)0))
107 ylComputeResult(bb);
108 }
109
110 YldLocResult result = ylLocResultFrState(ylProgState);
111 // Back to Prog mode
112 flogToProg(flog);
113 ylStateFree(ylProgState);
114 ylDEBUGif (!ylDebug) { } else afprintf(dbOut, "Locs %pAIntList\n", result->locs);
115 ylDEBUGif (!ylDebug) { } else afprintf(dbOut, "Record %pAIntList\n", result->reclocs);
116 return result;
117}
118
119localstatic void
120ylFlowInitBlock0(FlowGraph flog)
121{
122 // All zeros to start
123 return;
124}
125
126
127localstatic void
128ylFlowFillGenKillBB(FlowGraph flog, BBlock bb)
129{
130 Foam seq, stmt;
131 int i;
132 seq = bb->code;
133 ylDEBUGif (!ylDebug) { } else afprintf(dbOut, "(BB Starts %pFoam\n", seq);
134
135 bitvClearAll(ylProgState->bitvClass, dfFwdIn(bb)((bb)->dfinfo->in));
136 bitvClearAll(ylProgState->bitvClass, dfFwdGen(bb)((bb)->dfinfo->gen));
137 bitvClearAll(ylProgState->bitvClass, dfFwdKill(bb, int0)((bb)->dfinfo->exit[((int) 0)].kill));
138
139 for (i=0; i<foamArgc(seq)((seq)->hdr.argc); i++) {
140 Foam stmt = seq->foamSeq.argv[i];
141 ylFlowFillGenKillStmt(bb, stmt, dfFwdGen(bb)((bb)->dfinfo->gen), dfFwdKill(bb, int0)((bb)->dfinfo->exit[((int) 0)].kill));
142
143 Bitv chk = bitvNew(ylProgState->bitvClass);
144 bitvClearAll(ylProgState->bitvClass, chk);
145 bitvAnd(ylProgState->bitvClass, chk, dfFwdGen(bb)((bb)->dfinfo->gen), dfFwdKill(bb, int0)((bb)->dfinfo->exit[((int) 0)].kill));
146 assert(0 == bitvCount(ylProgState->bitvClass, chk))do { if (!(0 == bitvCount(ylProgState->bitvClass, chk))) _do_assert
(("0 == bitvCount(ylProgState->bitvClass, chk)"),"yldlocs.c"
,146); } while (0)
;
147 bitvFree(chk);
148 }
149 ylDEBUGif (!ylDebug) { } else afprintf(dbOut, " BB Done - Gen %pAIntList\n", bitvToAIntList(ylProgState->bitvClass, dfFwdGen(bb)((bb)->dfinfo->gen)));
150 ylDEBUGif (!ylDebug) { } else afprintf(dbOut, " BB Done - Kill %pAIntList)\n", bitvToAIntList(ylProgState->bitvClass, dfFwdKill(bb, int0)((bb)->dfinfo->exit[((int) 0)].kill)));
151}
152
153localstatic void
154ylFlowFillGenKillStmt(BBlock bb, Foam stmt, Bitv gen, Bitv kill)
155{
156 switch (foamTag(stmt)((stmt)->hdr.tag)) {
157 case FOAM_Set:
158 case FOAM_Def:
159 ylSet(bb, stmt->foamSet.lhs, gen, kill);
160 break;
161 case FOAM_Yield:
162 ylYield(bb, stmt, gen, kill);
163 break;
164 default:
165 break;
166 }
167}
168
169localstatic void
170ylSet(BBlock bb, Foam lhs, Bitv gen, Bitv kill)
171{
172 if (foamTag(lhs)((lhs)->hdr.tag) == FOAM_Values) {
173 foamIter(lhs, v, {{ { String argf = (foamInfoTable [(int)(((lhs)->hdr.tag))-
(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((lhs
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *v = (Foam *) ((lhs)->foamGen.argv)
+_i; { { ylSet(bb, *v, gen, kill); }; }; } } }; }
174 ylSet(bb, *v, gen, kill);{ { String argf = (foamInfoTable [(int)(((lhs)->hdr.tag))-
(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((lhs
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *v = (Foam *) ((lhs)->foamGen.argv)
+_i; { { ylSet(bb, *v, gen, kill); }; }; } } }; }
175 }){ { String argf = (foamInfoTable [(int)(((lhs)->hdr.tag))-
(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((lhs
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *v = (Foam *) ((lhs)->foamGen.argv)
+_i; { { ylSet(bb, *v, gen, kill); }; }; } } }; }
;
176 }
177 if (foamTag(lhs)((lhs)->hdr.tag) == FOAM_Loc) {
178 bitvClear(bbBitvClass(bb)((((bb)->graph)->bitvClass)), kill, lhs->foamLoc.index);
179 bitvSet(bbBitvClass(bb)((((bb)->graph)->bitvClass)), gen, lhs->foamLoc.index);
180 bitvClear(bbBitvClass(bb)((((bb)->graph)->bitvClass)), gen, ylProgState->nLocals + lhs->foamLoc.index);
181 bitvSet(bbBitvClass(bb)((((bb)->graph)->bitvClass)), kill, ylProgState->nLocals + lhs->foamLoc.index);
182 }
183}
184
185localstatic void
186ylYield(BBlock bb, Foam stmt, Bitv gen, Bitv kill)
187{
188 AInt count = ylProgState->nLocals;
189 for (int i = count; i < 2*count; i++) {
190 bitvClear(bbBitvClass(bb)((((bb)->graph)->bitvClass)), kill, i);
191 bitvSet(bbBitvClass(bb)((((bb)->graph)->bitvClass)), gen, i);
192 }
193}
194
195localstatic void
196ylComputeResult(BBlock bb)
197{
198 Foam code = bb->code;
199 Bitv bitv = dfFwdIn(bb)((bb)->dfinfo->in);
200
201 for (int i=0; i<foamArgc(code)((code)->hdr.argc); i++) {
202 Foam stmt = code->foamSeq.argv[i];
203 ylFindUses(bb, bitv, stmt);
204 }
205}
206
207localstatic void
208ylFindUses(BBlock bb, Bitv bitv, Foam foam)
209{
210 switch (foamTag(foam)((foam)->hdr.tag)) {
211 case FOAM_Set:
212 case FOAM_Def:
213 // NB: Evaluation order
214 ylFindUses(bb, bitv, foam->foamSet.rhs);
215 ylFindUsesLhs(bb, bitv, foam->foamSet.lhs);
216 break;
217 case FOAM_Loc:
218 ylCheckLoc(bb, bitv, foam->foamLoc.index);
219 break;
220 case FOAM_Yield:
221 ylFindUses(bb, bitv, foam->foamYield.value);
222 for (int i=0; i<ylProgState->nLocals; i++) {
223 bitvSet(bbBitvClass(bb)((((bb)->graph)->bitvClass)), bitv, ylProgState->nLocals + i);
224 }
225 break;
226 default:
227 foamIter(foam, expr, ylFindUses(bb, bitv, *expr)){ { String argf = (foamInfoTable [(int)(((foam)->hdr.tag))
-(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((foam
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *expr = (Foam *) ((foam)->foamGen.argv
)+_i; { ylFindUses(bb, bitv, *expr); }; } } }; }
;
228 }
229}
230
231localstatic void
232ylFindUsesLhs(BBlock bb, Bitv bitv, Foam foam)
233{
234 switch (foamTag(foam)((foam)->hdr.tag)) {
235 case FOAM_Values:
236 foamIter(foam, e, ylFindUsesLhs(bb, bitv, *e)){ { String argf = (foamInfoTable [(int)(((foam)->hdr.tag))
-(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((foam
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *e = (Foam *) ((foam)->foamGen.argv
)+_i; { ylFindUsesLhs(bb, bitv, *e); }; } } }; }
;
237 break;
238 case FOAM_Loc:
239 bitvSet(ylProgState->bitvClass, bitv, foam->foamLoc.index);
240 bitvClear(ylProgState->bitvClass, bitv, ylProgState->nLocals + foam->foamLoc.index);
241 break;
242 default:
243 foamIter(foam, expr, ylFindUses(bb, bitv, *expr)){ { String argf = (foamInfoTable [(int)(((foam)->hdr.tag))
-(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((foam
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *expr = (Foam *) ((foam)->foamGen.argv
)+_i; { ylFindUses(bb, bitv, *expr); }; } } }; }
;
244 }
245}
246
247
248localstatic void
249ylCheckLoc(BBlock bb, Bitv bitv, AInt idx)
250{
251 Bool live = bitvTest(ylProgState->bitvClass, bitv, idx);
252 Bool yld = bitvTest(ylProgState->bitvClass, bitv, idx + ylProgState->nLocals);
253
254 if (live && yld) {
255 ylMarkLoc(ylProgState, idx);
256 }
257}
258
259localstatic void
260ylMarkLoc(YlState state, AInt idx)
261{
262 ylDEBUGif (!ylDebug) { } else afprintf(dbOut, "Marking loc %d\n", idx);
263 bitvSet(state->bitvClass, state->result, idx);
264}
265
266localstatic YlState
267ylStateNew(Foam prog, FlowGraph flog, int nLocals)
268{
269 YlState state = (YlState) stoAlloc(OB_Other0, sizeof(*state));
270 state->nLocals = nLocals;
271 state->prog = prog;
272 state->flog = flog;
273 state->bitvClass = bitvClassCreate(2*nLocals);
274 state->result = bitvNew(state->bitvClass);
275 bitvClearAll(state->bitvClass, state->result);
276 return state;
277}
278
279localstatic void
280ylStateFree(YlState state)
281{
282 bitvClassDestroy(state->bitvClass);
283 stoFree(state);
284}
285
286localstatic YldLocResult
287ylLocResultFrState(YlState state)
288{
289 YldLocResult result = (YldLocResult) stoAlloc(OB_Other0, sizeof(*result));
290 AIntList reclocs = listNil(AInt)((AIntList) 0);
291 AIntList locs = listNil(AInt)((AIntList) 0);
292
293 for (int i=0; i<state->nLocals; i++) {
294 if (bitvTest(state->bitvClass, state->result, i))
295 reclocs = listCons(AInt)(AInt_listPointer->Cons)(i, reclocs);
296 else
297 locs = listCons(AInt)(AInt_listPointer->Cons)(i, locs);
298 }
299 result->reclocs = listNReverse(AInt)(AInt_listPointer->NReverse)(reclocs);
300 result->locs = listNReverse(AInt)(AInt_listPointer->NReverse)(locs);
301
302 return result;
303}
304
305void
306ylLocResultFree(YldLocResult result)
307{
308 listFree(AInt)(AInt_listPointer->Free)(result->locs);
309 listFree(AInt)(AInt_listPointer->Free)(result->reclocs);
310 stoFree(result);
311}