Bug Summary

File:src/abcheck.c
Warning:line 699, column 8
Value stored to 'what' during its initialization 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 abcheck.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 abcheck.c
1/*****************************************************************************
2 *
3 * abcheck.c: Verify tree format after macro expansion
4 *
5 * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org).
6 *
7 ****************************************************************************/
8
9#include "debug.h"
10#include "format.h"
11#include "phase.h"
12#include "spesym.h"
13#include "util.h"
14#include "forg.h"
15#include "comsg.h"
16#include "comsgdb.h"
17
18/*****************************************************************************
19 *
20 * Local function declarations
21 *
22 ****************************************************************************/
23
24localstatic void abCheckAdd (AbSyn);
25localstatic void abCheckApply (AbSyn);
26localstatic void abCheckAssign (AbSyn);
27localstatic void abCheckBuiltin (AbSyn);
28localstatic void abCheckDeclare (AbSyn);
29localstatic void abCheckDefine (AbSyn);
30localstatic void abCheckDDefine (AbSyn);
31localstatic void abCheckExport (AbSyn);
32localstatic void abCheckExtend (AbSyn);
33localstatic void abCheckFluid (AbSyn);
34localstatic void abCheckFor (AbSyn);
35localstatic void abCheckForeignImport (AbSyn);
36localstatic void abCheckForeignExport (AbSyn);
37localstatic void abCheckFree (AbSyn);
38localstatic void abCheckImport (AbSyn);
39localstatic void abCheckLambda (AbSyn);
40localstatic void abCheckLocal (AbSyn);
41localstatic void abCheckReference (AbSyn);
42localstatic void abCheckParam (AbSyn);
43localstatic void abCheckSelect (AbSyn);
44localstatic void abCheckWhere (AbSyn);
45
46localstatic Bool abCheckExportCategory (AbSyn);
47localstatic Bool abCheckExportSource (AbSyn);
48localstatic Bool abCheckExportTarget (AbSyn);
49localstatic void abCheckExtendDeclare (AbSyn, AbSyn);
50localstatic void abCheckFor0 (AbSyn);
51localstatic void abCheckFluidComma (AbSyn);
52localstatic void abCheckFluidDeclare (AbSyn, Bool);
53localstatic void abCheckParamDefine (AbSyn);
54localstatic void abCheckLOF (AbSyn, String);
55localstatic void abCheckLOFComma (AbSyn, String);
56localstatic void abCheckLOFDeclare (AbSyn, Bool, String);
57
58typedef void (*AbCheckFn) (AbSyn, String);
59
60localstatic void abCheckOneOrMoreForms (AbSyn, String, AbCheckFn);
61localstatic void abCheckOneDefine (AbSyn, String);
62localstatic void abCheckWithin (AbSyn, String);
63localstatic void abCheckWithinDeclare(AbSyn ab, String str);
64
65/*****************************************************************************
66 *
67 * Top-level entry point.
68 *
69 ****************************************************************************/
70
71void
72abCheck(AbSyn absyn)
73{
74 int i, argc;
75 AbSyn *argv;
76
77 if (!absyn)
78 bug("Encountered zero abstract syntax tree in abCheck.");
79
80 if (DEBUG(phase)phaseDebug) {
81 fnewline(dbOut);
82 fprintf(dbOut, "abCheck for ");
83 abPrint(dbOut, absyn);
84 findent += 2;
85 }
86
87 if (!abIsLeaf(absyn)(((absyn)->abHdr.tag) < AB_NODE_START)) {
88 argc = abArgc(absyn)((absyn)->abHdr.argc);
89 argv = abArgv(absyn)((absyn)->abGen.data.argv);
90
91 for (i = 0; i < argc; i++)
92 abCheck(argv[i]);
93 }
94
95 if (DEBUG(phase)phaseDebug) {
96 findent -= 2;
97 }
98
99 switch (abTag(absyn)((absyn)->abHdr.tag)) {
100 case AB_Nothing:
101 break;
102
103 case AB_Add:
104 abCheckAdd(absyn);
105 break;
106
107 case AB_Apply:
108 abCheckApply(absyn);
109 break;
110
111 case AB_Assign:
112 abCheckAssign(absyn);
113 break;
114
115 case AB_Builtin:
116 abCheckBuiltin(absyn);
117 break;
118
119 case AB_Declare:
120 abCheckDeclare(absyn);
121 break;
122
123 case AB_Define:
124 abCheckDefine(absyn);
125 break;
126
127 case AB_DDefine:
128 abCheckDDefine(absyn);
129 break;
130
131 case AB_Export:
132 abCheckExport(absyn);
133 break;
134
135 case AB_Extend:
136 abCheckExtend(absyn);
137 break;
138
139 case AB_Fluid:
140 abCheckFluid(absyn);
141 break;
142
143 case AB_For:
144 abCheckFor(absyn);
145 break;
146
147 case AB_ForeignImport:
148 abCheckForeignImport(absyn);
149 break;
150
151 case AB_ForeignExport:
152 abCheckForeignExport(absyn);
153 break;
154
155 case AB_Free:
156 abCheckFree(absyn);
157 break;
158
159 case AB_Import:
160 abCheckImport(absyn);
161 break;
162
163 case AB_Label:
164 if (!abHasTag(absyn->abLabel.label, AB_Id)((absyn->abLabel.label)->abHdr.tag == (AB_Id)))
165 comsgError(absyn, ALDOR_E_ChkBadLabel88);
166 break;
167
168 case AB_Goto:
169 if (!abHasTag(absyn->abGoto.label, AB_Id)((absyn->abGoto.label)->abHdr.tag == (AB_Id)))
170 comsgError(absyn, ALDOR_E_ChkBadGoto87);
171 break;
172
173 case AB_Lambda:
174 case AB_PLambda:
175 abCheckLambda(absyn);
176 break;
177
178 case AB_Local:
179 abCheckLocal(absyn);
180 break;
181
182 case AB_Macro:
183 comsgError(absyn, ALDOR_E_ChkBadMacro90);
184 break;
185
186 case AB_MLambda:
187 comsgError(absyn, ALDOR_E_ChkBadMLambda89);
188 break;
189
190 case AB_With:
191 abCheckOneOrMoreForms(absyn->abWith.within, "with",
192 abCheckWithin);
193 break;
194
195 case AB_Qualify:
196 if (!abHasTag(absyn->abQualify.what, AB_Id)((absyn->abQualify.what)->abHdr.tag == (AB_Id)))
197 comsgError(absyn, ALDOR_E_ChkBadQualification93);
198 break;
199
200 case AB_Where:
201 abCheckWhere(absyn);
202 break;
203
204 case AB_Select:
205 abCheckSelect(absyn);
206 break;
207
208 case AB_Reference:
209 abCheckReference(absyn);
210 break;
211
212 default:
213 break;
214 }
215}
216
217/*****************************************************************************
218 *
219 * :: abCheckAdd
220 *
221 ****************************************************************************/
222
223/*
224 * Look for improper exits from the top-level of an add body.
225 */
226localstatic void
227abCheckAdd(AbSyn absyn)
228{
229 AbSyn body = absyn->abAdd.capsule;
230 Length i, argc = abArgcAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abHdr.
argc) : 1)
;
231 AbSyn *argv = abArgvAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abGen.
data.argv) : &(body))
;
232
233 for (i = 0; i < argc; i += 1) {
234 AbSyn arg = argv[i];
235 if (abHasTag(arg, AB_Exit)((arg)->abHdr.tag == (AB_Exit))) {
236 comsgError(arg, ALDOR_E_ChkBadForm86, "add");
237 break;
238 }
239 }
240}
241
242/*****************************************************************************
243 *
244 * :: abCheckApply
245 *
246 ****************************************************************************/
247
248/*
249 * Look for improper forms in Unions and repeated
250 * selector/type pairs in Records, RawRecords and Unions.
251 */
252localstatic void
253abCheckApply(AbSyn absyn)
254{
255 AbSyn op = absyn->abApply.op;
256 Length i;
257
258 if (abIsRecordOrUnion(op)( ((((op))->abHdr.tag == (AB_Id)) && (((op))->abId
.sym)==(ssymUnion)) || ((((op))->abHdr.tag == (AB_Id)) &&
(((op))->abId.sym)==(ssymRecord)) || ((((op))->abHdr.tag
== (AB_Id)) && (((op))->abId.sym)==(ssymRawRecord
)) )
) {
259 AbSynList al = listNil(AbSyn)((AbSynList) 0);
260
261 for (i = 0; i < abApplyArgc(absyn)(((absyn)->abHdr.argc)-1); i += 1) {
262 AbSyn argi = abApplyArg(absyn, i)((absyn)->abApply.argv[i]);
263 if (listMember(AbSyn)(AbSyn_listPointer->Member)(al, argi, abEqual))
264 comsgError(argi, ALDOR_E_ChkBadRecordOrUnion94);
265 else
266 al = listCons(AbSyn)(AbSyn_listPointer->Cons)(argi, al);
267 }
268 listFree(AbSyn)(AbSyn_listPointer->Free)(al);
269 }
270}
271
272/*****************************************************************************
273 *
274 * :: abCheckAssign
275 *
276 ****************************************************************************/
277
278/*
279 * Check for improper left-hand sides of assignments.
280 */
281localstatic void
282abCheckAssign(AbSyn absyn)
283{
284 AbSyn lhs = absyn->abAssign.lhs;
285 AbSyn *argv = abArgvAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abGen.data.
argv) : &(lhs))
;
286 Length i, argc = abArgcAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abHdr.argc)
: 1)
;
287
288 for (i = 0; i < argc; i += 1) {
289 AbSyn arg = argv[i];
290
291 switch (abTag(arg)((arg)->abHdr.tag)) {
292 case AB_Id:
293 case AB_Apply:
294 break;
295
296 case AB_Declare:
297 if (abHasTag(lhs, AB_Comma)((lhs)->abHdr.tag == (AB_Comma)) &&
298 abHasTag(arg->abDeclare.id, AB_Comma)((arg->abDeclare.id)->abHdr.tag == (AB_Comma)))
299 comsgError(arg, ALDOR_E_ChkBadAssign81);
300 break;
301
302 default:
303 comsgError(arg, ALDOR_E_ChkBadAssign81);
304 break;
305 }
306 }
307}
308
309/*****************************************************************************
310 *
311 * :: abCheckBuiltin
312 *
313 ****************************************************************************/
314
315/*
316 * Check that the operations imported from Builtin are declarations.
317 */
318localstatic void
319abCheckBuiltin(AbSyn absyn)
320{
321 AbSyn what = absyn->abBuiltin.what;
322 AbSyn *argv = abArgvAs(AB_Sequence, what)(((what)->abHdr.tag == (AB_Sequence)) ? ((what)->abGen.
data.argv) : &(what))
;
323 Length i, argc = abArgcAs(AB_Sequence, what)(((what)->abHdr.tag == (AB_Sequence)) ? ((what)->abHdr.
argc) : 1)
;
324
325 for (i = 0; i < argc; i += 1)
326 if (!abHasTag(argv[i], AB_Declare)((argv[i])->abHdr.tag == (AB_Declare)))
327 comsgError(argv[i], ALDOR_E_ChkBadForm86, "builtin");
328}
329
330/*****************************************************************************
331 *
332 * :: abCheckDeclare
333 *
334 ****************************************************************************/
335
336/*
337 * Check that the id is an identifier or comma of identifiers.
338 */
339localstatic void
340abCheckDeclare(AbSyn absyn)
341{
342 AbSyn id = absyn->abDeclare.id;
343 AbSyn *argv = abArgvAs(AB_Comma, id)(((id)->abHdr.tag == (AB_Comma)) ? ((id)->abGen.data.argv
) : &(id))
;
344 Length i, argc = abArgcAs(AB_Comma, id)(((id)->abHdr.tag == (AB_Comma)) ? ((id)->abHdr.argc) :
1)
;
345
346 for (i = 0; i < argc; i += 1)
347 if (!abHasTag(argv[i], AB_Id)((argv[i])->abHdr.tag == (AB_Id)))
348 comsgError(argv[i], ALDOR_E_ChkBadDeclare82);
349}
350
351/*****************************************************************************
352 *
353 * :: abCheckDefine
354 *
355 ****************************************************************************/
356
357/*
358 * Check that the left-hand side is an identifier or
359 * a declaration of a single identifier.
360 */
361localstatic void
362abCheckDefine(AbSyn absyn)
363{
364 AbSyn lhs = absyn->abDefine.lhs;
365 AbSyn *argv = abArgvAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abGen.data.
argv) : &(lhs))
;
366 Length i, argc = abArgcAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abHdr.argc)
: 1)
;
367
368 for (i = 0; i < argc; i += 1) {
369 AbSyn arg = argv[i];
370
371 switch (abTag(arg)((arg)->abHdr.tag)) {
372 case AB_Id:
373 break;
374
375 case AB_Declare:
376 if (abHasTag(lhs, AB_Comma)((lhs)->abHdr.tag == (AB_Comma)) &&
377 abHasTag(arg->abDeclare.id, AB_Comma)((arg->abDeclare.id)->abHdr.tag == (AB_Comma)))
378 comsgError(arg, ALDOR_E_ChkBadDefine83);
379 break;
380
381 default:
382 comsgError(arg, ALDOR_E_ChkBadDefine83);
383 break;
384 }
385 }
386}
387
388/*****************************************************************************
389 *
390 * :: abCheckDDefine
391 *
392 ****************************************************************************/
393
394localstatic void
395abCheckDDefine(AbSyn absyn)
396{
397 AbSyn body = absyn->abDDefine.body;
398 AbSyn *argv = abArgvAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abGen.
data.argv) : &(body))
;
399 Length i, argc = abArgcAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abHdr.
argc) : 1)
;
400
401 for (i = 0; i < argc; i += 1)
402 if (!abHasTag(argv[i], AB_Define)((argv[i])->abHdr.tag == (AB_Define)))
403 comsgError(argv[i], ALDOR_E_ChkBadForm86, "define");
404}
405
406/*****************************************************************************
407 *
408 * :: abCheckExport
409 *
410 ****************************************************************************/
411
412/*
413 * Check that what is exported is a valid specification of exports,
414 * that there is at most one origin or destination,
415 * that the origin is a valid source of exports, and
416 * that the destination is a valid destination for exports.
417 */
418localstatic void
419abCheckExport(AbSyn absyn)
420{
421 AbSyn what = absyn->abExport.what;
422 AbSyn from = absyn->abExport.origin;
423 AbSyn dest = absyn->abExport.destination;
424
425 if (abIsNotNothing(from)!((from)->abHdr.tag == (AB_Nothing)) && abIsNotNothing(dest)!((dest)->abHdr.tag == (AB_Nothing)))
426 comsgError(absyn, ALDOR_E_ChkBadForm86, "export");
427
428 if (abIsNothing(from)((from)->abHdr.tag == (AB_Nothing)) && abIsNothing(dest)((dest)->abHdr.tag == (AB_Nothing)))
429 abCheckOneOrMoreForms(what, "export", abCheckOneDefine);
430 else {
431 if (!abCheckExportCategory(what))
432 comsgError(what, ALDOR_E_ChkBadForm86, "export");
433
434 if (!abCheckExportSource(from))
435 comsgError(from, ALDOR_E_ChkBadForm86, "export");
436
437 if (!abCheckExportTarget(dest))
438 comsgError(dest, ALDOR_E_ChkBadForm86, "export");
439 }
440}
441
442localstatic Bool
443abCheckExportCategory(AbSyn ab)
444{
445 switch (abTag(ab)((ab)->abHdr.tag)) {
446 case AB_Nothing:
447 case AB_Id:
448 case AB_Apply:
449 case AB_Qualify:
450 case AB_Declare:
451 case AB_Sequence:
452 case AB_With:
453 return true1;
454 default:
455 return false((int) 0);
456 }
457}
458
459localstatic Bool
460abCheckExportSource(AbSyn ab)
461{
462 switch (abTag(ab)((ab)->abHdr.tag)) {
463 case AB_Nothing:
464 case AB_Id:
465 case AB_Apply:
466 case AB_Qualify:
467 case AB_Comma:
468 return true1;
469 case AB_PretendTo:
470 return abCheckExportSource(ab->abPretendTo.type);
471 default:
472 return false((int) 0);
473 }
474}
475
476localstatic Bool
477abCheckExportTarget(AbSyn ab)
478{
479 return abIsNothing(ab)((ab)->abHdr.tag == (AB_Nothing)) ||
480 abIsTheId(ab, ssymBuiltin)(((ab)->abHdr.tag == (AB_Id)) && ((ab)->abId.sym
)==(ssymBuiltin))
||
481 abIsApplyOf(ab, ssymForeign)(((ab)->abHdr.tag == (AB_Apply)) && (((((ab)->abApply
.op))->abHdr.tag == (AB_Id)) && ((((ab)->abApply
.op))->abId.sym)==(ssymForeign)))
;
482}
483
484/*****************************************************************************
485 *
486 * :: abCheckExtend
487 *
488 ****************************************************************************/
489
490localstatic void
491abCheckExtend(AbSyn absyn)
492{
493 AbSyn body = absyn->abExtend.body;
494 AbSyn *argv = abArgvAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abGen.
data.argv) : &(body))
;
495 Length i, argc = abArgcAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abHdr.
argc) : 1)
;
496
497 for (i = 0; i < argc; i += 1) {
498 if (abHasTag(argv[i], AB_Define)((argv[i])->abHdr.tag == (AB_Define))) {
499 AbSyn lhs = argv[i]->abDefine.lhs;
500 AbSyn rhs = argv[i]->abDefine.rhs;
501
502 abCheckExtendDeclare(lhs, rhs);
503 }
504 else
505 abCheckExtendDeclare(argv[i], NULL((void*)0));
506 }
507}
508
509localstatic void
510abCheckExtendDeclare(AbSyn lhs, AbSyn rhs)
511{
512 switch (abTag(lhs)((lhs)->abHdr.tag)) {
513 case AB_Id:
514 if (!rhs) comsgError(lhs, ALDOR_E_ChkBadForm86, "extend");
515 break;
516
517 case AB_Declare:
518 break;
519
520 default:
521 comsgError(lhs, ALDOR_E_ChkBadForm86, "extend");
522 break;
523 }
524}
525
526/*****************************************************************************
527 *
528 * :: abCheckFluid
529 *
530 ****************************************************************************/
531
532localstatic void
533abCheckFluid(AbSyn absyn)
534{
535 AbSyn body = absyn->abFluid.argv[0];
536 AbSyn *argv = abArgvAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abGen.
data.argv) : &(body))
;
537 Length i, argc = abArgcAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abHdr.
argc) : 1)
;
538
539 for (i = 0; i < argc; i += 1) {
540 if (abHasTag(argv[i], AB_Assign)((argv[i])->abHdr.tag == (AB_Assign)))
541 abCheckFluidComma(argv[i]->abAssign.lhs);
542 else
543 abCheckFluidComma(argv[i]);
544 }
545}
546
547localstatic void
548abCheckFluidComma(AbSyn lhs)
549{
550 AbSyn *argv = abArgvAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abGen.data.
argv) : &(lhs))
;
551 Length i, argc = abArgcAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abHdr.argc)
: 1)
;
552 Bool isComma = abHasTag(lhs, AB_Comma)((lhs)->abHdr.tag == (AB_Comma));
553
554 for (i = 0; i < argc; i += 1) {
555 AbSyn arg = argv[i];
556
557 switch (abTag(arg)((arg)->abHdr.tag)) {
558 case AB_Id:
559 break;
560
561 case AB_Declare:
562 abCheckFluidDeclare(arg, isComma);
563 break;
564
565 default:
566 comsgError(arg, ALDOR_E_ChkBadForm86, "fluid");
567 break;
568 }
569 }
570}
571
572localstatic void
573abCheckFluidDeclare(AbSyn decl, Bool isComma)
574{
575 AbSyn name = decl->abDeclare.id;
576 AbSyn *argv = abArgvAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abGen.data
.argv) : &(name))
;
577 Length i, argc = abArgcAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abHdr.argc
) : 1)
;
578
579 if (isComma && abHasTag(name, AB_Comma)((name)->abHdr.tag == (AB_Comma)))
580 comsgError(name, ALDOR_E_ChkBadForm86, "fluid");
581
582 for (i = 0; i < argc; i += 1)
583 if (!abHasTag(argv[i], AB_Id)((argv[i])->abHdr.tag == (AB_Id)))
584 comsgError(argv[i], ALDOR_E_ChkBadForm86, "fluid");
585}
586
587/*****************************************************************************
588 *
589 * :: abCheckFor
590 *
591 ****************************************************************************/
592
593/*
594 * Check that the expression following 'for' is an identifier or
595 * a declaration of a single identifier, optionally preceeded
596 * by the keyword 'free'.
597 */
598localstatic void
599abCheckFor(AbSyn absyn)
600{
601 AbSyn lhs = absyn->abFor.lhs;
602
603 if (abHasTag(lhs, AB_Free)((lhs)->abHdr.tag == (AB_Free)) || abHasTag(lhs, AB_Local)((lhs)->abHdr.tag == (AB_Local)))
604 lhs = abArgv(lhs)((lhs)->abGen.data.argv)[0];
605
606 abCheckFor0(lhs);
607}
608
609localstatic void
610abCheckFor0(AbSyn lhs)
611{
612 AbSyn *argv = abArgvAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abGen.data.
argv) : &(lhs))
;
613 Length i, argc = abArgcAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abHdr.argc)
: 1)
;
614
615 for (i = 0; i < argc; i += 1) {
616 AbSyn arg = argv[i];
617
618 switch (abTag(arg)((arg)->abHdr.tag)) {
619 case AB_Id:
620 break;
621
622 case AB_Apply:
623 comsgError(arg, ALDOR_E_ChkBadFor85);
624 break;
625
626 case AB_Declare:
627 if (abHasTag(lhs, AB_Comma)((lhs)->abHdr.tag == (AB_Comma)) &&
628 abHasTag(arg->abDeclare.id, AB_Comma)((arg->abDeclare.id)->abHdr.tag == (AB_Comma)))
629 comsgError(arg, ALDOR_E_ChkBadFor85);
630 break;
631
632 default:
633 comsgError(arg, ALDOR_E_ChkBadFor85);
634 break;
635 }
636 }
637}
638
639localstatic void
640abCheckFor0_old(AbSyn var)
641{
642 switch (abTag(var)((var)->abHdr.tag)) {
643 case AB_Id:
644 break;
645
646 case AB_Declare:
647 if (!abHasTag(var->abDeclare.id, AB_Id)((var->abDeclare.id)->abHdr.tag == (AB_Id)))
648 comsgError(var, ALDOR_E_ChkBadFor85);
649 break;
650
651 default:
652 comsgError(var, ALDOR_E_ChkBadFor85);
653 break;
654 }
655}
656
657/*****************************************************************************
658 *
659 * :: abCheckForeignImport
660 *
661 ****************************************************************************/
662
663localstatic void
664abCheckForeignImport(AbSyn absyn)
665{
666 AbSyn what = absyn->abForeignImport.what;
667 AbSyn *argv = abArgvAs(AB_Sequence, what)(((what)->abHdr.tag == (AB_Sequence)) ? ((what)->abGen.
data.argv) : &(what))
;
668 Length i, argc = abArgcAs(AB_Sequence, what)(((what)->abHdr.tag == (AB_Sequence)) ? ((what)->abHdr.
argc) : 1)
;
669
670
671 /* Are we checking `import Cat from Foreign X' ? */
672 if (abTag(what)((what)->abHdr.tag) == AB_With) return;
673
674
675 /* Standard check of foreign import declarations */
676 for (i = 0; i < argc; i += 1) {
677 switch (abTag(argv[i])((argv[i])->abHdr.tag)) {
678 case AB_Nothing:
679 case AB_Declare:
680 case AB_Define:
681 case AB_DDefine:
682 break;
683
684 default:
685 comsgError(argv[i], ALDOR_E_ChkBadForm86, "import");
686 }
687 }
688}
689
690/*****************************************************************************
691 *
692 * :: abCheckForeignExport
693 *
694 ****************************************************************************/
695
696localstatic void
697abCheckForeignExport(AbSyn absyn)
698{
699 AbSyn what = absyn->abForeignExport.what;
Value stored to 'what' during its initialization is never read
700 AbSyn dest = absyn->abForeignExport.dest;
701 ForeignOrigin forg = forgFrAbSyn(dest->abApply.argv[0]);
702
703 if (forg->protocol == FOAM_Proto_Java
704 && forg->file == NULL((void*)0)) {
705 comsgError(dest, ALDOR_E_ChkMustExportJavaToPackage99, dest);
706 }
707
708 forgFree(forg);
709}
710
711/*****************************************************************************
712 *
713 * :: abCheckImport
714 *
715 ****************************************************************************/
716
717/*
718 * Check that what is imported is a valid specification of exports,
719 * and that the origin of the import is a valid non-empty source of exports.
720 */
721localstatic void
722abCheckImport(AbSyn absyn)
723{
724 AbSyn what = absyn->abImport.what;
725 AbSyn from = absyn->abImport.origin;
726 AbSyn where;
727
728 if (!abCheckExportCategory(what))
729 comsgError(what, ALDOR_E_ChkBadForm86, "import");
730
731 if (abIsNothing(from)((from)->abHdr.tag == (AB_Nothing)) || !abCheckExportSource(from)) {
732 Buffer obuf = bufNew();
733
734 bufPrintf(obuf, comsgString(ALDOR_E_ChkBadForm86), "import");
735
736 if (comsgOkDetails()) {
737 bufPutc(obuf, '\n');
738 bufPrintf(obuf, comsgString(ALDOR_D_ChkUseFromHint96));
739 }
740 where = abIsNothing(what)((what)->abHdr.tag == (AB_Nothing)) ? from : what;
741 comsgError(where, ALDOR_E_ExplicitMsg1, bufChars(obuf));
742 bufFree(obuf);
743 }
744}
745
746/*****************************************************************************
747 *
748 * :: abCheckLambda
749 *
750 ****************************************************************************/
751
752/*
753 * Check that the lambda expression has parameter types and return types,
754 * and ensure that the parameter names are unique.
755 */
756localstatic void
757abCheckLambda(AbSyn absyn)
758{
759 AbSyn param = absyn->abLambda.param;
760 AbSyn rtype = absyn->abLambda.rtype;
761 SymbolList parameters = listNil(Symbol)((SymbolList) 0);
762 Length i;
763
764#if RTYPE
765 if (!rtype)
766 comsgError(absyn, ALDOR_E_ChkMissingRetType95);
767#endif
768 abCheckParam(param);
769
770 for (i = 0; i < abArgc(param)((param)->abHdr.argc); i += 1) {
771 AbSyn pari = abDefineeIdOrElse(abArgv(param)((param)->abGen.data.argv)[i], NULL((void*)0));
772 Symbol sym;
773
774 if (!pari) continue;
775 sym = pari->abId.sym;
776
777 if (listMemq(Symbol)(Symbol_listPointer->Memq)(parameters, sym))
778 comsgError(abArgv(param)((param)->abGen.data.argv)[i], ALDOR_E_ChkBadParamsDups92);
779 else
780 parameters = listCons(Symbol)(Symbol_listPointer->Cons)(sym, parameters);
781 }
782 listFree(Symbol)(Symbol_listPointer->Free)(parameters);
783}
784
785/*****************************************************************************
786 *
787 * :: abCheckReference
788 *
789 ****************************************************************************/
790
791localstatic void
792abCheckReference(AbSyn absyn)
793{
794 AbSyn body = absyn -> abReference.body;
795
796 if (abHasTag(body, AB_Id)((body)->abHdr.tag == (AB_Id)))
797 return;
798 else if (abHasTag(body, AB_Apply)((body)->abHdr.tag == (AB_Apply)))
799 {
800 /* Can applications have non-ID operators? */
801 body = body -> abApply.op;
802 if (abHasTag(body, AB_Id)((body)->abHdr.tag == (AB_Id)))
803 return;
804 }
805
806
807 /* We don't like this form */
808 comsgError(absyn, ALDOR_E_ChkBadForm86, "ref");
809}
810
811/*****************************************************************************
812 *
813 * :: abCheckParam
814 *
815 ****************************************************************************/
816
817localstatic void
818abCheckParam(AbSyn absyn)
819{
820 AbSyn *argv = abArgvAs(AB_Comma, absyn)(((absyn)->abHdr.tag == (AB_Comma)) ? ((absyn)->abGen.data
.argv) : &(absyn))
;
821 Length i, argc = abArgcAs(AB_Comma, absyn)(((absyn)->abHdr.tag == (AB_Comma)) ? ((absyn)->abHdr.argc
) : 1)
;
822
823 if (!abHasTag(absyn, AB_Comma)((absyn)->abHdr.tag == (AB_Comma)))
824 comsgError(absyn, ALDOR_E_ChkBadParams91);
825
826 for (i = 0; i < argc; i += 1) {
827 if (abHasTag(argv[i], AB_Define)((argv[i])->abHdr.tag == (AB_Define)))
828 abCheckParamDefine(argv[i]->abDefine.lhs);
829 else
830 abCheckParamDefine(argv[i]);
831 }
832}
833
834localstatic void
835abCheckParamDefine(AbSyn lhs)
836{
837 if (!abHasTag(lhs, AB_Declare)((lhs)->abHdr.tag == (AB_Declare)))
838 comsgError(lhs, ALDOR_E_ChkBadParams91);
839}
840
841/*****************************************************************************
842 *
843 * :: abCheckSelect
844 *
845 ****************************************************************************/
846
847localstatic void
848abCheckSelect(AbSyn absyn)
849{
850 AbSyn seq;
851 int i;
852
853 seq = absyn->abSelect.alternatives;
854 if (!abHasTag(seq, AB_Sequence)((seq)->abHdr.tag == (AB_Sequence)))
855 comsgError(absyn, ALDOR_E_ChkSelectSeq97);
856
857 for (i = 0; i<abArgc(seq)((seq)->abHdr.argc); i++) {
858 if (!abHasTag(seq->abSequence.argv[i], AB_Exit)((seq->abSequence.argv[i])->abHdr.tag == (AB_Exit)))
859 break;
860 }
861 for ( ; i<abArgc(seq)((seq)->abHdr.argc); i++) {
862 if (abHasTag(seq->abSequence.argv[i], AB_Exit)((seq->abSequence.argv[i])->abHdr.tag == (AB_Exit)))
863 comsgError(absyn, ALDOR_E_ChkSelectExits98);
864 }
865}
866
867/*****************************************************************************
868 *
869 * :: abCheckWhere
870 *
871 ****************************************************************************/
872
873/*
874 * Look for improper exits from the context of a where clause.
875 */
876localstatic void
877abCheckWhere(AbSyn absyn)
878{
879 AbSyn ctxt = absyn->abWhere.context;
880 Length i, argc = abArgcAs(AB_Sequence, ctxt)(((ctxt)->abHdr.tag == (AB_Sequence)) ? ((ctxt)->abHdr.
argc) : 1)
;
881 AbSyn *argv = abArgvAs(AB_Sequence, ctxt)(((ctxt)->abHdr.tag == (AB_Sequence)) ? ((ctxt)->abGen.
data.argv) : &(ctxt))
;
882
883 for (i = 0; i < argc; i += 1) {
884 AbSyn arg = argv[i];
885 if (abHasTag(arg, AB_Exit)((arg)->abHdr.tag == (AB_Exit))) {
886 comsgError(arg, ALDOR_E_ChkBadForm86, "where");
887 break;
888 }
889 }
890}
891
892/******************************************************************************
893 *
894 * :: abCheckFree
895 * :: abCheckLocal
896 *
897 *****************************************************************************/
898
899localstatic void
900abCheckFree(AbSyn absyn)
901{
902 abCheckLOF(absyn->abFree.argv[0], "free");
903}
904
905localstatic void
906abCheckLocal(AbSyn absyn)
907{
908 abCheckLOF(absyn->abLocal.argv[0], "local");
909}
910
911localstatic void
912abCheckLOF(AbSyn body, String context)
913{
914 AbSyn *argv = abArgvAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abGen.
data.argv) : &(body))
;
915 Length i, argc = abArgcAs(AB_Sequence, body)(((body)->abHdr.tag == (AB_Sequence)) ? ((body)->abHdr.
argc) : 1)
;
916
917 for (i = 0; i < argc; i += 1) {
918 AbSyn arg = argv[i];
919
920 switch (abTag(arg)((arg)->abHdr.tag)) {
921 case AB_Id:
922 case AB_Declare:
923 case AB_Comma:
924 abCheckLOFComma(arg, context);
925 break;
926
927 case AB_Assign:
928 abCheckLOFComma(arg->abAssign.lhs, context);
929 abCheckAssign(arg);
930 break;
931
932 case AB_Define:
933 abCheckLOFComma(arg->abDefine.lhs, context);
934 abCheckDefine(arg);
935 break;
936
937 default:
938 comsgError(arg, ALDOR_E_ChkBadForm86, context);
939 break;
940 }
941 }
942}
943
944localstatic void
945abCheckLOFComma(AbSyn lhs, String context)
946{
947 AbSyn *argv = abArgvAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abGen.data.
argv) : &(lhs))
;
948 Length i, argc = abArgcAs(AB_Comma, lhs)(((lhs)->abHdr.tag == (AB_Comma)) ? ((lhs)->abHdr.argc)
: 1)
;
949 Bool isComma = abHasTag(lhs, AB_Comma)((lhs)->abHdr.tag == (AB_Comma));
950
951 for (i = 0; i < argc; i += 1) {
952 AbSyn arg = argv[i];
953
954 switch (abTag(arg)((arg)->abHdr.tag)) {
955 case AB_Id:
956 break;
957
958 case AB_Declare:
959 abCheckLOFDeclare(arg, isComma, context);
960 break;
961
962 default:
963 comsgError(arg, ALDOR_E_ChkBadForm86, context);
964 break;
965 }
966 }
967}
968
969localstatic void
970abCheckLOFDeclare(AbSyn decl, Bool isComma, String context)
971{
972 AbSyn name = decl->abDeclare.id;
973 AbSyn *argv = abArgvAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abGen.data
.argv) : &(name))
;
974 Length i, argc = abArgcAs(AB_Comma, name)(((name)->abHdr.tag == (AB_Comma)) ? ((name)->abHdr.argc
) : 1)
;
975
976 if (isComma && abHasTag(name, AB_Comma)((name)->abHdr.tag == (AB_Comma)))
977 comsgError(name, ALDOR_E_ChkBadForm86, context);
978
979 for (i = 0; i < argc; i += 1)
980 if (!abHasTag(argv[i], AB_Id)((argv[i])->abHdr.tag == (AB_Id)))
981 comsgError(argv[i], ALDOR_E_ChkBadForm86, context);
982}
983
984/*****************************************************************************
985 *
986 * abCheck helper functions.
987 *
988 ****************************************************************************/
989
990localstatic void
991abCheckOneOrMoreForms(AbSyn ab, String str, AbCheckFn check)
992{
993 int i;
994
995 switch (abTag(ab)((ab)->abHdr.tag)) {
996 case AB_Nothing:
997 break;
998
999 case AB_Comma:
1000 case AB_Sequence:
1001 for (i = 0; i < abArgc(ab)((ab)->abHdr.argc); i += 1)
1002 abCheckOneOrMoreForms(abArgv(ab)((ab)->abGen.data.argv)[i], str, check);
1003 break;
1004
1005 default:
1006 check(ab, str);
1007 }
1008}
1009
1010localstatic void
1011abCheckOneDefine(AbSyn ab, String str)
1012{
1013 if (abHasTag(ab, AB_Define)((ab)->abHdr.tag == (AB_Define)))
1014 ab = ab->abDefine.lhs;
1015
1016 if (!abHasTag(ab, AB_Declare)((ab)->abHdr.tag == (AB_Declare)))
1017 comsgError(ab, ALDOR_E_ChkBadForm86, str);
1018}
1019
1020localstatic void
1021abCheckWithin(AbSyn ab, String str)
1022{
1023 int i;
1024
1025 switch (abTag(ab)((ab)->abHdr.tag)) {
1026 case AB_Id:
1027 case AB_Declare:
1028 abCheckWithinDeclare(ab, str);
1029 case AB_Default:
1030 case AB_Import:
1031 case AB_Export:
1032 case AB_Apply:
1033 case AB_RestrictTo:
1034 break;
1035
1036 case AB_If:
1037 abCheckOneOrMoreForms(ab->abIf.thenAlt, str, abCheckWithin);
1038 abCheckOneOrMoreForms(ab->abIf.elseAlt, str, abCheckWithin);
1039 break;
1040
1041 case AB_Sequence:
1042 for (i=0; i<abArgc(ab)((ab)->abHdr.argc); i++)
1043 abCheckOneOrMoreForms(ab->abSequence.argv[i], str, abCheckWithin);
1044 break;
1045
1046 default:
1047 comsgError(ab, ALDOR_E_ChkBadForm86, str);
1048 break;
1049 }
1050}
1051
1052localstatic void
1053abCheckWithinDeclare(AbSyn ab, String str)
1054{
1055 AbSyn id = ab->abDeclare.id;
1056
1057 if (abTag(id)((id)->abHdr.tag) != AB_Id) {
1058 comsgError(ab, ALDOR_E_ChkBadForm86, str);
1059 }
1060}