]> andersk Git - splint.git/blob - src/exprChecks.c
Committing to make sure that the ./configure works.
[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 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_CHECKPOST)))
965         {
966           exprNode_free (body);
967           context_exitInnerPlain();
968           
969           return;
970         }
971     }
972   
973   exprNode_generateConstraints (body); /* evans 2002-03-02: this should not be declared to take a
974                                           dependent... fix it! */
975   
976   c =   uentry_getFcnPreconditions (ue);
977   DPRINTF(("function constraints\n"));
978   DPRINTF (("\n\n\n\n\n\n\n"));
979   
980   if (constraintList_isDefined(c) )
981     {
982       DPRINTF ((message ("Function preconditions are %s \n\n\n\n\n", constraintList_printDetailed (c) ) ) );
983       
984       body->requiresConstraints = constraintList_reflectChangesFreePre (body->requiresConstraints, c);
985       
986       c2  =  constraintList_copy (c);
987       fix =  constraintList_makeFixedArrayConstraints (body->uses);
988       c2  =  constraintList_reflectChangesFreePre (c2, fix);
989       constraintList_free (fix);
990       
991       if (context_getFlag (FLG_ORCONSTRAINT))
992         {
993           t = constraintList_reflectChangesOr (body->requiresConstraints, c2 );
994         }
995       else
996         {
997           t = constraintList_reflectChanges(body->requiresConstraints, c2);
998         }
999       
1000       constraintList_free (body->requiresConstraints);
1001       DPRINTF ((message ("The body has the required constraints: %s", constraintList_printDetailed (t) ) ) );
1002       
1003       body->requiresConstraints = t;
1004       
1005       t = constraintList_mergeEnsures (c, body->ensuresConstraints);
1006       constraintList_free(body->ensuresConstraints);
1007       
1008       body->ensuresConstraints = t;
1009       
1010       DPRINTF ((message ("The body has the ensures constraints: %s", constraintList_printDetailed (t) ) ) );
1011       constraintList_free(c2);
1012     }
1013   
1014   if (constraintList_isDefined(c))
1015     {
1016       DPRINTF ((message ("The Function %s has the preconditions %s", 
1017                          uentry_unparse(ue), constraintList_printDetailed(c))));
1018     }
1019   else
1020     {
1021       DPRINTF((message ("The Function %s has no preconditions", uentry_unparse(ue))));
1022     }
1023   
1024   implicitFcnConstraints = getImplicitFcnConstraints();
1025   
1026   if (constraintList_isDefined(implicitFcnConstraints) )
1027     {
1028       if (context_getFlag (FLG_IMPLICTCONSTRAINT) )
1029         {
1030           body->requiresConstraints = constraintList_reflectChangesFreePre (body->requiresConstraints, 
1031                                                                             implicitFcnConstraints );
1032         }
1033     }
1034   
1035   body->requiresConstraints = constraintList_sort (body->requiresConstraints);
1036   
1037   constraintList_printError(body->requiresConstraints, g_currentloc);
1038   
1039   post = uentry_getFcnPostconditions (ue);
1040   
1041   if (context_getFlag (FLG_CHECKPOST))
1042     {
1043       if (constraintList_isDefined (post))
1044         {
1045           constraintList post2;
1046           
1047           DPRINTF ((message ("The declared function postconditions are %s \n\n\n\n\n", 
1048                              constraintList_printDetailed (post) ) ) );
1049           
1050           post = constraintList_reflectChangesFreePre (post, body->ensuresConstraints);
1051           
1052           post2  =  constraintList_copy (post);
1053           fix =  constraintList_makeFixedArrayConstraints (body->uses);
1054           post2  =  constraintList_reflectChangesFreePre (post2, fix);
1055           constraintList_free(fix);
1056           if ( context_getFlag (FLG_ORCONSTRAINT) )
1057             {
1058               t = constraintList_reflectChangesOr (post2, body->ensuresConstraints);
1059             }
1060           else
1061             {
1062               t = constraintList_reflectChanges(post2, body->ensuresConstraints);
1063             }
1064           
1065           constraintList_free(post2);
1066           constraintList_free(post);
1067           post = t;
1068
1069           printf("Unresolved post conditions\n");
1070           constraintList_printErrorPostConditions(post, g_currentloc);
1071         }
1072     }
1073   
1074   if (constraintList_isDefined (post))
1075     {
1076       constraintList_free (post);
1077     }
1078    
1079    body->ensuresConstraints = constraintList_sort(body->ensuresConstraints);
1080
1081    if ( context_getFlag (FLG_FUNCTIONPOST) )
1082      {
1083        constraintList_printError(body->ensuresConstraints, g_currentloc);
1084      }
1085    
1086    /*   ConPrint (message ("Unable to resolve function constraints:\n%s", constraintList_printDetailed(body->requiresConstraints) ), g_currentloc);
1087
1088         ConPrint (message ("Splint has found function post conditions:\n%s", constraintList_printDetailed(body->ensuresConstraints) ), g_currentloc);
1089   
1090         printf ("The required constraints are:\n%s", constraintList_printDetailed(body->requiresConstraints) );
1091         printf ("The ensures constraints are:\n%s", constraintList_printDetailed(body->ensuresConstraints) );
1092    */
1093    
1094    if (constraintList_isDefined(c) )
1095      constraintList_free(c);
1096
1097    context_exitInnerPlain();
1098
1099    /*is it okay not to free this?*/
1100   exprNode_free (body);
1101   }
1102
1103 void exprChecks_checkEmptyMacroBody (void)
1104 {
1105   uentry hdr;
1106   
1107   if (!(context_inFunctionLike () || context_inMacroConstant ()
1108         || context_inUnknownMacro ()))
1109     {
1110       llcontbug 
1111         (message ("exprNode_checkEmptyMacroBody: not in macro function or constant: %q", 
1112                   context_unparse ()));
1113       return;
1114     }
1115   
1116   hdr = context_getHeader ();
1117   
1118   beginLine ();
1119   
1120   if (uentry_isFunction (hdr))
1121     {
1122       voptgenerror 
1123         (FLG_MACROEMPTY,
1124          message 
1125          ("Macro definition for %q is empty", uentry_getName (hdr)),
1126          g_currentloc);
1127
1128       usymtab_checkFinalScope (FALSE);
1129     }
1130
1131   context_exitFunction ();
1132   return;
1133 }
1134
1135 void exprNode_checkIterBody (/*@only@*/ exprNode body)
1136 {
1137   context_exitAllClauses ();
1138
1139   context_exitFunction ();
1140   exprNode_free (body);
1141 }
1142
1143 void exprNode_checkIterEnd (/*@only@*/ exprNode body)
1144 {
1145   context_exitAllClauses ();
1146   context_exitFunction ();
1147   exprNode_free (body);
1148 }
1149
1150 static
1151 bool checkModifyAuxAux (/*@exposed@*/ sRef s, exprNode f, sRef alias, exprNode err)
1152 {
1153   bool hasMods = context_hasMods ();
1154   flagcode errCode = hasMods ? FLG_MODIFIES : FLG_MODNOMODS;
1155
1156   if (exprNode_isDefined (f))
1157     {
1158       f->sets = sRefSet_insert (f->sets, s); 
1159     }
1160
1161   if (context_getFlag (FLG_MODIFIES) 
1162       && (hasMods || context_getFlag (FLG_MODNOMODS)))
1163     {
1164       sRefSet mods = context_modList ();
1165
1166       if (!sRef_canModify (s, mods))
1167         {
1168           sRef rb = sRef_getRootBase (s);
1169           
1170           
1171           if (sRef_isFileOrGlobalScope (rb))
1172             {
1173               if (!context_checkGlobMod (rb))
1174                 {
1175                   return FALSE;
1176                 }
1177             }
1178           
1179           if (sRef_isInvalid (alias) || sRef_sameName (s, alias))
1180             {
1181               if (sRef_isLocalVar (sRef_getRootBase (s)))
1182                 {
1183                   voptgenerror 
1184                     (errCode,
1185                      message 
1186                      ("Undocumented modification of internal state (%q): %s", 
1187                       sRef_unparse (s), exprNode_unparse (err)), 
1188                      exprNode_isDefined (f) ? f->loc : g_currentloc);
1189                 }
1190               else
1191                 {
1192                   if (sRef_isSystemState (s))
1193                     {
1194                       if (errCode == FLG_MODNOMODS) 
1195                         {
1196                           if (context_getFlag (FLG_MODNOMODS))
1197                             {
1198                               errCode = FLG_MODFILESYSTEM;
1199                             }
1200                         }
1201                       else
1202                         {
1203                           errCode = FLG_MODFILESYSTEM;
1204                         }
1205                     }
1206
1207                   voptgenerror 
1208                     (errCode,
1209                      message ("Undocumented modification of %q: %s", 
1210                               sRef_unparse (s), exprNode_unparse (err)), 
1211                      exprNode_isDefined (f) ? f->loc : g_currentloc);
1212                 }
1213               
1214               return TRUE;
1215             }
1216           else
1217             {
1218               if (sRef_isReference (s) && !sRef_isAddress (alias))
1219                 {
1220                   voptgenerror 
1221                     (errCode,
1222                      message
1223                      ("Possible undocumented modification of %q through alias %q: %s", 
1224                       sRef_unparse (s),
1225                       sRef_unparse (alias),
1226                       exprNode_unparse (err)),
1227                      exprNode_isDefined (f) ? f->loc : g_currentloc);
1228                   return TRUE;
1229                 }
1230             }
1231         }
1232     }
1233   else
1234     {
1235       if (context_maybeSet (FLG_MUSTMOD))
1236         {
1237           (void) sRef_canModify (s, context_modList ());
1238         }
1239       
1240       if (sRef_isRefsField (s))
1241         {
1242           sRef_setModified (s);
1243         }
1244     }
1245   
1246   return FALSE;
1247 }
1248
1249 static
1250 bool checkModifyAux (/*@exposed@*/ sRef s, exprNode f, sRef alias, exprNode err)
1251 {
1252   DPRINTF (("Check modify aux: %s", sRef_unparseFull (s)));
1253
1254   if (sRef_isReference (s) && sRef_isObserver (s) 
1255       && context_maybeSet (FLG_MODOBSERVER))
1256     {    
1257       cstring sname;
1258       
1259       if (sRef_isPointer (s)) 
1260         {
1261           sRef base = sRef_getBase (s);
1262           sname = sRef_unparse (base);
1263         }
1264       else 
1265         {
1266           if (sRef_isAddress (s))
1267             {
1268               sRef p = sRef_constructPointer (s);
1269               sname = sRef_unparse (p);
1270             }
1271           else
1272             {
1273               sname = sRef_unparse (s);
1274             }
1275         }
1276       
1277       if (!sRef_isValid (alias) || sRef_sameName (s, alias))
1278         {
1279           if (sRef_isMeaningful (s))
1280             {
1281               if (optgenerror 
1282                   (FLG_MODOBSERVER,
1283                    message ("Suspect modification of observer %s: %s", 
1284                             sname, exprNode_unparse (err)), 
1285                    exprNode_isDefined (f) ? f->loc : g_currentloc))
1286                 {
1287                   sRef_showExpInfo (s);
1288                 }
1289             }
1290           else
1291             {
1292               voptgenerror 
1293                 (FLG_MODOBSERVER,
1294                  message ("Suspect modification of observer returned by "
1295                           "function call: %s", 
1296                           exprNode_unparse (err)), 
1297                  exprNode_isDefined (f) ? f->loc : g_currentloc);
1298             }
1299         }
1300       else
1301         {
1302           if (optgenerror
1303               (FLG_MODOBSERVER,
1304                message ("Suspect modification of observer %s through alias %q: %s", 
1305                         sname, sRef_unparse (alias), exprNode_unparse (err)), 
1306                exprNode_isDefined (f) ? f->loc : g_currentloc))
1307             {
1308               sRef_showExpInfo (s);
1309             }
1310         }
1311       
1312       cstring_free (sname);
1313     }
1314   
1315   (void) checkModifyAuxAux (s, f, alias, err);
1316   return FALSE;
1317 }
1318
1319 static
1320 bool checkModifyValAux (/*@exposed@*/ sRef s, exprNode f, sRef alias, exprNode err)
1321 {
1322   (void) checkModifyAuxAux (s, f, alias, err);
1323   return FALSE;
1324 }
1325
1326 static
1327 bool checkCallModifyAux (/*@exposed@*/ sRef s, exprNode f, sRef alias, exprNode err)
1328 {
1329   bool result = FALSE;
1330
1331   DPRINTF (("Check modify aux: %s / %s",
1332             sRef_unparse (s), sRef_unparse (alias)));
1333
1334   if (sRef_isObserver (s) && context_maybeSet (FLG_MODOBSERVER))
1335     {    
1336       sRef p = sRef_isAddress (s) ? sRef_constructPointer (s) : s;
1337       cstring sname = sRef_unparse (p);
1338
1339       if (!sRef_isValid (alias) || sRef_sameName (s, alias))
1340         {
1341           if (sRef_isMeaningful (s))
1342             {
1343               result = optgenerror 
1344                 (FLG_MODOBSERVER,
1345                  message ("Suspect modification of observer %s: %s", 
1346                           sname, exprNode_unparse (err)), 
1347                  exprNode_isDefined (f) ? f->loc : g_currentloc);
1348             }
1349           else
1350             {
1351               result = optgenerror 
1352                 (FLG_MODOBSERVER,
1353                  message ("Suspect modification of observer returned by "
1354                           "function call: %s", 
1355                           exprNode_unparse (err)), 
1356                  exprNode_isDefined (f) ? f->loc : g_currentloc);
1357             }
1358         }
1359       else
1360         {
1361           result = optgenerror 
1362             (FLG_MODOBSERVER,
1363              message
1364              ("Suspect modification of observer %s through alias %q: %s", 
1365               sname, sRef_unparse (alias), exprNode_unparse (err)), 
1366              exprNode_isDefined (f) ? f->loc : g_currentloc);
1367         }
1368       
1369       cstring_free (sname);
1370     }
1371   else if (context_maybeSet (FLG_MODIFIES))
1372     {
1373       DPRINTF (("can modify: %s / %s",
1374                 sRef_unparse (s),
1375                 sRefSet_unparse (context_modList ())));
1376
1377       if (!(sRef_canModifyVal (s, context_modList ())))
1378         {
1379           sRef p = sRef_isAddress (s) ? sRef_constructPointer (s) : s;
1380           cstring sname = sRef_unparse (p);
1381           bool hasMods = context_hasMods ();
1382           sRef rb = sRef_getRootBase (s);
1383           flagcode errCode = hasMods ? FLG_MODIFIES : FLG_MODNOMODS;
1384           bool check = TRUE;
1385
1386           DPRINTF (("Can't modify! %s", sRef_unparse (s)));
1387
1388           if (sRef_isFileOrGlobalScope (rb))
1389             {
1390               uentry ue = sRef_getUentry (rb);
1391               
1392               /* be more specific here! */
1393               if (!uentry_isCheckedModify (ue))
1394                 {
1395                   check = FALSE;
1396                 }
1397             }
1398           
1399           if (check)
1400             {
1401               if (!sRef_isValid (alias) || sRef_sameName (s, alias))
1402                 {
1403                   if (sRef_isLocalVar (sRef_getRootBase (s)))
1404                     {
1405                       voptgenerror 
1406                         (errCode,
1407                          message 
1408                          ("Undocumented modification of internal "
1409                           "state (%q) through call to %s: %s", 
1410                           sRef_unparse (s), exprNode_unparse (f),
1411                           exprNode_unparse (err)), 
1412                          exprNode_isDefined (f) ? f->loc : g_currentloc);
1413                     }
1414                   else
1415                     {
1416                       if (sRef_isSystemState (s))
1417                         {
1418                           if (errCode == FLG_MODNOMODS) 
1419                             {
1420                               if (context_getFlag (FLG_MODNOMODS))
1421                                 {
1422                                   errCode = FLG_MODFILESYSTEM;
1423                                 }
1424                             }
1425                           else
1426                             {
1427                               errCode = FLG_MODFILESYSTEM;
1428                             }
1429                         }
1430                       
1431                       result = optgenerror 
1432                         (errCode,
1433                          message ("Undocumented modification of %s "
1434                                   "possible from call to %s: %s", 
1435                                   sname,
1436                                   exprNode_unparse (f),
1437                                   exprNode_unparse (err)),
1438                          exprNode_isDefined (f) ? f->loc : g_currentloc);
1439                     }
1440                 }
1441               else
1442                 {
1443                   result = optgenerror
1444                     (errCode,
1445                      message ("Undocumented modification of %s possible "
1446                               "from call to %s (through alias %q): %s", 
1447                               sname,
1448                               exprNode_unparse (f), 
1449                               sRef_unparse (alias), 
1450                               exprNode_unparse (err)),
1451                      exprNode_isDefined (f) ? f->loc : g_currentloc);
1452                 }
1453             }
1454           cstring_free (sname);
1455         }
1456     }
1457   else
1458     {
1459       if (context_maybeSet (FLG_MUSTMOD))
1460         {
1461           (void) sRef_canModifyVal (s, context_modList ());
1462         }
1463     }
1464
1465   return result;
1466 }
1467
1468 void exprNode_checkCallModifyVal (sRef s, exprNodeList args, exprNode f, exprNode err)
1469 {
1470   s = sRef_fixBaseParam (s, args);
1471   DPRINTF (("Check call modify: %s", sRef_unparse (s)));
1472   sRef_aliasCheckPred (checkCallModifyAux, NULL, s, f, err);
1473 }
1474
1475 void
1476 exprChecks_checkExport (uentry e)
1477 {
1478   if (context_checkExport (e))
1479     {
1480       fileloc fl = uentry_whereDeclared (e);
1481       
1482       if (fileloc_isHeader (fl) && !fileloc_isLib (fl) 
1483           && !fileloc_isImport (fl) && !uentry_isStatic (e))
1484         {
1485           if (uentry_isFunction (e) || 
1486               (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))))
1487             {
1488               voptgenerror 
1489                 (FLG_EXPORTFCN,
1490                  message ("Function exported, but not specified: %q", 
1491                           uentry_getName (e)),
1492                  fl);
1493             }
1494           else if (uentry_isExpandedMacro (e))
1495             {
1496               voptgenerror
1497                 (FLG_EXPORTMACRO,
1498                  message ("Expanded macro exported, but not specified: %q", 
1499                           uentry_getName (e)),
1500                  fl);
1501             }
1502           else if (uentry_isVariable (e) && !uentry_isParam (e)) 
1503             {
1504               voptgenerror 
1505                 (FLG_EXPORTVAR,
1506                  message ("Variable exported, but not specified: %q", 
1507                           uentry_getName (e)),
1508                  fl);
1509             }
1510           else if (uentry_isEitherConstant (e))
1511             {
1512               voptgenerror 
1513                 (FLG_EXPORTCONST,
1514                  message ("Constant exported, but not specified: %q", 
1515                           uentry_getName (e)),
1516                  fl);
1517             }
1518           else if (uentry_isIter (e) || uentry_isEndIter (e))
1519             {
1520               voptgenerror 
1521                 (FLG_EXPORTITER,
1522                  message ("Iterator exported, but not specified: %q", 
1523                           uentry_getName (e)),
1524                  fl);
1525             }
1526
1527           else if (uentry_isDatatype (e))
1528             {
1529               ; /* error already reported */
1530             }
1531           else
1532             {
1533               BADEXIT;
1534             }
1535         }
1536     }
1537 }
1538
1539 static void checkSafeReturnExpr (/*@notnull@*/ exprNode e)
1540 {
1541   ctype tr = ctype_getReturnType (context_currentFunctionType ());
1542   ctype te = exprNode_getType (e);
1543
1544   /* evans 2001-08-21: added test to warn about void returns from void functions */
1545   if (ctype_isVoid (tr))
1546     {
1547       (void) gentypeerror
1548         (te, e, tr, exprNode_undefined,
1549          message ("Return expression from function declared void: %s", exprNode_unparse (e)),
1550          e->loc);
1551       return;
1552     }
1553
1554   if (!ctype_forceMatch (tr, te) && !exprNode_matchLiteral (tr, e))
1555     {
1556       (void) gentypeerror
1557         (te, e, tr, exprNode_undefined,
1558          message ("Return value type %t does not match declared type %t: %s",
1559                   te, tr, exprNode_unparse (e)),
1560          e->loc);
1561     }
1562   else
1563     {
1564       sRef ret = e->sref;
1565       uentry rval = context_getHeader ();
1566       sRef resultref = uentry_getSref (rval);
1567
1568       DPRINTF (("Check return: %s / %s / %s",
1569                 exprNode_unparse (e),
1570                 sRef_unparseFull (e->sref),
1571                 uentry_unparse (rval)));
1572
1573       transferChecks_return (e, rval);
1574
1575       DPRINTF (("After return: %s / %s / %s",
1576                 exprNode_unparse (e),
1577                 sRef_unparseFull (e->sref),
1578                 uentry_unparse (rval)));
1579
1580       if (!(sRef_isExposed (uentry_getSref (context_getHeader ()))
1581             || sRef_isObserver (uentry_getSref (context_getHeader ())))
1582           && (context_getFlag (FLG_RETALIAS) 
1583               || context_getFlag (FLG_RETEXPOSE)))
1584         {
1585           sRef base = sRef_getRootBase (ret);
1586           ctype rtype = e->typ;
1587
1588           if (ctype_isUnknown (rtype))
1589             {
1590               rtype = tr;
1591             }
1592
1593           if (ctype_isVisiblySharable (rtype))
1594             {
1595               if (context_getFlag (FLG_RETALIAS))
1596                 {
1597                   sRef_aliasCheckPred (checkRefGlobParam, NULL, base, 
1598                                        e, exprNode_undefined);
1599                 }
1600               
1601               if (context_getFlag (FLG_RETEXPOSE) && sRef_isIReference (ret) 
1602                   && !sRef_isExposed (resultref) && !sRef_isObserver (resultref))
1603                 {
1604                   sRef_aliasCheckPred (checkRepExposed, NULL, base, e, 
1605                                        exprNode_undefined);
1606                 }
1607             }
1608         }
1609     }
1610 }
1611
1612
1613
1614
1615
This page took 0.16704 seconds and 5 git commands to generate.