]> andersk Git - splint.git/blame - src/exprChecks.c
*** empty log message ***
[splint.git] / src / exprChecks.c
CommitLineData
616915dd 1/*
2** LCLint - annotation-assisted static program checker
28bf4b0b 3** Copyright (C) 1994-2001 University of Virginia,
616915dd 4** Massachusetts Institute of Technology
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** This program is distributed in the hope that it will be useful, but
12** WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14** General Public License for more details.
15**
16** The GNU General Public License is available from http://www.gnu.org/ or
17** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18** MA 02111-1307, USA.
19**
20** For information on lclint: lclint-request@cs.virginia.edu
21** To report a bug: lclint-bug@cs.virginia.edu
22** For more information: http://lclint.cs.virginia.edu
23*/
24/*
25** exprChecks.c
26*/
27
28# include "lclintMacros.nf"
29# include "basic.h"
30# include "cgrammar.h"
31# include "cgrammar_tokens.h"
28bf4b0b 32# include "transferChecks.h"
616915dd 33# include "exprChecks.h"
34
35/*
36** for now, allow exprChecks to access exprNode.
37** may remove this in future
38*/
39
40/*@access exprNode@*/
41
28bf4b0b 42static bool checkCallModifyAux (/*@exposed@*/ sRef p_s, exprNode p_f, sRef p_alias, exprNode p_err);
43static bool checkModifyValAux (/*@exposed@*/ sRef p_s, exprNode p_f, sRef p_alias, exprNode p_err);
44static bool checkModifyAux (/*@exposed@*/ sRef p_s, exprNode p_f, sRef p_alias, exprNode p_err);
616915dd 45static void checkSafeReturnExpr (/*@notnull@*/ exprNode p_e);
46
47/*
48** called at end of expression statement
49**
50** of e->kind is not an assign, empty, body or modop
51** verify the the value is void
52**
53*/
54
55void
56exprNode_checkStatement (exprNode e)
57{
58 bool hasError = FALSE;
59
60 if (!exprNode_isError (e))
61 {
62 exprKind ek = e->kind;
63
64 if (ek == XPR_CALL && !(ctype_isRealVoid (e->typ)))
65 {
66 if (ctype_isKnown (e->typ))
67 {
68 if (ctype_isManifestBool (ctype_realishType (e->typ)))
69 {
70 hasError = optgenerror
71 (FLG_RETVALBOOL,
72 message ("Return value (type %t) ignored: %s",
73 e->typ,
74 exprNode_unparseFirst (e)),
75 e->loc);
76 }
77 else if (ctype_isDirectInt (e->typ))
78 {
79 hasError = optgenerror
80 (FLG_RETVALINT,
81 message ("Return value (type %t) ignored: %s",
82 e->typ,
83 exprNode_unparseFirst (e)),
84 e->loc);
85 }
86 else
87 {
88 hasError = optgenerror
89 (FLG_RETVALOTHER,
90 message ("Return value (type %t) ignored: %s",
91 e->typ,
92 exprNode_unparseFirst (e)),
93 e->loc);
94 }
95 }
96 }
97
98 if (!hasError && !(exprNode_mayEscape (e))
99 && !(e->canBreak)) /* control changes are effects too! */
100 {
101 if (sRefSet_hasRealElement (e->sets)
102 || sRefSet_hasRealElement (e->msets))
103 {
104 ; /* okay */
105 }
106 else
107 {
108 if (sRefSet_isEmpty (e->sets) && sRefSet_isEmpty (e->msets))
109 {
110 voptgenerror
111 (FLG_NOEFFECT,
112 message ("Statement has no effect: %s",
113 exprNode_unparseFirst (e)),
114 e->loc);
115 }
116 else
117 {
118 if (context_maybeSet (FLG_NOEFFECTUNCON))
119 {
120 if (sRefSet_hasUnconstrained (e->sets))
121 {
122 voptgenerror
123 (FLG_NOEFFECTUNCON,
124 message ("Statement has no effect (possible "
125 "undected modification through "
126 "call to %q): %s",
127 sRefSet_unparseUnconstrained (e->sets),
128 exprNode_unparseFirst (e)),
129 e->loc);
130 }
131 else if (sRefSet_hasUnconstrained (e->msets))
132 {
133 voptgenerror
134 (FLG_NOEFFECTUNCON,
135 message ("Statement has no effect (possible "
136 "undected modification through "
137 "call to %q): %s",
138 sRefSet_unparseUnconstrained (e->msets),
139 exprNode_unparseFirst (e)),
140 e->loc);
141 }
142 else
143 {
144 ; /* statement has unknown modification */
145 }
146 }
147 }
148 }
149 }
150 }
151}
152
153static bool
154checkRepExposed (sRef base, /*@notnull@*/ exprNode e, sRef alias,
155 /*@unused@*/ exprNode unused)
156{
157 ctype btype;
158
159 if (sRef_isInvalid (alias) || sRef_sameName (base, alias))
160 {
161 btype = sRef_getType (base);
162
163 if (ctype_isAbstract (btype) && ctype_isVisiblySharable (e->typ))
164 {
165 voptgenerror (FLG_RETEXPOSE,
166 message ("Return value exposes rep of %s: %s",
167 ctype_unparse (btype),
168 exprNode_unparse (e)),
169 e->loc);
170 return TRUE;
171 }
172 }
173 else
174 {
175 sRef rbase = sRef_getRootBase (base);
176 btype = sRef_getType (rbase);
177
178 if (ctype_isAbstract (btype) && ctype_isVisiblySharable (e->typ))
179 {
180 voptgenerror
181 (FLG_RETEXPOSE,
182 message ("Return value may expose rep of %s through alias %q: %s",
183 ctype_unparse (btype),
184 sRef_unparse (rbase),
185 exprNode_unparse (e)),
186 e->loc);
187 return TRUE;
188 }
189 }
190
191 return FALSE;
192}
193
194static bool
195checkRefGlobParam (sRef base, /*@notnull@*/ exprNode e,
196 sRef alias, /*@unused@*/ exprNode unused)
197{
198 if (sRef_isInvalid (alias) || sRef_sameName (base, alias))
199 {
200 ctype ct = e->typ;
201
202 if (ctype_isUnknown (ct))
203 {
204 ct = sRef_getType (base);
205 }
206
207 if (ctype_isVisiblySharable (ct))
208 {
28bf4b0b 209 if (sRef_isFileOrGlobalScope (base))
616915dd 210 {
28bf4b0b 211 uentry fcn = context_getHeader ();
212 bool noerror = FALSE;
213
214 if (uentry_isValid (fcn) && uentry_isFunction (fcn))
215 {
216 sRef res = uentry_getSref (fcn);
217
218 /* If result is dependent and global is owned, this is okay... */
219 if (sRef_isDependent (res)
220 && sRef_isOwned (base))
221 {
222 noerror = TRUE;
223
224 }
225 }
226
227 if (!noerror)
228 {
229 voptgenerror
230 (FLG_RETALIAS,
231 message ("Function returns reference to global %q: %s",
232 sRef_unparse (base),
233 exprNode_unparse (e)),
234 e->loc);
235 }
616915dd 236
237 return TRUE;
238 }
239 else if (sRef_isAnyParam (base))
240 {
241 uentryList params = context_getParams ();
242 int paramno = sRef_getParam (base);
243
244 if (paramno < uentryList_size (params))
245 {
246 uentry arg = uentryList_getN (params, paramno);
247 sRef ref = uentry_getSref (arg);
248
249 if (uentry_isReturned (arg)
250 || sRef_isOnly (ref)
251 || sRef_isExposed (ref)
252 || sRef_isRefCounted (ref))
253 {
254 ; /* okay */
255 }
256 else
257 {
258 voptgenerror
259 (FLG_RETALIAS,
260 message ("Function returns reference to parameter %q: %s",
261 sRef_unparse (base),
262 exprNode_unparse (e)),
263 e->loc);
264 }
265 }
266 else
267 {
268 llbuglit ("ret alias: bad paramno");
269 }
270
271 return TRUE;
272 }
273 else
274 {
275 return FALSE;
276 }
277 }
278 }
279 else
280 {
281 if (ctype_isVisiblySharable (e->typ))
282 {
28bf4b0b 283 if (sRef_isFileOrGlobalScope (base))
616915dd 284 {
285 voptgenerror
286 (FLG_RETALIAS,
287 message ("Function may return reference to global %q through alias %q: %s",
288 sRef_unparse (alias),
289 sRef_unparse (base),
290 exprNode_unparse (e)),
291 e->loc);
292 return TRUE;
293 }
294 else if (sRef_isAnyParam (base) && !(sRef_isOnly (base)))
295 {
296 uentryList params = context_getParams ();
297 int paramno = sRef_getParam (base);
298
299 if (paramno < uentryList_size (params))
300 {
301 uentry arg = uentryList_getN (params, paramno);
302
303 if (!uentry_isReturned (arg))
304 {
305 voptgenerror
306 (FLG_RETALIAS,
307 message
308 ("Function may return reference to parameter %q through alias %q: %s",
309 sRef_unparse (base),
310 sRef_unparse (alias),
311 exprNode_unparse (e)),
312 e->loc);
313
314 return TRUE;
315 }
316 }
317 else
318 {
319 voptgenerror
320 (FLG_RETALIAS,
321 message
322 ("Function may return reference to parameter %q through alias %q: %s",
323 sRef_unparse (base),
324 sRef_unparse (alias),
325 exprNode_unparse (e)),
326 e->loc);
327
328 return TRUE;
329 }
330 }
331 else
332 {
333 return FALSE;
334 }
335 }
336 }
337 return FALSE;
338}
339
340
341void
342exprNode_checkModify (exprNode e, exprNode err)
343{
344 llassert (exprNode_isDefined (e));
345
346 DPRINTF (("Check modify: %s", exprNode_unparse (e)));
28bf4b0b 347
616915dd 348 if (sRef_isValid (e->sref))
349 {
350 sRef_aliasCheckPred (checkModifyAux, sRef_isReference, e->sref, e, err);
351 }
352}
353
354void
355exprNode_checkModifyVal (exprNode e, exprNode err)
356{
357 llassert (exprNode_isDefined (e));
358
359 DPRINTF (("Check modify val: %s", exprNode_unparse (e)));
360
361 if (sRef_isValid (e->sref))
362 {
363 sRef_aliasCheckPred (checkModifyValAux, sRef_isReference, e->sref, e, err);
364 }
365}
366
367void
368exprChecks_checkNullReturn (fileloc loc)
369{
370 if (!context_inRealFunction ())
371 {
372 /*
373 llmsg ("exprChecks_checkNullReturnExpr: not in function context");
374 */
375 return;
376 }
377 else
378 {
379 if (ctype_isFunction (context_currentFunctionType ()))
380 {
28bf4b0b 381 ctype tr = ctype_getReturnType (context_currentFunctionType ());
616915dd 382
383 if (!ctype_isFirstVoid (tr))
384 {
385 if (ctype_isUnknown (tr))
386 {
387 voptgenerror
388 (FLG_CONTROL,
389 cstring_makeLiteral ("Empty return in function declared to implicitly return int"),
390 loc);
391 }
392 else
393 {
394 voptgenerror (FLG_CONTROL,
395 message ("Empty return in function declared to return %t", tr),
396 loc);
397 }
398 }
399 }
400 }
401}
402
403void
404exprNode_checkReturn (exprNode e)
405{
406 if (!exprNode_isError (e))
407 {
408 if (!context_inRealFunction ())
409 {
410 if (context_inMacro ())
411 {
412 llerror (FLG_CONTROL,
413 message ("Macro %s uses return (not functional)",
414 context_inFunctionName ()));
415 }
416 else
417 {
418 /*
419 llbuglit ("exprNode_checkReturn: not in function context");
420 */
421 }
422 }
423 else
424 {
425 if (ctype_isFunction (context_currentFunctionType ()))
426 {
427 checkSafeReturnExpr (e);
428 }
429 else
430 {
431 ;
432 }
433 }
434 }
435}
436
437void
438exprNode_checkPred (cstring c, exprNode e)
439{
440 ctype ct;
441
442 if (exprNode_isError (e))
443 return;
444
445 ct = exprNode_getType (e);
446
447 if (exprNode_isAssign (e))
448 {
449 voptgenerror
450 (FLG_PREDASSIGN,
451 message ("Test expression for %s is assignment expression: %s",
452 c, exprNode_unparse (e)),
453 e->loc);
454 }
455
28bf4b0b 456 if (ctype_isRealBool (ct) || ctype_isUnknown (ct))
457 /* evs 2000-12-20 added || ctype_isUnknown to avoid spurious messages */
616915dd 458 {
459 ;
460 }
461 else if (ctype_isRealPointer (ct))
462 {
463 voptgenerror
464 (FLG_PREDBOOLPTR,
465 message ("Test expression for %s not %s, type %t: %s", c,
466 context_printBoolName (),
467 ct, exprNode_unparse (e)),
468 e->loc);
469 }
470 else if (ctype_isRealInt (ct))
471 {
472 voptgenerror
473 (FLG_PREDBOOLINT,
474 message ("Test expression for %s not %s, type %t: %s", c,
475 context_printBoolName (), ct, exprNode_unparse (e)),
476 e->loc);
477 }
478 else
479 {
480 voptgenerror
481 (FLG_PREDBOOLOTHERS,
482 message ("Test expression for %s not %s, type %t: %s", c,
483 context_printBoolName (), ct, exprNode_unparse (e)),
484 e->loc);
485 }
486}
487
488void
489exprChecks_checkUsedGlobs (globSet decl, globSet used)
490{
491 fileloc fl = uentry_whereSpecified (context_getHeader ());
492
493 if (fileloc_isUndefined (fl))
494 {
495 fl = uentry_whereDeclared (context_getHeader ());
496 }
497
498 globSet_allElements (decl, el)
499 {
500 if (!globSet_member (used, el))
501 {
502 if (sRef_isSpecInternalState (el)
503 || sRef_isNothing (el))
504 {
505 ;
506 }
507 else
508 {
509 cstring sname = sRef_unparse (el);
510
511 if (fileloc_isLib (fl))
512 {
513 voptgenerror (FLG_USEALLGLOBS,
514 message ("Global %s listed (%q) but not used",
515 sname, fileloc_unparse (fl)),
516 g_currentloc);
517 }
518 else
519 {
520 voptgenerror (FLG_USEALLGLOBS,
521 message ("Global %s listed but not used", sname),
522 fl);
523 }
524
525 cstring_free (sname);
526 }
527 }
528 } end_globSet_allElements;
529}
530
531void
532exprNode_checkAllMods (sRefSet mods, uentry ue)
533{
534 bool realParams = FALSE;
535 uentry le = context_getHeader ();
536 fileloc fl = uentry_whereSpecified (le);
537 uentryList specParamNames = uentryList_undefined;
538 uentryList paramNames = context_getParams ();
539
540 if (uentry_isFunction (le))
541 {
542 specParamNames = uentry_getParams (le);
543
544 if (uentryList_isUndefined (specParamNames))
545 {
546 ; /* unknown params */
547 }
548 else if (uentryList_size (paramNames) != uentryList_size (specParamNames))
549 {
550 llbug
551 (message ("exprNode_checkAllMods: parameter lists have different sizes: "
552 "%q (%d) / %q (%d)",
553 uentryList_unparse (paramNames),
554 uentryList_size (paramNames),
555 uentryList_unparse (specParamNames),
556 uentryList_size (specParamNames)));
557 }
558 else if (uentryList_size (paramNames) > 0
559 && !uentry_hasRealName (uentryList_getN (specParamNames, 0)))
560 {
561 /* loaded from a library */
562 }
563 else
564 {
565 realParams = TRUE;
566 }
567 }
568
569 sRefSet_allElements (mods, sr)
570 {
571 if (sRef_isNothing (sr) || sRef_isSpecState (sr))
572 {
573 ; /* should report on anything? */
574 }
575 else if (sRef_isInternalState (sr))
576 {
577 if (!sRef_isModified (sr))
578 {
579 if (sRefSet_hasStatic (mods))
580 {
581 ; /* okay */
582 }
583 else
584 {
585 if (optgenerror
586 (FLG_MUSTMOD,
587 message
588 ("Function %s specified to modify internal state "
589 "but no internal state is modified",
590 uentry_rawName (ue)),
591 uentry_whereLast (ue)))
592 {
593 uentry_showWhereSpecified (le);
594 }
595 }
596 }
597 }
598 else
599 {
600 if (!sRef_isModified (sr))
601 {
602 cstring sname = realParams ? sRef_unparse (sr) : sRef_unparse (sr);
603
604 if (fileloc_isLib (fl) && !realParams)
605 {
606 voptgenerror
607 (FLG_MUSTMOD,
608 message ("Suspect object listed (%q) in modifies "
609 "clause of %s not modified: %s",
610 fileloc_unparse (fl),
611 uentry_rawName (ue),
612 sname),
613 uentry_whereLast (ue));
614 }
615 else
616 {
617 if (optgenerror
618 (FLG_MUSTMOD,
619 message ("Suspect object listed in modifies of %s "
620 "not modified: %s",
621 uentry_rawName (ue),
622 sname),
623 uentry_whereLast (ue)))
624 {
625 uentry_showWhereSpecified (le);
626 }
627 }
628 cstring_free (sname);
629 }
630 }
631 } end_sRefSet_allElements;
632}
633
634void exprNode_checkMacroBody (/*@only@*/ exprNode e)
635{
636 if (!exprNode_isError (e))
637 {
638 uentry hdr;
639
640 if (!(context_inFunctionLike () || context_inMacroConstant ()
b7e84605 641 || context_inUnknownMacro ()))
616915dd 642 {
643 llcontbug
644 (message
645 ("exprNode_checkMacroBody: not in macro function or constant: %q",
646 context_unparse ()));
647 exprNode_free (e);
648 return;
649 }
650
651 hdr = context_getHeader ();
652
653 if (e->kind == XPR_STMTLIST || e->kind == XPR_BODY)
654 {
655 voptgenerror
656 (FLG_MACROSTMT,
657 message
658 ("Macro %q definition is statement list (recommend "
659 "do { ... } while (0) constuction to ensure multiple "
660 "statement macro is syntactic function)",
661 uentry_getName (hdr)),
662 fileloc_isDefined (e->loc) ? e->loc : g_currentloc);
663 }
664
665 if (context_inMacroConstant ())
666 {
667 ctype t = uentry_getType (hdr);
668
669 uentry_setDefined (hdr, e->loc);
670
671 if (!(exprNode_matchType (t, e)))
672 {
673 cstring uname = uentry_getName (hdr);
674
675 if (cstring_equal (uname, context_getTrueName ())
676 || cstring_equal (uname, context_getFalseName ()))
677 {
678 /*
679 ** We need to do something special to allow FALSE and TRUE
680 ** to be defined without reporting errors. This is a tad
681 ** bogus, but otherwise lots of things would break.
682 */
683
684
685 llassert (ctype_isManifestBool (t));
686 /* Should also check type of e is a reasonable (?) bool type. */
687 }
688 else
689 {
690 if (optgenerror
691 (FLG_INCONDEFS,
692 message
693 ("Constant %q specified as %s, but defined as %s: %s",
694 uentry_getName (hdr),
695 ctype_unparse (t),
696 ctype_unparse (e->typ),
697 exprNode_unparse (e)),
698 e->loc))
699 {
700 uentry_showWhereSpecified (hdr);
701 }
702 }
703
704 cstring_free (uname);
705 }
706 else
707 {
708 if (context_maybeSet (FLG_NULLSTATE)
709 && ctype_isUA(t)
710 && ctype_isRealPointer (t)
711 && exprNode_isNullValue (e))
712 {
713 uentry ue = usymtab_getTypeEntry (ctype_typeId (t));
714 sRef sr = uentry_getSref (ue);
715
716 if (!sRef_possiblyNull (sr))
717 {
718 vgenhinterror
719 (FLG_NULLSTATE,
720 message ("Constant %q of non-null type %s defined "
721 "as null: %s",
722 uentry_getName (hdr), ctype_unparse (t),
723 exprNode_unparse (e)),
724 message ("If %s can be null, add a /*@null@*/ "
725 "qualifer to its typedef.",
726 ctype_unparse (t)),
727 e->loc);
728 }
729
730 uentry_mergeConstantValue (hdr, e->val);
731 e->val = multiVal_undefined;
732 }
733 }
734 }
b7e84605 735 else if (context_inMacroFunction () || context_inUnknownMacro ())
616915dd 736 {
737 ctype rettype = context_getRetType ();
738
739 if (context_isMacroMissingParams ())
740 {
741 llassert (context_inMacroFunction ());
742
743 /*
744 ** # define newname oldname
745 **
746 ** newname is a function
747 ** specification of oldname should match
748 ** specification of newname.
749 */
750
751 if (!ctype_isFunction (e->typ))
752 {
753 voptgenerror
754 (FLG_INCONDEFS,
755 message ("Function %s defined by unparameterized "
756 "macro not corresponding to function",
757 context_inFunctionName ()),
758 e->loc);
759 }
760 else
761 {
762 uentry ue = exprNode_getUentry (e);
763
764 if (uentry_isValid (ue))
765 {
766 /*
767 ** Okay, for now --- should check for consistency
768 */
769 /*
770 ** uentry oldue = usymtab_lookup (cfname);
771 */
772
773 /* check var conformance here! */
774 }
775 else
776 {
777 voptgenerror
778 (FLG_INCONDEFS,
779 message ("Function %s defined by unparameterized "
780 "macro not corresponding to function",
781 context_inFunctionName ()),
782 e->loc);
783 }
784
28bf4b0b 785 e->typ = ctype_getReturnType (e->typ);
616915dd 786 rettype = e->typ; /* avoid aditional errors */
787 }
788 }
789
790 if (ctype_isVoid (rettype) || ctype_isUnknown (rettype))
791 {
792 ; /* don't complain when void macros have values */
793 }
794 else if (!exprNode_matchType (rettype, e))
795 {
796 if (optgenerror
797 (FLG_INCONDEFS,
798 message ("Function %q specified to return %s, "
799 "implemented as macro having type %s: %s",
800 uentry_getName (hdr),
801 ctype_unparse (rettype), ctype_unparse (e->typ),
802 exprNode_unparse (e)),
803 e->loc))
804 {
805 uentry_showWhereSpecified (hdr);
806 }
807 }
808 else
809 {
810 switch (e->kind)
811 {
812 /* these expressions have values: */
813 case XPR_PARENS: case XPR_ASSIGN:
814 case XPR_EMPTY: case XPR_VAR:
815 case XPR_OP: case XPR_POSTOP:
816 case XPR_PREOP: case XPR_CALL:
817 case XPR_SIZEOFT: case XPR_SIZEOF:
818 case XPR_ALIGNOFT: case XPR_ALIGNOF:
819 case XPR_CAST: case XPR_FETCH:
820 case XPR_COMMA: case XPR_COND:
821 case XPR_ARROW: case XPR_CONST:
822 case XPR_STRINGLITERAL: case XPR_NUMLIT:
823 case XPR_FACCESS: case XPR_OFFSETOF:
824
825 checkReturnTransfer (e, hdr);
826 break;
827
828 /* these expressions don't */
829 case XPR_LABEL:
830 case XPR_VAARG: case XPR_ITER:
831 case XPR_FOR: case XPR_FORPRED:
832 case XPR_GOTO: case XPR_CONTINUE:
833 case XPR_BREAK: case XPR_RETURN:
834 case XPR_NULLRETURN: case XPR_IF:
835 case XPR_IFELSE: case XPR_DOWHILE:
836 case XPR_WHILE: case XPR_STMT:
837 case XPR_STMTLIST: case XPR_SWITCH:
838 case XPR_INIT: case XPR_BODY:
839 case XPR_NODE: case XPR_ITERCALL:
840 case XPR_TOK: case XPR_CASE:
841 case XPR_FTCASE: case XPR_FTDEFAULT:
842 case XPR_DEFAULT: case XPR_WHILEPRED:
843 case XPR_BLOCK: case XPR_INITBLOCK:
844 if (optgenerror
845 (FLG_INCONDEFS,
846 message ("Function %q specified to return %s, "
847 "implemented as macro with no result: %s",
848 uentry_getName (hdr),
849 ctype_unparse (rettype),
850 exprNode_unparse (e)),
851 e->loc))
852 {
853 uentry_showWhereSpecified (hdr);
854 }
855 }
856 }
857
858 usymtab_checkFinalScope (FALSE);
859 }
860 else
861 {
862 llbug (message ("exprNode_checkMacroBody: not in macro function: %q", context_unparse ()));
863 }
864
865 exprNode_free (e);
866 }
867
868 context_exitFunction ();
869 return;
870}
871
872void exprNode_checkFunctionBody (exprNode body)
873{
874 if (!exprNode_isError (body))
875 {
876 bool noret = context_getFlag (FLG_NORETURN);
877 bool checkret = exprNode_mustEscape (body);
878
879 if (!checkret
880 && noret
881 && !exprNode_errorEscape (body)
882 && context_inRealFunction ()
883 && ctype_isFunction (context_currentFunctionType ()))
884 {
28bf4b0b 885 ctype tr = ctype_getReturnType (context_currentFunctionType ());
616915dd 886
887 if (!ctype_isFirstVoid (tr))
888 {
889 if (ctype_isUnknown (tr))
890 {
891 voptgenerror
892 (FLG_NORETURN,
893 cstring_makeLiteral ("Path with no return in function declared to implicity return int"),
894 g_currentloc);
895 }
896 else
897 {
898 voptgenerror
899 (FLG_NORETURN,
900 message ("Path with no return in function declared to return %t",
901 tr),
902 g_currentloc);
903 }
904 }
905 }
616915dd 906
907 if (!checkret)
908 {
909 context_returnFunction ();
910 }
911 }
912}
913/*drl modified */
914
470b7798 915
28bf4b0b 916void exprNode_checkFunction (/*@unused@*/ uentry ue, /*@only@*/ exprNode fcnBody)
616915dd 917{
8f299805 918 constraintList c, t, post;
2934b455 919 constraintList c2, fix;
920 constraintList implicitFcnConstraints;
616915dd 921
28bf4b0b 922 /*@owned@*/ exprNode body;
923
bb25bea6 924 context_enterInnerContext ();
925
28bf4b0b 926 body = fcnBody;
4c02d8be 927
b7b694d6 928 /*
929 if we're not going to be printing any errors for buffer overflows
930 we can skip the checking to improve performance
931
932 FLG_DEBUGFUNCTIONCONSTRAINT controls wheather we perform the check anyway
933 in order to find potential problems like asserts and seg faults...
934 */
4c02d8be 935
936 if (!context_getFlag(FLG_DEBUGFUNCTIONCONSTRAINT) )
b7b694d6 937 /* check if errors will printed */
4c02d8be 938 if (! (context_getFlag(FLG_DEBUGFUNCTIONCONSTRAINT) ||
939 context_getFlag(FLG_FUNCTIONCONSTRAINT) ||
03d670b6 940 context_getFlag(FLG_ARRAYBOUNDS) ||
941 context_getFlag(FLG_ARRAYBOUNDSREAD) ||
4c02d8be 942 context_getFlag(FLG_CHECKPOST)
943 )
944 )
945 {
946 exprNode_free (body);
947 context_exitInnerPlain();
948
949 return;
950 }
28bf4b0b 951
616915dd 952 exprNode_generateConstraints (body);
28bf4b0b 953
616915dd 954
955 c = uentry_getFcnPreconditions (ue);
956 DPRINTF(("function constraints\n"));
957 DPRINTF (("\n\n\n\n\n\n\n"));
958
616915dd 959
28bf4b0b 960 if (constraintList_isDefined(c) )
616915dd 961 {
84c9ffbf 962
616915dd 963 DPRINTF ( (message ("Function preconditions are %s \n\n\n\n\n", constraintList_printDetailed (c) ) ) );
964
28bf4b0b 965 body->requiresConstraints = constraintList_reflectChangesFreePre (body->requiresConstraints, c);
bb25bea6 966
9280addf 967 c2 = constraintList_copy (c);
968 fix = constraintList_makeFixedArrayConstraints (body->uses);
28bf4b0b 969 c2 = constraintList_reflectChangesFreePre (c2, fix);
bb25bea6 970 constraintList_free(fix);
90bc41f7 971 if ( context_getFlag (FLG_ORCONSTRAINT) )
972 {
28bf4b0b 973 t = constraintList_reflectChangesOr (body->requiresConstraints, c2 );
90bc41f7 974 }
975 else
976 {
28bf4b0b 977 t = constraintList_reflectChanges(body->requiresConstraints, c2);
90bc41f7 978 }
bb25bea6 979
980 constraintList_free(body->requiresConstraints);
470b7798 981 DPRINTF ( (message ("The body has the required constraints: %s", constraintList_printDetailed (t) ) ) );
616915dd 982
bb25bea6 983 body->requiresConstraints = t;
984
985 t = constraintList_mergeEnsures (c, body->ensuresConstraints);
986 constraintList_free(body->ensuresConstraints);
987
988 body->ensuresConstraints = t;
989
990 DPRINTF ( (message ("The body has the ensures constraints: %s", constraintList_printDetailed (t) ) ) );
991 constraintList_free(c2);
616915dd 992 }
bb25bea6 993
28bf4b0b 994 if (constraintList_isDefined(c) )
616915dd 995 {
996 DPRINTF((message ("The Function %s has the preconditions %s", uentry_unparse(ue), constraintList_printDetailed(c) ) ) );
997 }
998 else
999 {
1000 DPRINTF((message ("The Function %s has no preconditions", uentry_unparse(ue) ) ) );
1001 }
1002
2934b455 1003 implicitFcnConstraints = getImplicitFcnConstraints();
1004
28bf4b0b 1005 if (constraintList_isDefined(implicitFcnConstraints) )
470b7798 1006 {
1007 if (context_getFlag (FLG_IMPLICTCONSTRAINT) )
1008 {
28bf4b0b 1009 body->requiresConstraints = constraintList_reflectChangesFreePre (body->requiresConstraints, implicitFcnConstraints );
470b7798 1010 }
1011 }
02984642 1012
1013 body->requiresConstraints = constraintList_sort (body->requiresConstraints);
470b7798 1014
616915dd 1015 constraintList_printError(body->requiresConstraints, g_currentloc);
8f299805 1016
1017 post = uentry_getFcnPostconditions (ue);
1018
1019 if ( context_getFlag (FLG_CHECKPOST) )
1020 {
28bf4b0b 1021 if (constraintList_isDefined(post) )
8f299805 1022 {
1023
1024 constraintList post2;
1025
1026 DPRINTF ( (message ("The declared function postconditions are %s \n\n\n\n\n", constraintList_printDetailed (post) ) ) );
1027
28bf4b0b 1028 post = constraintList_reflectChangesFreePre (post, body->ensuresConstraints);
8f299805 1029
1030 post2 = constraintList_copy (post);
1031 fix = constraintList_makeFixedArrayConstraints (body->uses);
28bf4b0b 1032 post2 = constraintList_reflectChangesFreePre (post2, fix);
8f299805 1033 constraintList_free(fix);
1034 if ( context_getFlag (FLG_ORCONSTRAINT) )
1035 {
28bf4b0b 1036 t = constraintList_reflectChangesOr (post2, body->ensuresConstraints);
8f299805 1037 }
1038 else
1039 {
28bf4b0b 1040 t = constraintList_reflectChanges(post2, body->ensuresConstraints);
8f299805 1041 }
1042
1043 constraintList_free(post2);
1044
1045 constraintList_free(post);
1046 post = t;
1047
1048
1049
1050 printf("Unresolved post conditions\n");
1051 constraintList_printErrorPostConditions(post, g_currentloc);
1052 }
1053 }
1054
28bf4b0b 1055 if (constraintList_isDefined(post) )
b7b694d6 1056 {
1057 constraintList_free(post);
1058 }
8f299805 1059
02984642 1060 body->ensuresConstraints = constraintList_sort(body->ensuresConstraints);
8f299805 1061
b7b694d6 1062 if ( context_getFlag (FLG_FUNCTIONPOST) )
1063 {
1064 constraintList_printError(body->ensuresConstraints, g_currentloc);
1065 }
616915dd 1066
8f299805 1067
b7b694d6 1068 /* ConPrint (message ("Unable to resolve function constraints:\n%s", constraintList_printDetailed(body->requiresConstraints) ), g_currentloc);
616915dd 1069
b7b694d6 1070 ConPrint (message ("LCLint has found function post conditions:\n%s", constraintList_printDetailed(body->ensuresConstraints) ), g_currentloc);
616915dd 1071
b7b694d6 1072 printf ("The required constraints are:\n%s", constraintList_printDetailed(body->requiresConstraints) );
1073 printf ("The ensures constraints are:\n%s", constraintList_printDetailed(body->ensuresConstraints) );
1074 */
616915dd 1075
28bf4b0b 1076 if (constraintList_isDefined(c) )
bb25bea6 1077 constraintList_free(c);
4ab867d6 1078
1079 context_exitInnerPlain();
1080
bb25bea6 1081 /*is it okay not to free this?*/
28bf4b0b 1082 exprNode_free (body);
1083 }
616915dd 1084
1085void exprChecks_checkEmptyMacroBody (void)
1086{
1087 uentry hdr;
1088
1089 if (!(context_inFunctionLike () || context_inMacroConstant ()
b7e84605 1090 || context_inUnknownMacro ()))
616915dd 1091 {
1092 llcontbug
1093 (message ("exprNode_checkEmptyMacroBody: not in macro function or constant: %q",
1094 context_unparse ()));
1095 return;
1096 }
1097
1098 hdr = context_getHeader ();
1099
1100 beginLine ();
1101
1102 if (uentry_isFunction (hdr))
1103 {
1104 voptgenerror
1105 (FLG_MACROEMPTY,
1106 message
1107 ("Macro definition for %q is empty", uentry_getName (hdr)),
1108 g_currentloc);
1109
1110 usymtab_checkFinalScope (FALSE);
1111 }
1112
1113 context_exitFunction ();
1114 return;
1115}
1116
1117void exprNode_checkIterBody (/*@only@*/ exprNode body)
1118{
1119 context_exitAllClauses ();
1120
1121 context_exitFunction ();
1122 exprNode_free (body);
1123}
1124
1125void exprNode_checkIterEnd (/*@only@*/ exprNode body)
1126{
1127 context_exitAllClauses ();
1128 context_exitFunction ();
1129 exprNode_free (body);
1130}
1131
1132static
28bf4b0b 1133bool checkModifyAuxAux (/*@exposed@*/ sRef s, exprNode f, sRef alias, exprNode err)
616915dd 1134{
1135 bool hasMods = context_hasMods ();
1136 flagcode errCode = hasMods ? FLG_MODIFIES : FLG_MODNOMODS;
1137
1138 if (exprNode_isDefined (f))
1139 {
1140 f->sets = sRefSet_insert (f->sets, s);
1141 }
1142
1143 if (context_getFlag (FLG_MODIFIES)
1144 && (hasMods || context_getFlag (FLG_MODNOMODS)))
1145 {
1146 sRefSet mods = context_modList ();
28bf4b0b 1147
616915dd 1148 if (!sRef_canModify (s, mods))
1149 {
1150 sRef rb = sRef_getRootBase (s);
616915dd 1151
28bf4b0b 1152
1153 if (sRef_isFileOrGlobalScope (rb))
616915dd 1154 {
1155 if (!context_checkGlobMod (rb))
1156 {
28bf4b0b 1157 return FALSE;
616915dd 1158 }
1159 }
28bf4b0b 1160
616915dd 1161 if (sRef_isInvalid (alias) || sRef_sameName (s, alias))
1162 {
1163 if (sRef_isLocalVar (sRef_getRootBase (s)))
1164 {
1165 voptgenerror
1166 (errCode,
1167 message
1168 ("Undocumented modification of internal state (%q): %s",
1169 sRef_unparse (s), exprNode_unparse (err)),
1170 exprNode_isDefined (f) ? f->loc : g_currentloc);
1171 }
1172 else
1173 {
1174 if (sRef_isSystemState (s))
1175 {
1176 if (errCode == FLG_MODNOMODS)
1177 {
1178 if (context_getFlag (FLG_MODNOMODS))
1179 {
1180 errCode = FLG_MODFILESYSTEM;
1181 }
1182 }
1183 else
1184 {
1185 errCode = FLG_MODFILESYSTEM;
1186 }
1187 }
1188
1189 voptgenerror
1190 (errCode,
1191 message ("Undocumented modification of %q: %s",
1192 sRef_unparse (s), exprNode_unparse (err)),
1193 exprNode_isDefined (f) ? f->loc : g_currentloc);
1194 }
1195
1196 return TRUE;
1197 }
1198 else
1199 {
1200 if (sRef_isReference (s) && !sRef_isAddress (alias))
1201 {
1202 voptgenerror
1203 (errCode,
1204 message
1205 ("Possible undocumented modification of %q through alias %q: %s",
1206 sRef_unparse (s),
1207 sRef_unparse (alias),
1208 exprNode_unparse (err)),
1209 exprNode_isDefined (f) ? f->loc : g_currentloc);
1210 return TRUE;
1211 }
1212 }
1213 }
1214 }
1215 else
1216 {
1217 if (context_maybeSet (FLG_MUSTMOD))
1218 {
1219 (void) sRef_canModify (s, context_modList ());
1220 }
1221
1222 if (sRef_isRefsField (s))
1223 {
1224 sRef_setModified (s);
1225 }
1226 }
1227
1228 return FALSE;
1229}
1230
1231static
28bf4b0b 1232bool checkModifyAux (/*@exposed@*/ sRef s, exprNode f, sRef alias, exprNode err)
616915dd 1233{
1234 DPRINTF (("Check modify aux: %s", sRef_unparseFull (s)));
1235
1236 if (sRef_isReference (s) && sRef_isObserver (s)
1237 && context_maybeSet (FLG_MODOBSERVER))
1238 {
1239 cstring sname;
1240
1241 if (sRef_isPointer (s))
1242 {
1243 sRef base = sRef_getBase (s);
1244 sname = sRef_unparse (base);
1245 }
1246 else
1247 {
1248 if (sRef_isAddress (s))
1249 {
1250 sRef p = sRef_constructPointer (s);
1251 sname = sRef_unparse (p);
1252 }
1253 else
1254 {
1255 sname = sRef_unparse (s);
1256 }
1257 }
1258
1259 if (!sRef_isValid (alias) || sRef_sameName (s, alias))
1260 {
1261 if (sRef_isMeaningful (s))
1262 {
1263 if (optgenerror
1264 (FLG_MODOBSERVER,
1265 message ("Suspect modification of observer %s: %s",
1266 sname, exprNode_unparse (err)),
1267 exprNode_isDefined (f) ? f->loc : g_currentloc))
1268 {
1269 sRef_showExpInfo (s);
1270 }
1271 }
1272 else
1273 {
1274 voptgenerror
1275 (FLG_MODOBSERVER,
1276 message ("Suspect modification of observer returned by "
1277 "function call: %s",
1278 exprNode_unparse (err)),
1279 exprNode_isDefined (f) ? f->loc : g_currentloc);
1280 }
1281 }
1282 else
1283 {
1284 if (optgenerror
1285 (FLG_MODOBSERVER,
1286 message ("Suspect modification of observer %s through alias %q: %s",
1287 sname, sRef_unparse (alias), exprNode_unparse (err)),
1288 exprNode_isDefined (f) ? f->loc : g_currentloc))
1289 {
1290 sRef_showExpInfo (s);
1291 }
1292 }
1293
1294 cstring_free (sname);
1295 }
1296
1297 (void) checkModifyAuxAux (s, f, alias, err);
1298 return FALSE;
1299}
1300
1301static
28bf4b0b 1302bool checkModifyValAux (/*@exposed@*/ sRef s, exprNode f, sRef alias, exprNode err)
616915dd 1303{
1304 (void) checkModifyAuxAux (s, f, alias, err);
1305 return FALSE;
1306}
1307
1308static
28bf4b0b 1309bool checkCallModifyAux (/*@exposed@*/ sRef s, exprNode f, sRef alias, exprNode err)
616915dd 1310{
1311 bool result = FALSE;
1312
28bf4b0b 1313 DPRINTF (("Check modify aux: %s / %s",
1314 sRef_unparse (s), sRef_unparse (alias)));
1315
616915dd 1316 if (sRef_isObserver (s) && context_maybeSet (FLG_MODOBSERVER))
1317 {
1318 sRef p = sRef_isAddress (s) ? sRef_constructPointer (s) : s;
1319 cstring sname = sRef_unparse (p);
1320
1321 if (!sRef_isValid (alias) || sRef_sameName (s, alias))
1322 {
1323 if (sRef_isMeaningful (s))
1324 {
1325 result = optgenerror
1326 (FLG_MODOBSERVER,
1327 message ("Suspect modification of observer %s: %s",
1328 sname, exprNode_unparse (err)),
1329 exprNode_isDefined (f) ? f->loc : g_currentloc);
1330 }
1331 else
1332 {
1333 result = optgenerror
1334 (FLG_MODOBSERVER,
1335 message ("Suspect modification of observer returned by "
1336 "function call: %s",
1337 exprNode_unparse (err)),
1338 exprNode_isDefined (f) ? f->loc : g_currentloc);
1339 }
1340 }
1341 else
1342 {
1343 result = optgenerror
1344 (FLG_MODOBSERVER,
1345 message
1346 ("Suspect modification of observer %s through alias %q: %s",
1347 sname, sRef_unparse (alias), exprNode_unparse (err)),
1348 exprNode_isDefined (f) ? f->loc : g_currentloc);
1349 }
1350
1351 cstring_free (sname);
1352 }
1353 else if (context_maybeSet (FLG_MODIFIES))
1354 {
28bf4b0b 1355 DPRINTF (("can modify: %s / %s",
1356 sRef_unparse (s),
1357 sRefSet_unparse (context_modList ())));
1358
616915dd 1359 if (!(sRef_canModifyVal (s, context_modList ())))
1360 {
1361 sRef p = sRef_isAddress (s) ? sRef_constructPointer (s) : s;
1362 cstring sname = sRef_unparse (p);
1363 bool hasMods = context_hasMods ();
1364 sRef rb = sRef_getRootBase (s);
1365 flagcode errCode = hasMods ? FLG_MODIFIES : FLG_MODNOMODS;
1366 bool check = TRUE;
28bf4b0b 1367
1368 DPRINTF (("Can't modify! %s", sRef_unparse (s)));
1369
1370 if (sRef_isFileOrGlobalScope (rb))
616915dd 1371 {
1372 uentry ue = sRef_getUentry (rb);
1373
1374 /* be more specific here! */
1375 if (!uentry_isCheckedModify (ue))
1376 {
1377 check = FALSE;
1378 }
1379 }
1380
1381 if (check)
1382 {
1383 if (!sRef_isValid (alias) || sRef_sameName (s, alias))
1384 {
1385 if (sRef_isLocalVar (sRef_getRootBase (s)))
1386 {
1387 voptgenerror
1388 (errCode,
1389 message
1390 ("Undocumented modification of internal "
1391 "state (%q) through call to %s: %s",
1392 sRef_unparse (s), exprNode_unparse (f),
1393 exprNode_unparse (err)),
1394 exprNode_isDefined (f) ? f->loc : g_currentloc);
1395 }
1396 else
1397 {
1398 if (sRef_isSystemState (s))
1399 {
1400 if (errCode == FLG_MODNOMODS)
1401 {
1402 if (context_getFlag (FLG_MODNOMODS))
1403 {
1404 errCode = FLG_MODFILESYSTEM;
1405 }
1406 }
1407 else
1408 {
1409 errCode = FLG_MODFILESYSTEM;
1410 }
1411 }
1412
1413 result = optgenerror
1414 (errCode,
1415 message ("Undocumented modification of %s "
1416 "possible from call to %s: %s",
1417 sname,
1418 exprNode_unparse (f),
1419 exprNode_unparse (err)),
1420 exprNode_isDefined (f) ? f->loc : g_currentloc);
1421 }
1422 }
1423 else
1424 {
1425 result = optgenerror
1426 (errCode,
1427 message ("Undocumented modification of %s possible "
1428 "from call to %s (through alias %q): %s",
1429 sname,
1430 exprNode_unparse (f),
1431 sRef_unparse (alias),
1432 exprNode_unparse (err)),
1433 exprNode_isDefined (f) ? f->loc : g_currentloc);
1434 }
1435 }
1436 cstring_free (sname);
1437 }
1438 }
1439 else
1440 {
1441 if (context_maybeSet (FLG_MUSTMOD))
1442 {
1443 (void) sRef_canModifyVal (s, context_modList ());
1444 }
1445 }
1446
1447 return result;
1448}
1449
1450void exprNode_checkCallModifyVal (sRef s, exprNodeList args, exprNode f, exprNode err)
1451{
1452 s = sRef_fixBaseParam (s, args);
28bf4b0b 1453 DPRINTF (("Check call modify: %s", sRef_unparse (s)));
616915dd 1454 sRef_aliasCheckPred (checkCallModifyAux, NULL, s, f, err);
1455}
1456
1457void
1458exprChecks_checkExport (uentry e)
1459{
1460 if (context_checkExport (e))
1461 {
1462 fileloc fl = uentry_whereDeclared (e);
1463
1464 if (fileloc_isHeader (fl) && !fileloc_isLib (fl)
1465 && !fileloc_isImport (fl) && !uentry_isStatic (e))
1466 {
1467 if (uentry_isFunction (e) ||
1468 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))))
1469 {
1470 voptgenerror
1471 (FLG_EXPORTFCN,
1472 message ("Function exported, but not specified: %q",
1473 uentry_getName (e)),
1474 fl);
1475 }
1476 else if (uentry_isExpandedMacro (e))
1477 {
1478 voptgenerror
1479 (FLG_EXPORTMACRO,
1480 message ("Expanded macro exported, but not specified: %q",
1481 uentry_getName (e)),
1482 fl);
1483 }
1484 else if (uentry_isVariable (e) && !uentry_isParam (e))
1485 {
1486 voptgenerror
1487 (FLG_EXPORTVAR,
1488 message ("Variable exported, but not specified: %q",
1489 uentry_getName (e)),
1490 fl);
1491 }
1492 else if (uentry_isEitherConstant (e))
1493 {
1494 voptgenerror
1495 (FLG_EXPORTCONST,
1496 message ("Constant exported, but not specified: %q",
1497 uentry_getName (e)),
1498 fl);
1499 }
1500 else if (uentry_isIter (e) || uentry_isEndIter (e))
1501 {
1502 voptgenerror
1503 (FLG_EXPORTITER,
1504 message ("Iterator exported, but not specified: %q",
1505 uentry_getName (e)),
1506 fl);
1507 }
1508
1509 else if (uentry_isDatatype (e))
1510 {
1511 ; /* error already reported */
1512 }
1513 else
1514 {
1515 BADEXIT;
1516 }
1517 }
1518 }
1519}
1520
1521static void checkSafeReturnExpr (/*@notnull@*/ exprNode e)
1522{
28bf4b0b 1523 ctype tr = ctype_getReturnType (context_currentFunctionType ());
616915dd 1524 ctype te = exprNode_getType (e);
1525
b7e84605 1526 /* evans 2001-08-21: added test to warn about void returns from void functions */
1527 if (ctype_isVoid (tr))
1528 {
1529 (void) gentypeerror
1530 (te, e, tr, exprNode_undefined,
1531 message ("Return expression from function declared void: %s", exprNode_unparse (e)),
1532 e->loc);
1533 return;
1534 }
1535
616915dd 1536 if (!ctype_forceMatch (tr, te) && !exprNode_matchLiteral (tr, e))
1537 {
1538 (void) gentypeerror
1539 (te, e, tr, exprNode_undefined,
1540 message ("Return value type %t does not match declared type %t: %s",
1541 te, tr, exprNode_unparse (e)),
1542 e->loc);
1543 }
1544 else
1545 {
1546 sRef ret = e->sref;
1547 uentry rval = context_getHeader ();
1548 sRef resultref = uentry_getSref (rval);
1549
28bf4b0b 1550 DPRINTF (("Check return: %s / %s / %s",
1551 exprNode_unparse (e),
1552 sRef_unparseFull (e->sref),
1553 uentry_unparse (rval)));
1554
616915dd 1555 checkReturnTransfer (e, rval);
1556
28bf4b0b 1557 DPRINTF (("After return: %s / %s / %s",
1558 exprNode_unparse (e),
1559 sRef_unparseFull (e->sref),
1560 uentry_unparse (rval)));
1561
616915dd 1562 if (!(sRef_isExposed (uentry_getSref (context_getHeader ()))
1563 || sRef_isObserver (uentry_getSref (context_getHeader ())))
1564 && (context_getFlag (FLG_RETALIAS)
1565 || context_getFlag (FLG_RETEXPOSE)))
1566 {
1567 sRef base = sRef_getRootBase (ret);
1568 ctype rtype = e->typ;
1569
1570 if (ctype_isUnknown (rtype))
1571 {
1572 rtype = tr;
1573 }
1574
1575 if (ctype_isVisiblySharable (rtype))
1576 {
1577 if (context_getFlag (FLG_RETALIAS))
1578 {
1579 sRef_aliasCheckPred (checkRefGlobParam, NULL, base,
1580 e, exprNode_undefined);
1581 }
1582
1583 if (context_getFlag (FLG_RETEXPOSE) && sRef_isIReference (ret)
1584 && !sRef_isExposed (resultref) && !sRef_isObserver (resultref))
1585 {
1586 sRef_aliasCheckPred (checkRepExposed, NULL, base, e,
1587 exprNode_undefined);
1588 }
1589 }
1590 }
1591 }
1592}
1593
28bf4b0b 1594
1595
1596
1597
This page took 0.431106 seconds and 5 git commands to generate.