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