Pristine Ack-5.5
[Ack-5.5.git] / doc / lint / chap4
1 .NH 1
2 How lint checks
3 .NH 2
4 The first pass first pass data structure
5 .PP
6 The data structure of
7 .I cem
8 is changed a little and some structures have been added.
9 .NH 3
10 The changes
11 .NH 4
12 Idf descriptor
13 .PP
14 A member
15 .ft CW
16 id_line
17 .R
18 is added
19 to the
20 .I idf
21 selector.
22 This line number is used for some warnings.
23 .NH 4
24 Def descriptor
25 .PP
26 The
27 .I def
28 selector is extended with the members
29 .ft CW
30 df_set
31 .R and
32 df_line.
33 .R
34 The
35 .ft CW
36 df_used
37 .R
38 member did exist already, but was only used for code generation.
39 This usage is eliminated so it can be used by
40 .I lint.
41 The meaning of these members should be clear.
42 .NH 3
43 The additions
44 .NH 4
45 Lint_stack_entry descriptor
46 .DS B
47 .ft CW
48 struct lint_stack_entry {
49         struct lint_stack_entry *next;
50         struct lint_stack_entry *previous;
51         short ls_class;
52         int ls_level;
53         struct state *ls_current;
54         union {
55                 struct state *S_if;
56                 struct state *S_end;
57                 struct switch_states switch_state;
58         } ls_states;
59 };
60 .R
61 .DE
62 .PP
63 Structure to simulate a stacking mechanism.
64 .IP \f(CWnext\fP 15
65 Pointer to the entry on top of this one.
66 .IP \f(CWprevious\fP
67 Pointer to the entry beneath this one.
68 .IP \f(CWls_class\fP
69 The class of statement this entry belongs to.
70 Possible classes are \f(CWIF\fP, \f(CWWHILE\fP, \f(CWDO\fP,
71 \f(CWFOR\fP, \f(CWSWITCH\fP and \f(CWCASE\fP.
72 .IP \f(CWls_level\fP
73 The level the corresponding statement is nested.
74 .IP \f(CWls_current\fP
75 A pointer to the state descriptor which describes the state
76 of the function (the state of the automatic variables, if the next
77 statement can be reached, et cetera) if control passes the
78 flow of control to the part of the program currently parsed.
79 The initialization of this state is as follows
80 .RS
81 .IP
82 If \f(CWls_class\fP in [\f(CWIF\fP, \f(CWSWITCH\fP] the state
83 after parsing the conditional expression.
84 .IP
85 If \f(CWls_class\fP in [\f(CWWHILE\fP, \f(CWFOR\fP] the state
86 after parsing the code between the brackets.
87 .IP
88 If \f(CWls_class\fP in [\f(CWDO\fP, \f(CWCASE\fP] the state at
89 entrance of the statement after the \f(CWDO\fP or \f(CWCASE\fP
90 token.
91 .RE
92 .IP \f(CWls_states\fP 15
93 Union of pointers to state descriptors containing different information
94 for different values of \f(CWls_class\fP.
95 .RS
96 .IP
97 If \f(CWls_class\fP is \f(CWIF\fP and in case of parsing an else part,
98 \f(CWls_states.S_if\fP points to the state that is reached after the
99 if part.
100 .IP
101 If \f(CWls_class\fP in [\f(CWWHILE\fP, \f(CWFOR\fP, \f(CWDO\fP]
102 then \f(CWls_states.S_end\fP contains a conservative description
103 of the state of the program after `jumping'
104 to the end of the statement after the \f(CWWHILE\fP, \f(CWDO\fP
105 or \f(CWFOR\fP token.
106 I.e. the state at reaching a break (not inside a switch) or
107 continue statement.
108 .IP
109 If ls_class is \f(CWSWITCH\fP, \f(CWls_states\fP is used as a structure
110 .DS B
111 .ft CW
112 struct switch_states {
113         struct state S_case;
114         struct state S_break;
115 };
116 .R
117 .DE
118 containing two pointers to state descriptors.
119 \f(CWls_states.switch_state.S_case\fP contains
120 a conservative description
121 of the state of the program after \f(CWcase ... case\fP
122 parts are parsed.
123 \f(CWls_states.switch_state.S_break\fP the state after parsing
124 all the \f(CWcase ... break\fP parts.
125 The reason for \f(CWls_states.switch_state.default_met\fP should be
126 self-explanatory.
127 .IP
128 In case \f(CWls_class\fP is \f(CWCASE\fP, \f(CWls_states\fP is not used.
129 .RE
130 .NH 4
131 State descriptor
132 .DS B
133 .ft CW
134 struct state {
135         struct state *next;
136         struct auto_def *st_auto_list;
137         int st_nrchd;
138         int st_warned;
139 };
140 .R
141 .DE
142 .IP \f(CWst_auto_list\fP 15
143 Pointer to a list of definitions of the automatic variables whose
144 scope contain the current position in the program.
145 .IP \f(CWst_nrchd\fP
146 True if the next statement can't be reached.
147 .IP \f(CWst_warned\fP
148 True if a warning has already been given.
149 .NH 4
150 Auto_def descriptor
151 .DS B
152 .ft CW
153 struct auto_def {
154         struct auto_def *next;
155         struct idf *ad_idf;
156         struct def *ad_def;
157         int ad_used;
158         int ad_set;
159         int ad_maybe_set;
160 };
161 .R
162 .DE
163 .IP \f(CWnext\fP 15
164 Points to the next auto_definition of the list.
165 .IP \f(CWad_idf\fP
166 Pointer to the idf descriptor associated with this auto_definition.
167 .IP \f(CWad_def\fP
168 Ditto for def descriptor.
169 .IP \f(CWad_used\fP
170 Indicates the state of this automatic variable.
171 Ditto for \f(CWad_set\fP and \f(CWad_maybe_set\fP.
172 Only one of \f(CWad_set\fP and \f(CWad_maybe_set\fP may be true.
173 .NH 4
174 Expr_state descriptor
175 .DS B
176 .ft CW
177 struct expr_state {
178         struct expr_state *next;
179         struct idf *es_idf;
180         arith es_offset;
181         int es_used;
182         int es_set;
183 };
184 .R
185 .DE
186 .PP
187 This structure is introduced to keep track of which variables,
188 array entries and structure members (union members) are set
189 and/or used in evaluating an expression.
190 .IP \f(CWnext\fP 15
191 Pointer to the next descriptor of this list.
192 .IP \f(CWes_idf\fP
193 Pointer to the idf descriptor this descriptor belongs to.
194 .IP \f(CWes_offset\fP
195 In case of an array, a structure or union, this member contains
196 the offset the compiler would generate for locating the array
197 entry or structure/union member.
198 .IP \f(CWes_used\fP
199 True if the indicated memory location is used in evaluating the
200 expression.
201 .IP \f(CWes_set\fP
202 Ditto for set.
203 .NH 4
204 Outdef descriptor
205 .DS B
206 .ft CW
207 struct outdef {
208         int od_class;
209         char *od_name;
210         char *od_file;
211         unsigned int od_line;
212         int od_nrargs;
213         struct tp_entry *od_entry;
214         int od_returns;
215         struct type *od_type;
216 };
217 .DE
218 .R
219 .PP
220 As structures of this type are not allocated dynamically by a
221 storage allocator, it contains no next member.
222 An outdef can be given to to \f(CWoutput_def()\fP to be passed to the
223 second pass.
224 Basically this forms the interface with the second pass.
225 .IP \f(CWod_class\fP 15
226 Indicates what kind of definition it is.
227 Possible classes are \f(CWEFDF\fP, \f(CWEVDF\fP, \f(CWSFDF\fP,
228 \f(CWSVDF\fP, \f(CWLFDF\fP, \f(CWLVDF\fP,
229 \f(CWEFDC\fP, \f(CWEVDC\fP, \f(CWIFDC\fP, \f(CWFC\fP, \f(CWVU\fP.
230 ([\f(CWE\fPxternal, \f(CWS\fPtatic, \f(CWL\fPibrary, \f(CWI\fPmplicit]
231 [\f(CWF\fPunction, \f(CWV\fPariable]
232 [\f(CWD\fPe\f(CWF\fPinition, \f(CWD\fPe\f(CWC\fPlaration,
233 \f(CWC\fPall, \f(CWU\fPsage])
234 .IP \f(CWod_name\fP
235 The name of the function or variable.
236 .IP \f(CWod_file\fP
237 The file this definition comes from.
238 .IP \f(CWod_nrargs\fP
239 If \f(CWod_class\fP is one of \f(CWEFDF\fP, \f(CWSFDF\fP or
240 \f(CWLFDF\fP, this member contains the
241 number of arguments this function has.
242 If the function was preceded by the pseudocomment
243 \f(CW/*\ VARARGS\ */\fP,
244 \f(CWod_nrargs\fP gets the value \f(CW-1-n\fP.
245 .IP \f(CWod_entry\fP
246 A pointer to a list of \f(CWod_nrargs\fP cells, each containing a
247 pointer to the type descriptor of an argument. (\f(CW-1-od_nrargs\fP
248 cells if
249 \f(CWod_nrargs < 0\fP.)
250 \f(CWTp_entry\fP is defined as
251 .DS B
252 .ft CW
253 struct tp_entry {
254         struct tp_entry *next; /* pointer to next cell */
255         struct type *te_type;  /* an argument type     */
256 };
257 .R
258 .DE
259 .IP \f(CWod_returns\fP 15
260 For classes \f(CWEFDF\fP, \f(CWSFDF\fP and \f(CWLFDF\fP this
261 member tells if the function returns an expression or not.
262 In case \f(CWod_class\fP is \f(CWFC\fP it is true if the value
263 of the function is used, false otherwise.
264 For other classes this member is not used.
265 .IP \f(CWod_type\fP
266 A pointer to the type of the function or variable defined or
267 declared.
268 Not used for classes \f(CWFC\fP and \f(CWVU\fP.
269 .NH 2
270 The first pass checking mechanism
271 .PP
272 In the description of the implementation of the pass one 
273 warnings, it is assumed that the reader is familiar with the
274 \fILLgen\fP parser generator, as described in [6].
275 .NH 3
276 Used and/or set variables
277 .PP
278 To be able to give warnings like
279 .ft CW
280 %s used before set
281 .R
282 and
283 .ft CW
284 %s set but not used in function %s
285 .R
286 , there needs to be a way to keep track of the state of a variable.
287 A first approach to do this was by adding two fields to the
288 \fIdef\fP selector: 
289 .ft CW
290 df_set
291 .R
292 and
293 .ft CW
294 df_used.
295 .R
296 While parsing the program, each time an expression was met
297 this expression was analyzed and the fields of each \fIdef\fP
298 selector were possibly set during this analysis.
299 This analysis was done by passing each expression to a
300 function 
301 .ft CW
302 lint_expr
303 .R
304 , which walks the expression tree in a way similar to the function
305 \f(CWEVAL\fP in the file \fIeval.c\fP of the original
306 .I
307 cem
308 .R
309 compiler.
310 This approach has one big disadvantage: it is impossible to keep
311 track of the flow of control of the program.
312 No warning will be given for the program fragment of figure 3.
313 .KF
314 .DS B
315 .ft CW
316 func()
317 {
318         int i;
319
320         if (cond)
321                 i = 0;
322         else
323                 use(i);  /* i may be used before set */
324 }
325 .I
326 .DE
327 .br
328 .ce
329 figure\ 3.
330 .R
331 .KE
332 .PP
333 It is clear that it would be nice having
334 .I lint
335 warn for this construction.
336 .PP
337 This was done in the second approach.
338 When there was a choice between two statements, each statement
339 was parsed with its own copy of the state at entrance of the
340 .I
341 choosing statement.
342 .R
343 A state consisted of the state of the automatic variables
344 (including register variables).
345 In addition to the possibilities of being used and set,
346 a variable could be \fImaybe set\fP.
347 These states were passed between the statement parsing routines
348 using the \fILLgen\fP parameter mechanism.
349 At the end of a choosing statement, the two states were merged
350 into one state, which became the state after this statement.
351 The construction of figure 4 was now detected, but switch
352 statements still gave problems and continue and break statements
353 were not understood.
354 The main problem of a switch statement is, that the closing bracket
355 (`\f(CW)\fP') has to be followed by a \fIstatement\fP.
356 The syntax shows no choice of statements, as is the case with
357 if, while, do and for statements.
358 Using the \fILLgen\fP parameter mechanism, it is not a trivial
359 task to parse the different case parts of a switch statement
360 with the same initial state and to merge the results into one
361 state.
362 This observation led to the third and final approach, as described
363 next.
364 .PP
365 Instead of passing the state of the program through the statements
366 parsing routines using the \fILLgen\fP parameters, a special stack is
367 introduced, the
368 .I lint_stack.
369 When a choosing statement is parsed, an entry is pushed on the stack
370 containing the information that is needed to keep track of the
371 state of the program.
372 Each entry contains a description of the
373 .I current
374 state of the program and a field that indicates what part of the
375 program the parser is currently parsing.
376 For all the possible choosing statements I describe the actions
377 to be taken.
378 .PP
379 At entrance of an if statement, an entry is pushed on the stack
380 with the current state being a copy of the current state of the
381 stack element one below.
382 The class of this entry is \f(CWIF\fP.
383 At reaching the else part, the current state is moved to
384 another place in this stack entry (to \f(CWS_IF\fP), and a new copy
385 of the current state at entrance of this if statement is made.
386 At the end of the else part, the two states are merged into
387 one state, the new current state, and the \f(CWIF\fP entry is
388 popped from the stack.
389 If there is no else part, then the state that is reached after
390 parsing the if part is merged with the current state at entrance
391 of the if statement into the new current state.
392 .PP
393 At entrance of a while statement a \f(CWWHILE\fP entry is pushed
394 on the stack containing a copy of the current state.
395 If a continue or break statement is met in the while statement,
396 the state at reaching this continue or break statement is
397 merged with a special state in the \f(CWWHILE\fP entry, called
398 \f(CWS_END\fP.
399 (If \f(CWS_END\fP did not yet contain a state, the state is copied
400 to \f(CWS_END\fP.)
401 At the end of the while statement this \f(CWS_END\fP is merged with the 
402 current state, which result is merged with the state at entrance
403 of the while statement into the new current state.
404 .PP
405 A for statement is treated similarly.
406 A do statement is treated the same way too, except that \f(CWS_END\fP
407 isn't merged with the state at entrance of the do statement,
408 but becomes the new current state.
409 .PP
410 For switch statements a \f(CWSWITCH\fP entry is pushed on the stack.
411 Apart from the current state, this entry contains two other
412 states, \f(CWS_BREAK\fP and \f(CWS_CASE\fP.
413 \f(CWS_BREAK\fP initially contains no state, \f(CWS_CASE\fP
414 initially contains a
415 copy of the current state at entrance of the switch statement.
416 After parsing a case label, a \f(CWCASE\fP entry is pushed on the stack,
417 containing a copy of the current state.
418 If, after zero or more statements, we meet another case label,
419 the state at reaching this case label is merged with \f(CWS_CASE\fP
420 of the \f(CWSWITCH\fP entry below and a new copy of the state
421 at entrance
422 of the switch statement is put in the \f(CWCASE\fP entry.
423 If we meet a break statement, we merge the current state with
424 \f(CWS_BREAK\fP of the \f(CWSWITCH\fP entry below and pop the
425 \f(CWCASE\fP entry.
426 In addition to this, the occurrence of a default statement
427 inside the switch statement is recorded in the \f(CWSWITCH\fP entry.
428 At the end of the switch statement we check if we have met a
429 default statement.
430 If not, \f(CWS_BREAK\fP is merged with the current state at entrance
431 of the switch statement. (Because it is possible that no case
432 label will be chosen.)
433 Next the \f(CWS_CASE\fP is `special_merged' with \f(CWS_BREAK\fP
434 into the new current state.
435 For more details about these merge functions see the sources.
436 .PP
437 With the approach described above, 
438 .I lint
439 is aware of the flow
440 of control in the program.
441 There still are some doubtful constructions
442 .I lint
443 will not detect and there are some constructions (although rare)
444 for which
445 .I lint
446 gives an incorrect warning (see figure 4).
447 .KF
448 .DS B
449 .ft CW
450 {
451         int i;
452
453         for (;;) {
454                 if (cond) {
455                         i = 0;
456                         break;
457                 }
458         }
459         use(i);
460         /* lint warns: maybe i used before set
461          * although  the  fragment  is correct
462          */
463 }
464 .DE
465 .br
466 .I
467 .ce
468 figure\ 4.
469 .R
470 .KE
471 .PP
472 A nice advantage of the method is, that the parser stays clear,
473 i.e. it isn't extended with extra parameters which must pass the
474 states.
475 In this way the parser still is very readable and we have a nice
476 interface with
477 .I lint
478 using function calls.
479 .NH 3
480 Undefined evaluation orders
481 .PP
482 In expressions the values of some variables are used and some
483 variables are set.
484 Of course, the same holds for subexpressions.
485 The compiler is allowed to choose the order of evaluation of
486 subexpressions involving a commutative and associative operator
487 (\f(CW*\fP, \f(CW+\fP, \f(CW&\fP, \f(CW|\fP, \f(CW^\fP),
488 the comma in a parameter list or an assignment operator.
489 In section 3.4 it is made clear that this will lead to
490 statements with ambiguous semantics.
491 .PP
492 The way these constructs are detected is rather straight forward.
493 The function which parses an expression (\f(CWlint_expr\fP)
494 returns a linked
495 list containing information telling which variables are set and
496 which variables are used.
497 A variable is indicated by its
498 .I idf
499 descriptor and an
500 .I offset.
501 This offset is needed for discriminating entries of the same
502 array and members of the same structure or union, so it is
503 possible to warn about the statement
504 .ft CW
505 a[b[0]]\ =\ b[0]++;.
506 .R
507 When \f(CWlint_expr\fP meets a commutative operator (with respect to the
508 evaluation order), it calls itself recursively with the operands
509 of the operator as expression.
510 The returned results are checked for undefined evaluation orders
511 and are put together.
512 This is done by the function \f(CWcheck_and_merge\fP.
513 .NH 3
514 Useless statements
515 .PP
516 Statements which compute a value that is not used,
517 are said to have a \fInull effect\fP.
518 Examples are \f(CWx = 2, 3;\fP, \f(CWf() + g();\fP and
519 \f(CW*p++;\fP.
520 (\f(CW*\fP and \f(CW++\fP have the same precedence and associate
521 from right to left.)
522 .PP
523 A conditional expression computes a value too.
524 If this value isn't used, it is better to use an if-else
525 statement.
526 So, if
527 .I lint
528 sees
529 .DS B
530 .ft CW
531 b ? f() : g();
532 .R
533 .DE
534 .LP
535 it warns \f(CWuse if-else construction\fP.
536 .NH 3
537 Not-reachable statements
538 .PP
539 The algorithm to detect not-reachable statements (including not
540 reachable initializations) is as follows.
541 Statements after a label and a case statement and the compound
542 statement of a function are always reachable.
543 Other statements are not-reachable after:
544 .QS
545 .RS
546 .IP - 1
547 a goto statement
548 .IP -
549 a return statement
550 .IP -
551 a break statement
552 .IP -
553 a continue statement
554 .IP -
555 a switch statement
556 .IP -
557 an endless loop (a while, do or for loop with a conditional
558 which always evaluates to true and without a break statement)
559 .IP -
560 an if-else statement of which both if part and else part
561 end up in a not-reachable state
562 .IP -
563 a switch statement of which all \f(CWcase ... break\fP parts
564 (including
565 a \f(CWdefault ... break\fP part) end up in a not-reachable state
566 .IP -
567 the pseudocomment \f(CW/*\ NOTREACHED\ */\fP
568 .RE
569 .QE
570 .PP
571 The algorithm is easily implemented using the \f(CWst_nrchd\fP selector
572 in the
573 .I state
574 descriptor.
575 The \f(CWst_warned\fP selector is used to prevent superfluous warnings.
576 To detect an endless loop, after a while (<true>), for (..;<true>;..)
577 and do part the current state of the stack entry beneath the top one
578 is set to not reached.
579 If, in the statement following, a break statement is met, this same
580 state is set to reached.
581 If the while (<cond>) part of the do statement is met, this state
582 is set to reached if <cond> doesn't evaluates to true.
583 The detection of not-reachable statements after a switch statement
584 is done in a similar way.
585 In addition it is checked if a default statement isn't met, in
586 which case the statement after the switch statement can be reached.
587 The warning \f(CWstatement not reached\fP is not given for compound
588 statements.
589 If
590 .I lint
591 did, it would warn for the compound statement in a switch statement,
592 which would be incorrect.
593 .PP
594 Not-reachable statements are still interpreted by
595 .I lint.
596 I.e. when
597 .I lint
598 warns that some statement can't be reached, it assumes this is
599 not what the programmer really wants and it ignores this fact.
600 In this way a lot of useless warnings are prevented in the case of
601 a not-reachable statement.
602 See figure 5.
603 .KF
604 .DS B
605 .ft CW
606 {
607         int i;
608
609         for (;;) {
610                 /* A loop in which the programmer
611                  * forgot to introduce a conditional
612                  * break statement.
613                  * Suppose i is not used in this part.
614                  */
615         }
616         /* some more code in which i is used */
617 }
618 /* The warning "statement not reached" highlights the bug.
619  * An additional warning "i unused in function %s" is 
620  * formally correct, but doesn't provide the programmer
621  * with useful information.
622  */
623 .DE
624 .I
625 .ce
626 figure\ 5.
627 .R
628 .KE
629 .NH 3
630 Functions returning expressions and just returning
631 .PP
632 Each time a return statement is met,
633 .I lint
634 checks if an expression is returned or not.
635 If a function has a return with expression and a return without
636 expression,
637 .I lint
638 warns
639 .ft CW
640 function %s has return(e); and return;.
641 .R
642 If the flow of control can
643 .I
644 fall through
645 .R
646 the end of the compound statement of a function, this indicates
647 an implicit return statement without an expression.
648 If the end of the compound statement of the function can be reached,
649 .I lint
650 introduces this implicit return statement without expression.
651 .PP
652 Sometimes the programmer knows for sure that all case parts inside
653 a switch statement include all possible cases, so he doesn't
654 introduce a default statement.
655 This can lead to an incorrect warning.
656 Figure 6 shows how to prevent this warning.
657 .KF
658 .DS B
659 .ft CW
660             func()
661             {
662                     switch (cond) {
663                     case 0: return(e0);
664                     case 1: return(e1);
665                     }
666                     /* NOTREACHED */
667             }
668 /* no warning: "function func has return(e); and return; */
669 .DE
670 .I
671 .ce
672 figure\ 6.
673 .R
674 .KE
675 .PP
676 The pseudocomment \f(CW/*\ NOTREACHED\ */\fP can also be used to tell
677 .I lint
678 that some function doesn't return. See figure 7.
679 .KS
680 .DS B
681 .ft CW
682   func()
683   {
684           switch (cond) {
685           case 0: return(e0);
686           case 1: return(e1);
687           default: error();   /* calls exit or abort */
688                    /* NOTREACHED */
689           }
690   }
691 /* no warning: "function func has return(e); and return;" */
692 .I
693 .DE
694 .ce
695 figure\ 7.
696 .R
697 .KE
698 .NH 3
699 Output definitions for the second pass
700 .PP
701 The first pass can only process one program file.
702 To be able to process a program that spreads over more than one file,
703 the first pass outputs definitions that are processed by a second
704 pass.
705 The format of such a definition is different for different classes:
706 .PP
707 For class in {EFDF, SFDF, LFDF}
708 .DS C
709 <name>:<class>:<file>:<line>:<nr of args>:<type of args>:<returns value>:<type>
710 .DE
711 .LP
712 A negative \fInr of args\fP indicates that the function can be called with
713 a varying number of arguments.
714 .PP
715 For class = FC
716 .DS C
717 <name>:<class>:<file>:<line>:<value is used>:<type>
718 .DE
719 .LP
720 The \fIvalue is used\fP part can have three meanings:
721 the value of the function is ignored;
722 the value of the function is used;
723 the value of the function is cast to type \fIvoid\fP.
724 .PP
725 For other classes
726 .DS C
727 <name>:<class>:<file>:<line>:<type>
728 .DE
729 .LP
730 Definitions of class VU (Variable Usage) are only output for \fIused\fP
731 global variables.
732 .PP
733 Structure and union types that are output to the intermediate file
734 are simplified.
735 (The following occurrences of \fIstructure\fP should be
736 read as \fIstructure or union\fP and \fIstruct\fP as \fIstruct or
737 union\fP.)
738 Structures that are identified by a \fIstructure tag\fP are output
739 to the intermediate file as \f(CWstruct <tag>\fP.
740 Structures without a structure tag are output as
741 \f(CWstruct {<mems>}\fP with \f(CW<mems>\fP a semicolon-separated
742 list of types of the members of this structure.
743 An alternative way would be to output the complete structure definition.
744 However, this gives practical problems.
745 It is allowed to define some object of a structure type with a
746 structure tag, without this structure being defined at that place.
747 The first approach leaves errors, such as in figure 8, undetected.
748 .KF
749 .DS B
750 .ft CW
751     "a.c"                           "b.c"
752
753 struct str {                    struct str {
754         float f;                        int i;
755 } s;                            };
756
757 main()                          func(s)
758 {                                       struct str s;
759         func(s);                {}
760 }
761 .I
762 .DE
763 .ce
764 figure\ 8.
765 .R
766 .KE
767 .PP
768 To be able to detect these errors, the first pass should also output
769 definitions of structure tags.
770 The example of figure 8 would then get a warning like
771 .ft CW
772 structure str defined inconsistently
773 .R
774 .PP
775 More information on these definitions in section 4.3 and 4.4.
776 .NH 3
777 Generating libraries
778 .PP
779 .I Lint
780 knows the library `-lc', `-lm' and `-lcurses'.
781 If a program uses some other library, it is possible to generate
782 a corresponding \fIlint library\fP.
783 To do this, precede all the C source files of this library by
784 the pseudocomment \f(CW/*\ LINTLIBRARY\ */\fP.
785 Then feed these files one by one to the first pass of
786 .I lint
787 collecting the standard output in a file and ignoring the warnings.
788 The resulting file contains library definitions of the functions
789 and external variables defined in the library sources, and not more
790 than that.
791 If this file is called `llib-l\fIname\fP.ln
792 .I lint
793 can be told to search the library by passing it as argument in
794 the command line `-llib-l\fIname\fP.ln.
795 The implementation of this feature is simple.
796 .PP
797 As soon as the pseudocomment \f(CW/*\ LINTLIBRARY\ */\fP is met,
798 only function and variable definitions are output with class LFDF
799 and LVDF respectively.
800 Other definitions, which otherwise would have been output, are
801 discarded.
802 .PP
803 Instead of generating a special lint library file, one can make a
804 file containing the library definitions and starting with
805 \f(CW/* LINTLIBRARY */\fP.
806 This file can then be passed to
807 .I lint
808 just by its name.
809 This method isn't as efficient as the first one.
810 .NH 3
811 Interpreting the pseudocomments
812 .PP
813 The interpretation of the pseudocomments is done by the lexical
814 analyzer, because this part of the program already took care of the
815 comments. 
816 At first sight this seems very easy: as soon as some pseudocomment
817 is met, raise the corresponding flag.
818 Unfortunately this doesn't work.
819 The lexical analyzer is a \fIone token look ahead scanner\fP.
820 This causes the above procedure to raise the flags one token too
821 soon.
822 A solution to get the right effect is to reserve two flags per
823 pseudocomment.
824 The first is set as soon as the corresponding pseudocomment is 
825 scanned.
826 At the returning of each token this flag is moved to the second flag.
827 The delay in this way achieved makes the pseudocomments have effect
828 at the correct place.
829 .NH 2
830 The second pass data structure
831 .NH 3
832 Inp_def descriptor
833 .DS B
834 .ft CW
835 struct inp_def {
836         struct inp_def *next;
837         int id_class;
838         char id_name[NAMESIZE];
839         char id_file[FNAMESIZE];
840         unsigned int id_line;
841         int id_nrargs;
842         char argtps[ARGSTPSSIZE];
843         int id_returns;
844         char id_type[TYPESIZE];
845         int id_called;
846         int id_used;
847         int id_ignored;
848         int id_voided;
849 };
850 .R
851 .DE
852 .PP
853 This description is almost similar to the \fIoutdef\fP descriptor as
854 described in 4.1.2.5.
855 There are some differences too.
856 .IP \f(CWnext\fP 15
857 As structures of this type are allocated dynamically, this field
858 is added so the same memory allocator as used in the first pass can be
859 used.
860 .LP
861 \f(CWid_called
862 .br
863 id_used
864 .br
865 id_ignored\fP
866 .IP \f(CWid_voided\fP 15
867 Some additional fields only used for function definitions.Their
868 meaning should be clear.
869 .PP
870 The other fields have the same meaning as the corresponding fields
871 in the \fIoutdef\fP descriptor.
872 Some attention should be paid to \f(CWid_argtps\fP and \f(CWid_type\fP.
873 These members have type \f(CWarray of char\fP, in contrast to
874 their counterparts in the \fIoutdef\fP descriptor.
875 The only operation performed on types is a check on equality.
876 Types are output by the first pass as a string describing the type.
877 The type of \f(CWi\fP in \f(CWint *i();\fP e.g. is output as
878 \f(CWint *()\fP.
879 Such a string is best put in an \f(CWarray of char\fP to be compared
880 easily.
881 .NH 2
882 The second pass checking mechanism
883 .PP
884 After all the definitions that are output by the first pass are
885 sorted by name, the definitions belonging to one name are ordered
886 as follows.
887 .QS
888 .RS
889 .IP - 1
890 external definitions
891 .IP -
892 static definitions
893 .IP -
894 library definitions
895 .IP -
896 declarations
897 .IP -
898 function calls
899 .IP -
900 variable usages
901 .RE
902 .QE
903 .PP
904 The main program of the second pass is easily explained.
905 For all different names, do the following.
906 First read the definitions.
907 If there is more than one definition, check for conflicts.
908 Then read the declarations, function calls and variable usages and
909 check them against the definitions.
910 After having processed all the declarations, function calls and
911 variable usages, check the definitions to see if they are used
912 correctly.
913 The next three paragraphs will explain the three most important
914 functions of the program.
915 .NH 3
916 Read_defs()
917 .PP
918 This function reads all definitions belonging to the same name.
919 Only one external definition is allowed, so if there are more, a
920 warning is given.
921 In different files it is allowed to define static functions or
922 variables with the same name.
923 So if a static function is read, \f(CWread_defs\fP checks if there isn't
924 already an external definition, and if not it puts the static
925 definition in the list of static definitions, to be used later.
926 If no external or static definitions are met, a library definition is
927 taken as definition.
928 If a function or a variable is defined with the same name as a function
929 or a variable in a library (which is allowed)
930 .I lint
931 gives a warning.
932 Of course it is also possible that there is no definition at all.
933 In that case \f(CWcheck\fP will warn.
934 .NH 3
935 Check()
936 .PP
937 \f(CWCheck\fP verifies declarations, function calls and variable
938 usages against the definitions.
939 For each of these entries the corresponding definition is looked up.
940 As there may be more than one static definition, first a static
941 definition from the same file as the entry is searched.
942 If not present, the external definition (which may be a library
943 definition) is taken as definition.
944 If no definition can be found and the current entry is an external
945 declaration,
946 .I lint
947 warns.
948 However in the case of an implicit function declaration
949 .I lint
950 will not warn, because
951 we will get a warning \f(CW%s used but not defined\fP later on.
952 Next a check is done if the declarations are consistent with their
953 definitions.
954 After the declarations, the function calls and variable usages are
955 verified against their corresponding definitions.
956 If no definition exists,
957 .I lint
958 warns.
959 Else the field \f(CWid_called\fP is set to 1.
960 (For variable definitions this should be interpreted as \fIused\fP.)
961 For variable usages this will be all.
962 If we are processing a function call we also check the number and types
963 of the arguments and we warn for function values which are used from
964 functions that don't return a value.
965 For each function call we administrate if a function value is used,
966 ignored or voided.
967 .NH 3
968 Check_usage()
969 .PP
970 Checks if the external definition and static definitions are used
971 correctly.
972 If a function or variable is defined but never used,
973 .I lint
974 warns, except for library definitions.
975 Functions, which return a value but whose value is always or
976 sometimes ignored, get a warning.
977 (A function value which is voided (cast to void) is not ignored,
978 but it isn't used either.)
979 .bp