]> andersk Git - splint.git/blob - src/exprChecks.c
Cleaned up flags to generate manual help.
[splint.git] / src / exprChecks.c
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 University of Virginia,
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://www.splint.org
23 */
24 /*
25 ** exprChecks.c
26 */
27
28 # include "lclintMacros.nf"
29 # include "basic.h"
30 # include "cgrammar.h"
31 # include "cgrammar_tokens.h"
32 # include "transferChecks.h"
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
42 static bool checkCallModifyAux (/*@exposed@*/ sRef p_s, exprNode p_f, sRef p_alias, exprNode p_err);
43 static bool checkModifyValAux (/*@exposed@*/ sRef p_s, exprNode p_f, sRef p_alias, exprNode p_err);
44 static bool checkModifyAux (/*@exposed@*/ sRef p_s, exprNode p_f, sRef p_alias, exprNode p_err);
45 static 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
55 void
56 exprNode_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
153 static bool
154 checkRepExposed (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
194 static bool
195 checkRefGlobParam (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         {
209           if (sRef_isFileOrGlobalScope (base))
210             {
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                 }
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         {
283           if (sRef_isFileOrGlobalScope (base))
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
341 void
342 exprNode_checkModify (exprNode e, exprNode err)
343 {
344   llassert (exprNode_isDefined (e));
345
346   DPRINTF (("Check modify: %s", exprNode_unparse (e)));
347   
348   if (sRef_isValid (e->sref))
349     {
350       sRef_aliasCheckPred (checkModifyAux, sRef_isReference, e->sref, e, err);
351     }
352 }
353
354 void
355 exprNode_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
367 void
368 exprChecks_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         {
381           ctype tr = ctype_getReturnType (context_currentFunctionType ());
382
383           if (!ctype_isFirstVoid (tr))
384             {
385               if (ctype_isUnknown (tr))
386                 {
387                   voptgenerror
388                     (FLG_EMPTYRETURN,
389                      cstring_makeLiteral ("Empty return in function declared to implicitly return int"),
390                      loc);
391                 }
392               else
393                 {
394                   voptgenerror (FLG_EMPTYRETURN,
395                                 message ("Empty return in function declared to return %t", tr),
396                                 loc);
397                 }
398             }
399         }
400     }
401 }
402
403 void
404 exprNode_checkReturn (exprNode e)
405 {
406   if (!exprNode_isError (e))
407     {
408       if (!context_inRealFunction ())
409         {
410           if (context_inMacro ())
411             {
412               llerror (FLG_MACRORETURN,
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
437 void
438 exprNode_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
456   if (ctype_isRealBool (ct) || ctype_isUnknown (ct)) 
457          /* evs 2000-12-20 added || ctype_isUnknown to avoid spurious messages */
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
488 void
489 exprChecks_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
531 void
532 exprNode_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
634 void exprNode_checkMacroBody (/*@only@*/ exprNode e)
635 {
636   if (!exprNode_isError (e))
637     {
638       uentry hdr;
639
640       if (!(context_inFunctionLike () || context_inMacroConstant ()
641             || context_inUnknownMacro ()))
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         }
735       else if (context_inMacroFunction () || context_inUnknownMacro ())
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                   
785                   e->typ = ctype_getReturnType (e->typ);
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                   transferChecks_return (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
872 void 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         {
885           ctype tr = ctype_getReturnType (context_currentFunctionType ());
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         }
906       
907       if (!checkret)
908         {
909           context_returnFunction ();
910         }
911     }
912 }
913 /*drl modified */
914
915
916 void exprNode_checkFunction (/*@unused@*/ uentry ue, /*@only@*/ exprNode fcnBody)
917 {
918   constraintList c, t, post;
919   constraintList c2, fix;
920   constraintList implicitFcnConstraints;
921
922   /*@owned@*/ exprNode body;
923
924   context_enterInnerContext ();
925
926   body = fcnBody;
927
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 assert failures and seg faults...
934   */
935
936   if (!context_getFlag(FLG_DEBUGFUNCTIONCONSTRAINT))
937     {
938       /* check if errors will printed */
939       if (!(context_getFlag(FLG_DEBUGFUNCTIONCONSTRAINT) ||
940             context_getFlag(FLG_BOUNDSWRITE) ||
941             context_getFlag(FLG_BOUNDSREAD) ||
942             context_getFlag(FLG_CHECKPOST)))
943         {
944           exprNode_free (body);
945           context_exitInnerPlain();
946           
947           return;
948         }
949     }
950   
951   exprNode_generateConstraints (body);
952   
953   c =   uentry_getFcnPreconditions (ue);
954   DPRINTF(("function constraints\n"));
955   DPRINTF (("\n\n\n\n\n\n\n"));
956   
957   if (constraintList_isDefined(c) )
958     {
959       DPRINTF ((message ("Function preconditions are %s \n\n\n\n\n", constraintList_printDetailed (c) ) ) );
960       
961       body->requiresConstraints = constraintList_reflectChangesFreePre (body->requiresConstraints, c);
962       
963       c2  =  constraintList_copy (c);
964       fix =  constraintList_makeFixedArrayConstraints (body->uses);
965       c2  =  constraintList_reflectChangesFreePre (c2, fix);
966       constraintList_free (fix);
967       
968       if (context_getFlag (FLG_ORCONSTRAINT))
969         {
970           t = constraintList_reflectChangesOr (body->requiresConstraints, c2 );
971         }
972       else
973         {
974           t = constraintList_reflectChanges(body->requiresConstraints, c2);
975         }
976       
977       constraintList_free (body->requiresConstraints);
978       DPRINTF ((message ("The body has the required constraints: %s", constraintList_printDetailed (t) ) ) );
979       
980       body->requiresConstraints = t;
981       
982       t = constraintList_mergeEnsures (c, body->ensuresConstraints);
983       constraintList_free(body->ensuresConstraints);
984       
985       body->ensuresConstraints = t;
986       
987       DPRINTF ((message ("The body has the ensures constraints: %s", constraintList_printDetailed (t) ) ) );
988       constraintList_free(c2);
989     }
990   
991   if (constraintList_isDefined(c))
992     {
993       DPRINTF ((message ("The Function %s has the preconditions %s", 
994                          uentry_unparse(ue), constraintList_printDetailed(c))));
995     }
996   else
997     {
998       DPRINTF((message ("The Function %s has no preconditions", uentry_unparse(ue))));
999     }
1000   
1001   implicitFcnConstraints = getImplicitFcnConstraints();
1002   
1003   if (constraintList_isDefined(implicitFcnConstraints) )
1004     {
1005       if (context_getFlag (FLG_IMPLICTCONSTRAINT) )
1006         {
1007           body->requiresConstraints = constraintList_reflectChangesFreePre (body->requiresConstraints, 
1008                                                                             implicitFcnConstraints );
1009         }
1010     }
1011   
1012   body->requiresConstraints = constraintList_sort (body->requiresConstraints);
1013   
1014   constraintList_printError(body->requiresConstraints, g_currentloc);
1015   
1016   post = uentry_getFcnPostconditions (ue);
1017   
1018   if (context_getFlag (FLG_CHECKPOST))
1019     {
1020       if (constraintList_isDefined (post))
1021         {
1022           constraintList post2;
1023           
1024           DPRINTF ((message ("The declared function postconditions are %s \n\n\n\n\n", 
1025                              constraintList_printDetailed (post) ) ) );
1026           
1027           post = constraintList_reflectChangesFreePre (post, body->ensuresConstraints);
1028           
1029           post2  =  constraintList_copy (post);
1030           fix =  constraintList_makeFixedArrayConstraints (body->uses);
1031           post2  =  constraintList_reflectChangesFreePre (post2, fix);
1032           constraintList_free(fix);
1033           if ( context_getFlag (FLG_ORCONSTRAINT) )
1034             {
1035               t = constraintList_reflectChangesOr (post2, body->ensuresConstraints);
1036             }
1037           else
1038             {
1039               t = constraintList_reflectChanges(post2, body->ensuresConstraints);
1040             }
1041           
1042           constraintList_free(post2);
1043           constraintList_free(post);
1044           post = t;
1045
1046           printf("Unresolved post conditions\n");
1047           constraintList_printErrorPostConditions(post, g_currentloc);
1048         }
1049     }
1050   
1051   if (constraintList_isDefined (post))
1052     {
1053       constraintList_free (post);
1054     }
1055    
1056    body->ensuresConstraints = constraintList_sort(body->ensuresConstraints);
1057
1058    if ( context_getFlag (FLG_FUNCTIONPOST) )
1059      {
1060        constraintList_printError(body->ensuresConstraints, g_currentloc);
1061      }
1062    
1063    /*   ConPrint (message ("Unable to resolve function constraints:\n%s", constraintList_printDetailed(body->requiresConstraints) ), g_currentloc);
1064
1065         ConPrint (message ("Splint has found function post conditions:\n%s", constraintList_printDetailed(body->ensuresConstraints) ), g_currentloc);
1066   
1067         printf ("The required constraints are:\n%s", constraintList_printDetailed(body->requiresConstraints) );
1068         printf ("The ensures constraints are:\n%s", constraintList_printDetailed(body->ensuresConstraints) );
1069    */
1070    
1071    if (constraintList_isDefined(c) )
1072      constraintList_free(c);
1073
1074    context_exitInnerPlain();
1075
1076    /*is it okay not to free this?*/
1077   exprNode_free (body);
1078   }
1079
1080 void exprChecks_checkEmptyMacroBody (void)
1081 {
1082   uentry hdr;
1083   
1084   if (!(context_inFunctionLike () || context_inMacroConstant ()
1085         || context_inUnknownMacro ()))
1086     {
1087       llcontbug 
1088         (message ("exprNode_checkEmptyMacroBody: not in macro function or constant: %q", 
1089                   context_unparse ()));
1090       return;
1091     }
1092   
1093   hdr = context_getHeader ();
1094   
1095   beginLine ();
1096   
1097   if (uentry_isFunction (hdr))
1098     {
1099       voptgenerror 
1100         (FLG_MACROEMPTY,
1101          message 
1102          ("Macro definition for %q is empty", uentry_getName (hdr)),
1103          g_currentloc);
1104
1105       usymtab_checkFinalScope (FALSE);
1106     }
1107
1108   context_exitFunction ();
1109   return;
1110 }
1111
1112 void exprNode_checkIterBody (/*@only@*/ exprNode body)
1113 {
1114   context_exitAllClauses ();
1115
1116   context_exitFunction ();
1117   exprNode_free (body);
1118 }
1119
1120 void exprNode_checkIterEnd (/*@only@*/ exprNode body)
1121 {
1122   context_exitAllClauses ();
1123   context_exitFunction ();
1124   exprNode_free (body);
1125 }
1126
1127 static
1128 bool checkModifyAuxAux (/*@exposed@*/ sRef s, exprNode f, sRef alias, exprNode err)
1129 {
1130   bool hasMods = context_hasMods ();
1131   flagcode errCode = hasMods ? FLG_MODIFIES : FLG_MODNOMODS;
1132
1133   if (exprNode_isDefined (f))
1134     {
1135       f->sets = sRefSet_insert (f->sets, s); 
1136     }
1137
1138   if (context_getFlag (FLG_MODIFIES) 
1139       && (hasMods || context_getFlag (FLG_MODNOMODS)))
1140     {
1141       sRefSet mods = context_modList ();
1142
1143       if (!sRef_canModify (s, mods))
1144         {
1145           sRef rb = sRef_getRootBase (s);
1146           
1147           
1148           if (sRef_isFileOrGlobalScope (rb))
1149             {
1150               if (!context_checkGlobMod (rb))
1151                 {
1152                   return FALSE;
1153                 }
1154             }
1155           
1156           if (sRef_isInvalid (alias) || sRef_sameName (s, alias))
1157             {
1158               if (sRef_isLocalVar (sRef_getRootBase (s)))
1159                 {
1160                   voptgenerror 
1161                     (errCode,
1162                      message 
1163                      ("Undocumented modification of internal state (%q): %s", 
1164                       sRef_unparse (s), exprNode_unparse (err)), 
1165                      exprNode_isDefined (f) ? f->loc : g_currentloc);
1166                 }
1167               else
1168                 {
1169                   if (sRef_isSystemState (s))
1170                     {
1171                       if (errCode == FLG_MODNOMODS) 
1172                         {
1173                           if (context_getFlag (FLG_MODNOMODS))
1174                             {
1175                               errCode = FLG_MODFILESYSTEM;
1176                             }
1177                         }
1178                       else
1179                         {
1180                           errCode = FLG_MODFILESYSTEM;
1181                         }
1182                     }
1183
1184                   voptgenerror 
1185                     (errCode,
1186                      message ("Undocumented modification of %q: %s", 
1187                               sRef_unparse (s), exprNode_unparse (err)), 
1188                      exprNode_isDefined (f) ? f->loc : g_currentloc);
1189                 }
1190               
1191               return TRUE;
1192             }
1193           else
1194             {
1195               if (sRef_isReference (s) && !sRef_isAddress (alias))
1196                 {
1197                   voptgenerror 
1198                     (errCode,
1199                      message
1200                      ("Possible undocumented modification of %q through alias %q: %s", 
1201                       sRef_unparse (s),
1202                       sRef_unparse (alias),
1203                       exprNode_unparse (err)),
1204                      exprNode_isDefined (f) ? f->loc : g_currentloc);
1205                   return TRUE;
1206                 }
1207             }
1208         }
1209     }
1210   else
1211     {
1212       if (context_maybeSet (FLG_MUSTMOD))
1213         {
1214           (void) sRef_canModify (s, context_modList ());
1215         }
1216       
1217       if (sRef_isRefsField (s))
1218         {
1219           sRef_setModified (s);
1220         }
1221     }
1222   
1223   return FALSE;
1224 }
1225
1226 static
1227 bool checkModifyAux (/*@exposed@*/ sRef s, exprNode f, sRef alias, exprNode err)
1228 {
1229   DPRINTF (("Check modify aux: %s", sRef_unparseFull (s)));
1230
1231   if (sRef_isReference (s) && sRef_isObserver (s) 
1232       && context_maybeSet (FLG_MODOBSERVER))
1233     {    
1234       cstring sname;
1235       
1236       if (sRef_isPointer (s)) 
1237         {
1238           sRef base = sRef_getBase (s);
1239           sname = sRef_unparse (base);
1240         }
1241       else 
1242         {
1243           if (sRef_isAddress (s))
1244             {
1245               sRef p = sRef_constructPointer (s);
1246               sname = sRef_unparse (p);
1247             }
1248           else
1249             {
1250               sname = sRef_unparse (s);
1251             }
1252         }
1253       
1254       if (!sRef_isValid (alias) || sRef_sameName (s, alias))
1255         {
1256           if (sRef_isMeaningful (s))
1257             {
1258               if (optgenerror 
1259                   (FLG_MODOBSERVER,
1260                    message ("Suspect modification of observer %s: %s", 
1261                             sname, exprNode_unparse (err)), 
1262                    exprNode_isDefined (f) ? f->loc : g_currentloc))
1263                 {
1264                   sRef_showExpInfo (s);
1265                 }
1266             }
1267           else
1268             {
1269               voptgenerror 
1270                 (FLG_MODOBSERVER,
1271                  message ("Suspect modification of observer returned by "
1272                           "function call: %s", 
1273                           exprNode_unparse (err)), 
1274                  exprNode_isDefined (f) ? f->loc : g_currentloc);
1275             }
1276         }
1277       else
1278         {
1279           if (optgenerror
1280               (FLG_MODOBSERVER,
1281                message ("Suspect modification of observer %s through alias %q: %s", 
1282                         sname, sRef_unparse (alias), exprNode_unparse (err)), 
1283                exprNode_isDefined (f) ? f->loc : g_currentloc))
1284             {
1285               sRef_showExpInfo (s);
1286             }
1287         }
1288       
1289       cstring_free (sname);
1290     }
1291   
1292   (void) checkModifyAuxAux (s, f, alias, err);
1293   return FALSE;
1294 }
1295
1296 static
1297 bool checkModifyValAux (/*@exposed@*/ sRef s, exprNode f, sRef alias, exprNode err)
1298 {
1299   (void) checkModifyAuxAux (s, f, alias, err);
1300   return FALSE;
1301 }
1302
1303 static
1304 bool checkCallModifyAux (/*@exposed@*/ sRef s, exprNode f, sRef alias, exprNode err)
1305 {
1306   bool result = FALSE;
1307
1308   DPRINTF (("Check modify aux: %s / %s",
1309             sRef_unparse (s), sRef_unparse (alias)));
1310
1311   if (sRef_isObserver (s) && context_maybeSet (FLG_MODOBSERVER))
1312     {    
1313       sRef p = sRef_isAddress (s) ? sRef_constructPointer (s) : s;
1314       cstring sname = sRef_unparse (p);
1315
1316       if (!sRef_isValid (alias) || sRef_sameName (s, alias))
1317         {
1318           if (sRef_isMeaningful (s))
1319             {
1320               result = optgenerror 
1321                 (FLG_MODOBSERVER,
1322                  message ("Suspect modification of observer %s: %s", 
1323                           sname, exprNode_unparse (err)), 
1324                  exprNode_isDefined (f) ? f->loc : g_currentloc);
1325             }
1326           else
1327             {
1328               result = optgenerror 
1329                 (FLG_MODOBSERVER,
1330                  message ("Suspect modification of observer returned by "
1331                           "function call: %s", 
1332                           exprNode_unparse (err)), 
1333                  exprNode_isDefined (f) ? f->loc : g_currentloc);
1334             }
1335         }
1336       else
1337         {
1338           result = optgenerror 
1339             (FLG_MODOBSERVER,
1340              message
1341              ("Suspect modification of observer %s through alias %q: %s", 
1342               sname, sRef_unparse (alias), exprNode_unparse (err)), 
1343              exprNode_isDefined (f) ? f->loc : g_currentloc);
1344         }
1345       
1346       cstring_free (sname);
1347     }
1348   else if (context_maybeSet (FLG_MODIFIES))
1349     {
1350       DPRINTF (("can modify: %s / %s",
1351                 sRef_unparse (s),
1352                 sRefSet_unparse (context_modList ())));
1353
1354       if (!(sRef_canModifyVal (s, context_modList ())))
1355         {
1356           sRef p = sRef_isAddress (s) ? sRef_constructPointer (s) : s;
1357           cstring sname = sRef_unparse (p);
1358           bool hasMods = context_hasMods ();
1359           sRef rb = sRef_getRootBase (s);
1360           flagcode errCode = hasMods ? FLG_MODIFIES : FLG_MODNOMODS;
1361           bool check = TRUE;
1362
1363           DPRINTF (("Can't modify! %s", sRef_unparse (s)));
1364
1365           if (sRef_isFileOrGlobalScope (rb))
1366             {
1367               uentry ue = sRef_getUentry (rb);
1368               
1369               /* be more specific here! */
1370               if (!uentry_isCheckedModify (ue))
1371                 {
1372                   check = FALSE;
1373                 }
1374             }
1375           
1376           if (check)
1377             {
1378               if (!sRef_isValid (alias) || sRef_sameName (s, alias))
1379                 {
1380                   if (sRef_isLocalVar (sRef_getRootBase (s)))
1381                     {
1382                       voptgenerror 
1383                         (errCode,
1384                          message 
1385                          ("Undocumented modification of internal "
1386                           "state (%q) through call to %s: %s", 
1387                           sRef_unparse (s), exprNode_unparse (f),
1388                           exprNode_unparse (err)), 
1389                          exprNode_isDefined (f) ? f->loc : g_currentloc);
1390                     }
1391                   else
1392                     {
1393                       if (sRef_isSystemState (s))
1394                         {
1395                           if (errCode == FLG_MODNOMODS) 
1396                             {
1397                               if (context_getFlag (FLG_MODNOMODS))
1398                                 {
1399                                   errCode = FLG_MODFILESYSTEM;
1400                                 }
1401                             }
1402                           else
1403                             {
1404                               errCode = FLG_MODFILESYSTEM;
1405                             }
1406                         }
1407                       
1408                       result = optgenerror 
1409                         (errCode,
1410                          message ("Undocumented modification of %s "
1411                                   "possible from call to %s: %s", 
1412                                   sname,
1413                                   exprNode_unparse (f),
1414                                   exprNode_unparse (err)),
1415                          exprNode_isDefined (f) ? f->loc : g_currentloc);
1416                     }
1417                 }
1418               else
1419                 {
1420                   result = optgenerror
1421                     (errCode,
1422                      message ("Undocumented modification of %s possible "
1423                               "from call to %s (through alias %q): %s", 
1424                               sname,
1425                               exprNode_unparse (f), 
1426                               sRef_unparse (alias), 
1427                               exprNode_unparse (err)),
1428                      exprNode_isDefined (f) ? f->loc : g_currentloc);
1429                 }
1430             }
1431           cstring_free (sname);
1432         }
1433     }
1434   else
1435     {
1436       if (context_maybeSet (FLG_MUSTMOD))
1437         {
1438           (void) sRef_canModifyVal (s, context_modList ());
1439         }
1440     }
1441
1442   return result;
1443 }
1444
1445 void exprNode_checkCallModifyVal (sRef s, exprNodeList args, exprNode f, exprNode err)
1446 {
1447   s = sRef_fixBaseParam (s, args);
1448   DPRINTF (("Check call modify: %s", sRef_unparse (s)));
1449   sRef_aliasCheckPred (checkCallModifyAux, NULL, s, f, err);
1450 }
1451
1452 void
1453 exprChecks_checkExport (uentry e)
1454 {
1455   if (context_checkExport (e))
1456     {
1457       fileloc fl = uentry_whereDeclared (e);
1458       
1459       if (fileloc_isHeader (fl) && !fileloc_isLib (fl) 
1460           && !fileloc_isImport (fl) && !uentry_isStatic (e))
1461         {
1462           if (uentry_isFunction (e) || 
1463               (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))))
1464             {
1465               voptgenerror 
1466                 (FLG_EXPORTFCN,
1467                  message ("Function exported, but not specified: %q", 
1468                           uentry_getName (e)),
1469                  fl);
1470             }
1471           else if (uentry_isExpandedMacro (e))
1472             {
1473               voptgenerror
1474                 (FLG_EXPORTMACRO,
1475                  message ("Expanded macro exported, but not specified: %q", 
1476                           uentry_getName (e)),
1477                  fl);
1478             }
1479           else if (uentry_isVariable (e) && !uentry_isParam (e)) 
1480             {
1481               voptgenerror 
1482                 (FLG_EXPORTVAR,
1483                  message ("Variable exported, but not specified: %q", 
1484                           uentry_getName (e)),
1485                  fl);
1486             }
1487           else if (uentry_isEitherConstant (e))
1488             {
1489               voptgenerror 
1490                 (FLG_EXPORTCONST,
1491                  message ("Constant exported, but not specified: %q", 
1492                           uentry_getName (e)),
1493                  fl);
1494             }
1495           else if (uentry_isIter (e) || uentry_isEndIter (e))
1496             {
1497               voptgenerror 
1498                 (FLG_EXPORTITER,
1499                  message ("Iterator exported, but not specified: %q", 
1500                           uentry_getName (e)),
1501                  fl);
1502             }
1503
1504           else if (uentry_isDatatype (e))
1505             {
1506               ; /* error already reported */
1507             }
1508           else
1509             {
1510               BADEXIT;
1511             }
1512         }
1513     }
1514 }
1515
1516 static void checkSafeReturnExpr (/*@notnull@*/ exprNode e)
1517 {
1518   ctype tr = ctype_getReturnType (context_currentFunctionType ());
1519   ctype te = exprNode_getType (e);
1520
1521   /* evans 2001-08-21: added test to warn about void returns from void functions */
1522   if (ctype_isVoid (tr))
1523     {
1524       (void) gentypeerror
1525         (te, e, tr, exprNode_undefined,
1526          message ("Return expression from function declared void: %s", exprNode_unparse (e)),
1527          e->loc);
1528       return;
1529     }
1530
1531   if (!ctype_forceMatch (tr, te) && !exprNode_matchLiteral (tr, e))
1532     {
1533       (void) gentypeerror
1534         (te, e, tr, exprNode_undefined,
1535          message ("Return value type %t does not match declared type %t: %s",
1536                   te, tr, exprNode_unparse (e)),
1537          e->loc);
1538     }
1539   else
1540     {
1541       sRef ret = e->sref;
1542       uentry rval = context_getHeader ();
1543       sRef resultref = uentry_getSref (rval);
1544
1545       DPRINTF (("Check return: %s / %s / %s",
1546                 exprNode_unparse (e),
1547                 sRef_unparseFull (e->sref),
1548                 uentry_unparse (rval)));
1549
1550       transferChecks_return (e, rval);
1551
1552       DPRINTF (("After return: %s / %s / %s",
1553                 exprNode_unparse (e),
1554                 sRef_unparseFull (e->sref),
1555                 uentry_unparse (rval)));
1556
1557       if (!(sRef_isExposed (uentry_getSref (context_getHeader ()))
1558             || sRef_isObserver (uentry_getSref (context_getHeader ())))
1559           && (context_getFlag (FLG_RETALIAS) 
1560               || context_getFlag (FLG_RETEXPOSE)))
1561         {
1562           sRef base = sRef_getRootBase (ret);
1563           ctype rtype = e->typ;
1564
1565           if (ctype_isUnknown (rtype))
1566             {
1567               rtype = tr;
1568             }
1569
1570           if (ctype_isVisiblySharable (rtype))
1571             {
1572               if (context_getFlag (FLG_RETALIAS))
1573                 {
1574                   sRef_aliasCheckPred (checkRefGlobParam, NULL, base, 
1575                                        e, exprNode_undefined);
1576                 }
1577               
1578               if (context_getFlag (FLG_RETEXPOSE) && sRef_isIReference (ret) 
1579                   && !sRef_isExposed (resultref) && !sRef_isObserver (resultref))
1580                 {
1581                   sRef_aliasCheckPred (checkRepExposed, NULL, base, e, 
1582                                        exprNode_undefined);
1583                 }
1584             }
1585         }
1586     }
1587 }
1588
1589
1590
1591
1592
This page took 0.166709 seconds and 5 git commands to generate.