]> andersk Git - splint.git/blob - src/transferChecks.c
Fixed problem with NULL being changed.
[splint.git] / src / transferChecks.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 ** transferChecks.c
26 */
27
28 # include "splintMacros.nf"
29 # include "basic.h"
30 # include "transferChecks.h"
31
32 /* transfer types: */
33 typedef enum
34 {
35   TT_FCNRETURN,
36   TT_DOASSIGN,
37   TT_FIELDASSIGN,
38   TT_FCNPASS,
39   TT_GLOBPASS,
40   TT_GLOBRETURN,
41   TT_PARAMRETURN,
42   TT_LEAVETRANS,
43   TT_GLOBINIT
44 } transferKind;
45
46 static void checkStructTransfer (exprNode p_lhs, sRef p_slhs, exprNode p_rhs, sRef p_srhs,
47                                  fileloc p_loc, transferKind p_tt);
48 static void checkMetaStateConsistent (/*@exposed@*/ sRef p_fref, sRef p_tref, 
49                                       fileloc p_loc, transferKind p_transferType) ;
50
51 static void checkLeaveTrans (uentry p_actual, transferKind p_transferType);
52 static void checkTransfer (exprNode p_fexp, /*@dependent@*/ sRef p_fref,
53                            exprNode p_texp, /*@dependent@*/ sRef p_tref, 
54                            exprNode p_fcn, /* for printing better error messages */
55                            fileloc p_loc, transferKind p_transferType);
56 static void checkGlobTrans (uentry p_glob, transferKind p_type);
57
58 static ynm
59 checkCompletelyDefined (exprNode p_fexp, /*@exposed@*/ sRef p_fref, sRef p_ofref,
60                         exprNode p_texp, sRef p_tref,
61                         bool p_topLevel, bool p_inUnion, bool p_directUnion,
62                         fileloc p_loc, transferKind p_transferType, int p_depth,
63                         bool p_report);
64
65 static /*@exposed@*/ sRef dependentReference (sRef p_sr);
66 static bool canLoseLocalReference (/*@dependent@*/ sRef p_sr, fileloc p_loc) ;
67
68 /*
69 ** returns the most specific alkind
70 */
71
72 alkind alkind_resolve (alkind a1, alkind a2)
73 {
74   if (a1 == AK_UNKNOWN || a1 == AK_ERROR) return a2;
75   if (a2 == AK_UNKNOWN || a2 == AK_ERROR || a2 == AK_LOCAL) return a1;
76   if (a1 == AK_LOCAL) return a2;
77   return a1;
78 }
79
80 /*
81 ** tref <- fref
82 **
83 ** transferType:
84 **   FCNRETURN   return fref; tref is return type
85 **   GLOBASSIGN  tref = fref; 
86 **   FCNPASS     call (fref) ; tref is the argument type
87 **
88 */
89
90 static /*@only@*/ cstring
91 transferErrorMessage (transferKind transferType, alkind tkind) /*@*/ 
92 {
93   switch (transferType)
94     {
95     case TT_FCNRETURN:
96       return (message ("returned as %s", alkind_unparse (tkind)));
97     case TT_DOASSIGN:
98       return (message ("assigned to %s", alkind_unparse (tkind)));
99     case TT_FIELDASSIGN:
100       return (message ("assigned to %s", alkind_unparse (tkind)));
101     case TT_GLOBINIT:
102       return (message ("used as initial value for %s", 
103                        alkind_unparse (tkind)));
104     case TT_FCNPASS:
105       return (message ("passed as %s param", alkind_unparse (tkind)));
106     BADDEFAULT;
107     }
108   BADEXIT;
109 }
110
111 static /*@only@*/ cstring
112 transferErrorExcerpt (transferKind transferType, exprNode fexp, exprNode texp, exprNode fcn) /*@*/ 
113 {
114   switch (transferType)
115     {
116     case TT_FCNRETURN:
117       return (message ("return %s", exprNode_unparse (fexp)));
118     case TT_FIELDASSIGN:
119     case TT_DOASSIGN:
120     case TT_GLOBINIT:
121       return (message ("%s = %s", exprNode_unparse (texp), exprNode_unparse (fexp)));
122     case TT_FCNPASS:
123       if (exprNode_isDefined (fcn))
124         {
125           return message ("%s(..., %s, ...)",
126                           exprNode_unparse (fcn),
127                           exprNode_unparse (fexp));
128         }
129       else
130         {
131           return cstring_copy (exprNode_unparse (fexp));  
132         }
133     BADDEFAULT;
134     }
135   BADEXIT;
136 }
137
138 static cstring
139 transferErrorExpMessage (transferKind transferType, exkind tkind) /*@*/
140 {
141   if (exkind_isUnknown (tkind))
142     {
143       switch (transferType)
144         {
145         case TT_FCNRETURN:
146           return (cstring_makeLiteral ("returned without qualification"));
147         case TT_FIELDASSIGN:
148         case TT_DOASSIGN:
149           return (cstring_makeLiteral ("assigned to unqualified reference"));
150         case TT_FCNPASS:
151           return (cstring_makeLiteral ("passed without qualification"));
152         case TT_GLOBINIT:
153           return (cstring_makeLiteral ("used as initial value for unqualified storage"));
154         BADDEFAULT;
155         }
156     }
157   else
158     {
159       switch (transferType)
160         {
161         case TT_FCNRETURN:
162           return (message ("returned as %s", exkind_unparse (tkind)));
163         case TT_FIELDASSIGN:
164         case TT_DOASSIGN:
165           return (message ("assigned to %s", exkind_unparse (tkind)));
166         case TT_FCNPASS:
167           return (message ("passed as %s param", exkind_unparse (tkind)));
168           BADDEFAULT;
169         }
170     }
171
172   BADEXIT;
173 }
174
175 static /*@observer@*/ cstring
176 transferNullMessage (transferKind transferType) /*@*/
177 {
178   switch (transferType)
179     {
180     case TT_FCNRETURN:
181       return (cstring_makeLiteralTemp ("returned as non-null"));
182     case TT_DOASSIGN:
183     case TT_FIELDASSIGN:
184       return (cstring_makeLiteralTemp ("assigned to non-null"));
185     case TT_GLOBINIT:
186       return (cstring_makeLiteralTemp ("initialized to non-null"));
187     case TT_FCNPASS:
188       return (cstring_makeLiteralTemp ("passed as non-null param"));
189     BADDEFAULT;
190     }
191   BADEXIT;
192 }
193
194 static /*@dependent@*/ exprNode atFunction = exprNode_undefined;
195 static int atArgNo = 0;
196 static int atNumArgs = 0;
197
198 static cstring generateText (exprNode e1, exprNode e2, 
199                              sRef tref, transferKind tt) 
200    /*@*/
201 {
202   if (tt == TT_DOASSIGN || tt == TT_GLOBINIT)
203     {
204       return (message ("%s = %s", exprNode_unparse (e2),
205                        exprNode_unparse (e1)));
206     }
207   else if (tt == TT_FIELDASSIGN)
208     {
209       return (message ("%s = %s (field %q)",
210                        exprNode_unparse (e2),
211                        exprNode_unparse (e1),
212                        sRef_unparse (tref)));
213     }
214   else if (tt == TT_FCNPASS)
215     {
216       return (message ("%s (%s%s%s)",
217                        exprNode_unparse (atFunction),
218                        (atArgNo == 1 ? cstring_undefined 
219                 : cstring_makeLiteralTemp ("..., ")),
220                        exprNode_unparse (e1),
221                        (atArgNo == atNumArgs ? cstring_undefined
222                         : cstring_makeLiteralTemp (", ..."))));
223     }
224   else
225     {
226       return (cstring_copy (exprNode_unparse (e1)));
227     }
228 }
229
230 static /*@observer@*/ cstring
231 transferType_unparse (transferKind transferType) /*@*/
232 {
233   switch (transferType)
234     {
235     case TT_FCNRETURN:
236       return (cstring_makeLiteralTemp ("Returned"));
237     case TT_DOASSIGN:
238     case TT_FIELDASSIGN:
239       return (cstring_makeLiteralTemp ("Assigned"));
240     case TT_FCNPASS:
241       return (cstring_makeLiteralTemp ("Passed"));
242     case TT_GLOBINIT:
243       return (cstring_makeLiteralTemp ("Initialized"));
244     case TT_GLOBRETURN:
245       return (cstring_makeLiteralTemp ("GLOB RETURN!"));
246     case TT_GLOBPASS:
247       return (cstring_makeLiteralTemp ("GLOB PASS!"));
248     case TT_PARAMRETURN:
249       return (cstring_makeLiteralTemp ("PARAM RETURN!"));
250     case TT_LEAVETRANS:
251       return (cstring_makeLiteralTemp ("LEAVE TRANS!"));
252     BADDEFAULT;
253     }
254   BADEXIT;
255 }
256
257 static /*@observer@*/ cstring udError (sRef s)
258 {
259   if (sRef_isDead (s))
260     {
261       return cstring_makeLiteralTemp ("released");
262     }
263   else if (sRef_isAllocated (s))
264     {
265       return cstring_makeLiteralTemp ("allocated but not defined");
266     }
267   else
268     {
269       return cstring_makeLiteralTemp ("undefined");
270     }
271 }
272
273 static /*@only@*/ 
274 cstring defExpl (sRef s) /*@*/
275 {
276   sRef rb = sRef_getRootBase (s);
277
278   if (sRef_sameName (rb, s))
279     {
280       if (sRef_isAllocated (s))
281         {
282           return cstring_makeLiteral (" (allocated only)");
283         }
284       return cstring_undefined;
285     }
286   else
287     {
288       return (message (" (%q is %s)", sRef_unparse (s), udError (s)));
289     }
290 }
291
292 /*
293 **
294 ** More than just definition checking --- checks for consistent state also!
295 **
296 ** Returns TRUE if fref is completely defined.
297 ** if !report, returns TRUE unless error is at the deep level.
298 */
299
300 static ynm
301 checkCompletelyDefined (exprNode fexp, /*@exposed@*/ sRef fref, sRef ofref,
302                         exprNode texp, sRef tref, 
303                         bool topLevel, bool inUnion, bool directUnion,
304                         fileloc loc, transferKind transferType,
305                         int depth, bool report)
306 {
307   ctype ct;
308   alkind fkind = sRef_getAliasKind (fref);
309   alkind tkind = sRef_getAliasKind (tref);
310   
311   DPRINTF (("Check completely defined: %s [%s] / %s [%s]",
312             exprNode_unparse (fexp), sRef_unparseFull (fref),
313             exprNode_unparse (texp), sRef_unparseFull (tref)));
314
315   if (depth > MAXDEPTH)
316     {
317       llquietbug
318         (message 
319          ("Check definition limit exceeded, checking %q. "
320           "This either means there is a variable with at least "
321           "%d indirections apparent in the program text, or "
322           "there is a bug in Splint.",
323           sRef_unparse (fref),
324           MAXDEPTH));
325
326       return YES;
327     }
328
329   if (!sRef_isKnown (fref))
330     {
331       return YES;
332     }
333
334   if (sRef_isDead (fref))
335     {
336       DPRINTF (("Dead storage to completely defined: %s", sRef_unparseFull (fref)));
337     }
338
339   if (alkind_isStack (fkind))
340     {
341       ctype rt = ctype_realType (sRef_getType (tref));
342
343       if (ctype_isMutable (rt) && !ctype_isSU (rt))
344         {
345           if (transferType == TT_PARAMRETURN)
346             {
347               if (optgenerror 
348                   (FLG_RETSTACK,
349                    message
350                    ("Stack-allocated storage %qreachable from parameter %q",
351                     sRef_unparseOpt (fref),
352                     sRef_unparse (ofref)),
353                    loc))
354                 {
355                   sRef_showAliasInfo (fref);
356                 }
357             }
358           else if (transferType == TT_GLOBRETURN)
359             {
360               if (optgenerror 
361                   (FLG_RETSTACK,
362                    message
363                    ("Stack-allocated storage %qreachable from global %q",
364                     sRef_unparseOpt (fref),
365                     sRef_unparse (ofref)),
366                    loc))
367                 {
368                   sRef_showAliasInfo (fref);
369                 }
370             }
371           else if (transferType == TT_FCNRETURN)
372             {
373               if (optgenerror 
374                   (FLG_RETSTACK,
375                    message 
376                    ("Stack-allocated storage %qreachable from return value: %s",
377                     sRef_unparseOpt (fref), 
378                     exprNode_unparse (fexp)),
379                    loc))
380                 {
381                   sRef_showAliasInfo (fref);
382                 }
383             }
384           else
385             {
386               /* no error */
387             }
388         }
389     }
390
391   if (!topLevel)
392     {
393       DPRINTF (("From: %s ==> %s",
394                 sRef_unparseFull (fref),
395                 sRef_unparseFull (tref)));
396       
397       checkMetaStateConsistent (fref, tref, loc, transferType);
398
399       if ((sRef_isObserver (fref) && !sRef_isObserver (tref))
400           || (sRef_isExposed (fref) && !(sRef_isObserver (tref) 
401                                          || sRef_isExposed (tref))))
402         {
403           flagcode code = (sRef_isObserver (fref) 
404                            ? FLG_OBSERVERTRANS : FLG_EXPOSETRANS);
405
406           if (!sRef_isStateLive (fref))
407             {
408               ; /* no error (will be a definition error) */
409             }
410           else if (transferType == TT_DOASSIGN
411                    || transferType == TT_FIELDASSIGN
412                    || transferType == TT_GLOBINIT
413                    || transferType == TT_FCNPASS)
414             {
415               ; /* no error */
416             }
417           else if (transferType == TT_PARAMRETURN)
418             {
419               if (optgenerror 
420                   (code,
421                    message
422                    ("%s storage %qreachable from %s parameter",
423                     exkind_capName (sRef_getExKind (fref)),
424                     sRef_unparseOpt (fref), 
425                     exkind_unparseError (sRef_getExKind (tref))),
426                    loc))
427                 {
428                   sRef_showExpInfo (fref);
429                   sRef_setExKind (fref, XO_UNKNOWN, loc);
430                 }
431             }
432           else if (transferType == TT_LEAVETRANS)
433             {
434               ;
435             }
436           else if (transferType == TT_GLOBINIT)
437             {
438               if (optgenerror 
439                   (code,
440                    message 
441                    ("%s storage %qreachable from %s initial value",
442                     exkind_capName (sRef_getExKind (fref)),
443                     sRef_unparseOpt (fref), 
444                     exkind_unparseError (sRef_getExKind (tref))),
445                    loc))
446                 {
447                   sRef_showExpInfo (fref);
448                   sRef_setExKind (fref, XO_UNKNOWN, loc);
449                 }
450             }
451           else if (transferType == TT_GLOBRETURN)
452             {
453               if (optgenerror 
454                   (code,
455                    message
456                    ("%s storage %qreachable from %s global",
457                     exkind_capName (sRef_getExKind (fref)),
458                     sRef_unparseOpt (fref), 
459                     exkind_unparseError (sRef_getExKind (tref))),
460                    loc))
461                 {
462                   sRef_showExpInfo (fref);
463                   sRef_setExKind (fref, XO_UNKNOWN, loc);
464                 }
465             }
466           else if (transferType == TT_FCNRETURN)
467             {
468               if (optgenerror 
469                   (code,
470                    message 
471                    ("%s storage %qreachable from %s return value",
472                     exkind_capName (sRef_getExKind (fref)),
473                     sRef_unparseOpt (fref), 
474                     exkind_unparseError (sRef_getExKind (tref))),
475                    loc))
476                 {
477                   sRef_showExpInfo (fref);
478                   sRef_setExKind (fref, XO_UNKNOWN, loc);
479                 }
480             }
481           else
482             {
483               llcontbug (message ("Transfer type: %s", 
484                                   transferType_unparse (transferType)));
485               
486               if (optgenerror 
487                   (code,
488                    message
489                    ("%s storage %qreachable from %s return value",
490                     exkind_capName (sRef_getExKind (fref)),
491                     sRef_unparseOpt (fref), 
492                     exkind_unparseError (sRef_getExKind (tref))),
493                    loc))
494                 {
495                   sRef_showExpInfo (fref);
496                   sRef_setExKind (fref, XO_UNKNOWN, loc);
497                 }
498             }
499
500         }
501       
502       if (!alkind_compatible (fkind, tkind))
503         {
504           if (fkind == AK_UNKNOWN && !sRef_isStateLive (fref))
505             {
506               ; /* no error (will be a definition error) */
507             }
508           else if (transferType == TT_DOASSIGN
509                    || transferType == TT_FIELDASSIGN) /* evans 2002-02-05 - added TT_FIELDASSIGN */
510             {
511               ; /* no error */
512             }
513           else if (transferType == TT_FCNPASS)
514             {
515               if (alkind_isKnown (sRef_getAliasKind (tref)))
516                 {
517                   if (optgenerror 
518                       (FLG_COMPMEMPASS,
519                        message
520                        ("Storage %qreachable from passed parameter "
521                         "is %s (should be %s): %s",
522                         sRef_unparseOpt (fref), 
523                         alkind_unparse (sRef_getAliasKind (fref)),
524                         alkind_unparse (sRef_getAliasKind (tref)),
525                         exprNode_unparse (fexp)),
526                        loc))
527                     {
528                       sRef_showAliasInfo (fref);
529                     }
530                 }
531             }
532           else if (transferType == TT_PARAMRETURN)
533             {
534               bool noerror = FALSE;
535
536               if (alkind_isDependent (sRef_getAliasKind (fref)))
537                 {
538                   if (canLoseLocalReference (fref, loc))
539                     {
540                       noerror = TRUE;
541                     }
542                 }
543
544               if (!noerror
545                   && optgenerror 
546                   (FLG_COMPMEMPASS,
547                    message
548                    ("Storage %qreachable from parameter is %s (should be %s)",
549                     sRef_unparseOpt (fref), 
550                     alkind_unparse (sRef_getAliasKind (fref)),
551                     alkind_unparse (sRef_getAliasKind (tref))),
552                    loc))
553                 {
554                   sRef_showAliasInfo (fref);
555                 }
556               }
557           else if (transferType == TT_LEAVETRANS)
558             {
559               if (optgenerror 
560                   (FLG_COMPMEMPASS,
561                    message
562                    ("Storage %qreachable from temporary reference is %s "
563                     "at scope exit (should be %s)",
564                     sRef_unparseOpt (fref), 
565                     alkind_unparse (sRef_getAliasKind (fref)),
566                     alkind_unparse (sRef_getAliasKind (tref))),
567                    loc))
568                 {
569                   sRef_showAliasInfo (fref);
570                 }
571               }
572           else if (transferType == TT_GLOBRETURN)
573             {
574               if (optgenerror 
575                   (FLG_COMPMEMPASS,
576                    message
577                    ("Storage %qreachable from global is %s (should be %s)",
578                     sRef_unparseOpt (fref), 
579                     alkind_unparse (sRef_getAliasKind (fref)),
580                     alkind_unparse (sRef_getAliasKind (tref))),
581                    loc))
582                 {
583                   sRef_showAliasInfo (fref);
584                 }
585             }
586           else if (transferType == TT_FCNRETURN)
587             {
588               if (optgenerror 
589                   (FLG_COMPMEMPASS,
590                    message 
591                    ("Storage %qreachable from return value is %s (should be %s)",
592                     sRef_unparseOpt (fref), 
593                     alkind_unparse (sRef_getAliasKind (fref)),
594                     alkind_unparse (sRef_getAliasKind (tref))),
595                    loc))
596                 {
597                   sRef_showAliasInfo (fref);
598                 }
599             }
600           else if (transferType == TT_GLOBINIT)
601             {
602               if (optgenerror 
603                   (FLG_COMPMEMPASS,
604                    message 
605                    ("Storage %qreachable from initial value is %s (should be %s)",
606                     sRef_unparseOpt (fref), 
607                     alkind_unparse (sRef_getAliasKind (fref)),
608                     alkind_unparse (sRef_getAliasKind (tref))),
609                    loc))
610                 {
611                   sRef_showAliasInfo (fref);
612                 }
613             }
614           else
615             {
616               llcontbug (message ("Transfer type: %s", 
617                                   transferType_unparse (transferType)));
618               
619               if (optgenerror 
620                   (FLG_COMPMEMPASS,
621                    message
622                    ("Storage %qreachable from return value is %s (should be %s)",
623                     sRef_unparseOpt (fref), 
624                     alkind_unparse (sRef_getAliasKind (fref)),
625                     alkind_unparse (sRef_getAliasKind (tref))),
626                    loc))
627                 {
628                   sRef_showAliasInfo (fref);
629                 }
630             }
631         }
632
633       if (sRef_isDead (fref))
634         {
635           if (directUnion)
636             {
637               return NO;
638             }
639
640           if (transferType == TT_PARAMRETURN)
641             {
642               if (optgenerror 
643                   (FLG_USERELEASED,
644                    message 
645                    ("Released storage %q reachable from parameter at return point",
646                     sRef_unparse (fref)),
647                    loc))
648                 {
649                   sRef_showStateInfo (fref);
650                   return YES;
651                 }
652               }
653           else if (transferType == TT_LEAVETRANS)
654             {
655               if (optgenerror 
656                   (FLG_USERELEASED,
657                    message ("Released storage %q reachable from temporary "
658                             "reference at scope exit",
659                             sRef_unparse (fref)),
660                    loc))
661                 {
662                   sRef_showStateInfo (fref);
663                   return YES;
664                 }
665               }
666           else if (transferType == TT_GLOBRETURN)
667             {
668               if (optgenerror 
669                   (FLG_GLOBSTATE,
670                    message ("Released storage %q reachable from global",
671                             sRef_unparse (fref)),
672                    loc))
673                 {
674                   sRef_showStateInfo (fref);
675                   return YES;
676                 }
677             }
678           else if (transferType == TT_FCNPASS)
679             {
680               if (optgenerror 
681                   (FLG_USERELEASED,
682                    message ("Released storage %q reachable from passed parameter",
683                             sRef_unparse (fref)),
684                    loc))
685                 {
686                   sRef_showStateInfo (fref);
687                   return YES;
688                 }
689             }
690           else
691             {
692               if (optgenerror 
693                   (FLG_USERELEASED,
694                    message ("Released storage %q reachable from parameter",
695                             sRef_unparse (fref)),
696                    loc))
697                 {
698                   sRef_showStateInfo (fref);
699                   return YES;
700                 }
701             }
702         }
703     }
704
705   if (!topLevel 
706       && sRef_possiblyNull (fref) 
707       && !sRef_perhapsNull (tref) 
708       && ctype_isRealPointer (sRef_getType (tref))
709       && !usymtab_isGuarded (fref))
710     {
711       if (transferType == TT_FCNRETURN)
712         {
713           if (optgenerror 
714               (FLG_NULLRET, 
715                message ("%q storage %qderivable from return value: %s", 
716                         cstring_capitalize (sRef_nullMessage (fref)),
717                         sRef_unparseOpt (fref),
718                         exprNode_unparse (fexp)),
719                loc))
720             {
721               sRef_showNullInfo (fref);
722
723               DPRINTF (("fref: %s", sRef_unparseFull (fref)));
724               DPRINTF (("tref: %s", sRef_unparseFull (tref)));
725
726               sRef_setNullError (fref);
727             }
728         }
729       else if (transferType == TT_GLOBRETURN || transferType == TT_PARAMRETURN)
730         {
731           if (optgenerror 
732               (FLG_NULLSTATE,
733                message 
734                ("Function returns with %s storage derivable from %q %q", 
735                 sRef_nullMessage (fref),
736                 cstring_makeLiteral ((transferType == TT_GLOBRETURN) 
737                                      ? "global" : "parameter"),
738                 sRef_unparse (fref)),
739                loc))
740             {
741               sRef_showNullInfo (fref);
742               sRef_setNullError (fref);
743             }
744         }
745       else if (transferType == TT_GLOBPASS)
746         {
747           if (optgenerror
748               (FLG_NULLPASS,
749                message ("Function called with %s storage "
750                         "derivable from global %q", 
751                         sRef_nullMessage (fref),
752                         sRef_unparse (fref)),
753                loc))
754             {
755               sRef_showNullInfo (fref);
756               sRef_setNullError (fref);
757             }
758         }
759       else if (transferType == TT_FCNPASS)
760         {
761           if (optgenerror
762               (FLG_NULLSTATE,
763                message ("%q storage %qderivable from parameter %q", 
764                         cstring_capitalize (sRef_nullMessage (fref)),
765                         sRef_unparseOpt (fref),
766                         generateText (fexp, exprNode_undefined, 
767                                       sRef_undefined, TT_FCNPASS)),
768                loc))
769             {
770               DPRINTF (("fref: %s", sRef_unparseFull (fref)));
771               DPRINTF (("tref: %s", sRef_unparseFull (tref)));
772               sRef_showNullInfo (fref);
773               sRef_setNullError (fref);
774             }
775         }
776       else
777         {
778           llassert (transferType == TT_DOASSIGN
779                     || transferType == TT_FIELDASSIGN /* evans 2002-02-05: no warnings for local fields */
780                     || transferType == TT_GLOBINIT
781                     || transferType == TT_LEAVETRANS);
782         }
783     }
784
785   if (sRef_isRelDef (tref) 
786       || sRef_isPartial (tref) 
787       || sRef_isAllocated (tref)
788       || sRef_isStateSpecial (tref))
789     {
790       /* should check fref is allocated? */
791       return YES;
792     }
793
794   ct = ctype_realType (sRef_getType (fref));
795
796   DPRINTF (("Here: %s", ctype_unparse (ct)));
797
798   if (!(sRef_isAnyDefined (fref) 
799         || sRef_isPdefined (fref)
800         || sRef_isAllocated (fref)
801         || sRef_isStateUnknown (fref)))
802     {
803       if (transferType == TT_GLOBRETURN)
804         {
805           if (report
806               && optgenerror 
807               (FLG_COMPDEF,
808                message ("Function returns with global %q not "
809                         "completely defined%q",
810                         sRef_unparse (sRef_getRootBase (fref)),
811                         defExpl (fref)),
812                loc))
813             {
814               sRef_showStateInfo (fref);
815               sRef_setDefined (fref, loc);
816             }
817         }
818       else if (transferType == TT_GLOBPASS)
819         {
820           if (report &&
821               optgenerror 
822               (FLG_COMPDEF,
823                message 
824                ("Function called with global %q not completely defined%q",
825                 sRef_unparse (sRef_getRootBase (fref)),
826                 defExpl (fref)),
827                loc))
828             {
829               sRef_showStateInfo (fref);
830               sRef_setDefined (fref, loc);
831             }
832         }
833       else if (transferType == TT_PARAMRETURN)
834         {
835           if (report && !topLevel
836               && optgenerror 
837               (FLG_COMPDEF,
838                message ("Function returns storage %q reachable from parameter not "
839                         "completely defined%q",
840                         sRef_unparse (ofref),
841                         defExpl (fref)),
842                loc))
843             {
844               sRef_showStateInfo (fref);
845               sRef_setDefined (fref, loc);
846             }
847         }
848       else if (transferType == TT_LEAVETRANS)
849         {
850           if (report && !topLevel
851               && optgenerror 
852               (FLG_COMPDEF,
853                message ("Scope exits with storage %q reachable from "
854                         "temporary reference not completely defined%q",
855                         sRef_unparse (ofref),
856                         defExpl (fref)),
857                loc))
858             {
859               sRef_showStateInfo (fref);
860               sRef_setDefined (fref, loc);
861             }
862         }
863       else 
864         {
865           if (transferType != TT_DOASSIGN
866               && (!(sRef_isNew (fref) || sRef_isType (fref))))
867             {
868               if (report)
869                 {
870                   DPRINTF (("Here we are: %s", sRef_unparseFull (fref)));
871
872                   if (sRef_isDead (fref))
873                     {
874                       if (optgenerror 
875                           (FLG_USERELEASED,
876                            message ("%s storage %qwas released: %q",
877                                     transferType_unparse (transferType),
878                                     sRef_unparseOpt (fref), 
879                                     generateText (fexp, texp, tref, transferType)),
880                            loc))
881                         {
882                           sRef_showStateInfo (fref);
883                         }
884                     }
885                   else 
886                     {
887                       if (optgenerror 
888                           (FLG_COMPDEF,
889                            message 
890                            ("%s storage %qnot completely defined%q: %q",
891                             transferType_unparse (transferType),
892                             sRef_unparseOpt (ofref),
893                             defExpl (fref),
894                             generateText (fexp, texp, tref, transferType)),
895                            loc))
896                         {
897                           sRef rb = sRef_getRootBase (fref);
898                           sRef_showStateInfo (fref);
899                           
900                           sRef_setDefinedCompleteDirect (rb, loc);
901                         }
902                     }
903                 }
904             }
905           else
906             {
907
908               if (sRef_isAllocated (fref) && sRef_isValid (tref) 
909                   && (transferType == TT_DOASSIGN))
910                 {
911                   sRef_setAllocatedComplete (tref, loc);
912                 }
913               return YES;
914             }
915         }
916
917       return NO;
918     }
919   
920   if (ctype_isUnknown (ct))
921     {
922       return YES;
923     }
924   else if (ctype_isPointer (ct) || ctype_isArray (ct)) /* evans 2001-07-12 added ctype_isArray */
925     {
926       ctype tct = ctype_realType (sRef_getType (tref));
927
928       if (sRef_isStateUnknown (fref))
929         {
930           return NO;
931         }
932       else
933         {
934           DPRINTF (("Here fref: %s", sRef_unparseFull (fref)));
935           DPRINTF (("Here tref: %s", sRef_unparseFull (tref)));
936
937           if (ctype_isAP (tct) || ctype_isUnknown (tct))
938             {
939               sRef fptr = sRef_constructDeref (fref);
940               sRef tptr = sRef_constructDeref (tref);
941
942               DPRINTF (("Here tptr: %s", sRef_unparseFull (tptr)));
943
944               return (checkCompletelyDefined (fexp, fptr, ofref,
945                                               texp, tptr,
946                                               FALSE, inUnion, FALSE, loc, 
947                                               transferType, depth + 1, report));
948             }
949           else
950             {
951               return YES;
952             }
953         }
954     }
955   else if (ctype_isStruct (ct))
956     {
957       ctype tct = ctype_realType (sRef_getType (tref));
958
959       DPRINTF (("Struct defined: %s", ctype_unparse (tct)));
960
961       if (ctype_match (ct, tct))
962         {
963           bool isOk = TRUE;
964           bool hasOneDefined = FALSE;
965           cstringSList badFields = cstringSList_undefined;
966           
967           if (sRef_isStateUnknown (fref) || sRef_isAllocated (tref)) 
968             {
969               return YES;
970             }
971           
972           DPRINTF (("Check field: %s", sRef_unparseFull (fref)));
973
974           if (sRef_isPdefined (fref) || sRef_isAnyDefined (fref))
975             {
976               DPRINTF (("Is defined: %s", sRef_unparse (fref)));
977
978               sRefSet_realElements (sRef_derivedFields (fref), sr)
979                 {
980                   bool thisField;
981                   
982                   hasOneDefined = TRUE;
983                   
984                   DPRINTF (("Check derived: %s", sRef_unparseFull (sr)));
985
986                   if (sRef_isField (sr))
987                     {
988                       cstring fieldname = sRef_getField (sr);
989                       sRef fldref = sRef_makeField (tref, fieldname);
990                       bool shouldCheck = !sRef_isRecursiveField (fldref);
991                         
992                       if (shouldCheck)
993                         {
994                           thisField = 
995                             ynm_toBoolRelaxed 
996                             (checkCompletelyDefined (fexp, sr, ofref,
997                                                      texp, fldref,
998                                                      FALSE, inUnion, FALSE, loc, 
999                                                      transferType, depth + 1, 
1000                                                      FALSE));
1001                         }
1002                       else
1003                         {
1004                           thisField = TRUE;
1005                         }
1006                       
1007                       if (!thisField)
1008                         {
1009                           isOk = FALSE;
1010                           badFields = cstringSList_add (badFields,
1011                                                         sRef_getField (sr));
1012                         }
1013                     }
1014                 } end_sRefSet_realElements;
1015             }
1016           else if (sRef_isAllocated (fref))
1017             {
1018               /*
1019               ** for structures, each field must be completely defined
1020               */
1021               
1022               uentryList fields = ctype_getFields (ct);
1023               
1024               uentryList_elements (fields, ue)
1025                 {
1026                   bool thisField;
1027                   cstring name = uentry_getRealName (ue);
1028                   sRef ffield = sRef_makeField (fref, name);
1029                   sRef tfield = sRef_makeField (tref, name);
1030                   bool shouldCheck = !sRef_isRecursiveField (tfield);
1031                   
1032                   if (!shouldCheck)
1033                     {
1034                       thisField = TRUE;
1035                     }
1036                   else
1037                     {
1038                       thisField = ynm_toBoolRelaxed
1039                         (checkCompletelyDefined (fexp, ffield, ofref,
1040                                                  texp, tfield,
1041                                                  FALSE, inUnion, FALSE,
1042                                                  loc, transferType,
1043                                                  depth + 1, FALSE));
1044                     }
1045                   
1046                   if (!thisField)
1047                     {
1048                       isOk = FALSE;
1049                       badFields = cstringSList_add (badFields, uentry_rawName (ue));
1050                     }
1051                   else
1052                     {
1053                       hasOneDefined = TRUE;
1054                     }
1055                 } end_uentryList_elements;
1056             }
1057           else
1058             {
1059               DPRINTF (("Not checking: %s", sRef_unparseFull (fref)));
1060             }
1061           
1062           if (!isOk && (!inUnion || hasOneDefined))
1063             {
1064               if (transferType == TT_GLOBRETURN)
1065                 {
1066                   if (optgenerror
1067                       (FLG_COMPDEF,
1068                        message ("Global storage %q contains %d undefined field%& "
1069                                 "when call returns: %q",
1070                                 sRef_unparse (fref),
1071                                 cstringSList_size (badFields),
1072                                 cstringSList_unparseAbbrev (badFields)),
1073                        loc))
1074                     {
1075                       sRef_setDefined (fref, loc);
1076                     }
1077                 }
1078               else if (transferType == TT_GLOBPASS)
1079                 {
1080                   if (optgenerror
1081                       (FLG_COMPDEF,
1082                        message ("Global storage %q contains %d undefined field%& "
1083                                 "before call: %q",
1084                                 sRef_unparse (fref),
1085                                 cstringSList_size (badFields),
1086                                 cstringSList_unparseAbbrev (badFields)),
1087                        loc))
1088                     {
1089                       sRef_setDefined (fref, loc);
1090                     }
1091                 }
1092               else if (transferType == TT_PARAMRETURN)
1093                 {
1094                   if (optgenerror
1095                       (FLG_COMPDEF,
1096                        message ("Storage %qreachable from parameter "
1097                                 "contains %d undefined field%&: %q",
1098                                 sRef_unparseOpt (fref),
1099                                 cstringSList_size (badFields),
1100                                 cstringSList_unparseAbbrev (badFields)),
1101                        loc))
1102                     {
1103                       sRef_setDefined (fref, loc);
1104                     }
1105                 }
1106               else if (transferType == TT_LEAVETRANS)
1107                 {
1108                   /* no error */
1109                 }
1110               else
1111                 {
1112                   if (optgenerror
1113                       (FLG_COMPDEF,
1114                        message ("%s storage %qcontains %d undefined field%&: %q",
1115                                 transferType_unparse (transferType),
1116                                 sRef_unparseOpt (fref),
1117                                 cstringSList_size (badFields),
1118                                 cstringSList_unparseAbbrev (badFields)),
1119                        loc))
1120                     {
1121                       sRef_setDefined (fref, loc);
1122                     }
1123                 }
1124             }
1125           
1126           cstringSList_free (badFields);
1127           
1128           if (inUnion)
1129             {
1130               if (directUnion)
1131                 {
1132                   return (ynm_fromBool (hasOneDefined));
1133                 }
1134               else
1135                 {
1136                   return (MAYBE);
1137                 }
1138             }
1139           else
1140             {
1141               return (ynm_fromBool (!report || isOk));
1142             }
1143         }
1144       else
1145         {
1146           return YES;
1147         }
1148     }
1149   else if (ctype_isUnion (ct))
1150     {
1151       if (sRef_isStateUnknown (fref) || sRef_isAllocated (tref)) 
1152         {
1153           return YES;
1154         }
1155       else 
1156         {
1157           ctype tct = ctype_realType (sRef_getType (tref));
1158           
1159           if (ctype_isKnown (tct) && ctype_match (ct, tct))
1160             {
1161               cstringSList goodFields = cstringSList_new ();
1162               bool isOk = FALSE;
1163               int nelements = sRefSet_size (sRef_derivedFields (fref));       
1164
1165               /*
1166               ** for unions, at least one field must be completely defined
1167               */
1168               
1169               if (sRef_isPdefined (fref) || sRef_isAnyDefined (fref))
1170                 {
1171                   isOk = TRUE;
1172                 }
1173               
1174               sRefSet_realElements (sRef_derivedFields (fref), sr)
1175                 {
1176                   bool thisField;
1177
1178                   if (sRef_isField (sr))
1179                     {
1180                       sRef fldref = sRef_makeField (tref, sRef_getField (sr));
1181
1182                       DPRINTF (("Trying union field: %s", sRef_unparseFull (fldref)));
1183
1184                       thisField = ynm_toBoolStrict 
1185                         (checkCompletelyDefined 
1186                          (fexp, sr, ofref,
1187                           texp, fldref, FALSE, inUnion, 
1188                           (nelements > 1 ? TRUE : FALSE),
1189                           loc, transferType, depth + 1, FALSE));
1190                       
1191                       if (thisField)
1192                         {
1193                           goodFields = cstringSList_add 
1194                             (goodFields, sRef_getField (sr));
1195                         }
1196                     }
1197                 } end_sRefSet_realElements;
1198               
1199               if (cstringSList_empty (goodFields) 
1200                   && !isOk 
1201                   && context_getFlag (FLG_UNIONDEF))
1202                 {
1203                   if (!inUnion)
1204                     {
1205                       if (transferType == TT_PARAMRETURN)
1206                         {
1207                           voptgenerror 
1208                             (FLG_UNIONDEF,
1209                              message ("Union %q reachable from parameter has "
1210                                       "no defined field",
1211                                       sRef_unparse (fref)),
1212                              loc);
1213                         }
1214                       else if (transferType == TT_LEAVETRANS)
1215                         {
1216                           voptgenerror 
1217                             (FLG_UNIONDEF,
1218                              message ("Union %q has no defined field at scope exit",
1219                                       sRef_unparse (fref)),
1220                              loc);
1221                         }
1222                       /* evans 2001-08-21: added this branch for global returns */
1223                       else if (transferType == TT_GLOBRETURN)
1224                         {
1225                           voptgenerror 
1226                             (FLG_UNIONDEF,
1227                              message ("Union %q reachable from global %q has "
1228                                       "no defined field",
1229                                       sRef_unparse (fref),
1230                                       sRef_unparse (sRef_getRootBase (fref))),
1231                              loc);
1232                         }
1233                       else if (transferType == TT_DOASSIGN
1234                                || transferType == TT_FIELDASSIGN
1235                                || transferType == TT_GLOBINIT)
1236                         {
1237                           ; /* no error */
1238                         }
1239                       else
1240                         {
1241                           voptgenerror 
1242                             (FLG_UNIONDEF,
1243                              message ("%s union %q has no defined field",
1244                                       transferType_unparse (transferType),
1245                                       sRef_unparse (fref)),
1246                              loc);
1247                         }
1248                     }
1249                   isOk = FALSE;
1250                 }
1251               
1252               cstringSList_free (goodFields);
1253               return ynm_fromBool (!report || isOk);
1254             }
1255         }
1256     }
1257   else
1258     {
1259       ;
1260     }
1261
1262   return YES;
1263 }
1264
1265 /*
1266 ** fref is being free'd
1267 */
1268
1269 typedef enum {
1270   DSC_GLOB, DSC_LOCAL, DSC_PARAM, DSC_STRUCT
1271   } dscCode;
1272
1273 static /*@observer@*/ cstring dscCode_unparse (dscCode desc) /*@*/
1274 {
1275   switch (desc)
1276     {
1277     case DSC_GLOB:
1278       return cstring_makeLiteralTemp ("killed global");
1279     case DSC_LOCAL:
1280       return cstring_makeLiteralTemp ("variable declared in this scope");
1281     case DSC_PARAM:
1282       return cstring_makeLiteralTemp ("released storage");
1283     case DSC_STRUCT:
1284       return cstring_makeLiteralTemp ("released structure parameter");
1285     }
1286
1287   BADEXIT;
1288 }
1289
1290 static bool 
1291 checkCompletelyDestroyed (exprNode p_fexp, sRef p_fref, bool p_topLevel, bool p_isField,
1292                           fileloc p_loc, int p_depth, dscCode p_desc,
1293                           bool p_hideErrors);
1294
1295 bool transferChecks_globalDestroyed (sRef fref, fileloc loc)
1296 {
1297   DPRINTF (("Global destroyed: %s", sRef_unparseFull (fref)));
1298   return (checkCompletelyDestroyed (exprNode_undefined, fref, TRUE, FALSE,
1299                                     loc, 0, DSC_GLOB, FALSE));
1300 }
1301
1302 void transferChecks_localDestroyed (sRef fref, fileloc loc)
1303 {
1304   if (sRef_isObserver (fref) || sRef_isExposed (fref)
1305       || sRef_isPartial (fref))
1306     {
1307       ;
1308     }
1309   else
1310     {
1311       (void) checkCompletelyDestroyed (exprNode_undefined, fref, TRUE, FALSE,
1312                                        loc, 0, DSC_LOCAL, FALSE);
1313     }
1314 }
1315
1316 void transferChecks_structDestroyed (sRef fref, fileloc loc)
1317 {
1318   DPRINTF (("Check struct destroyed: %s", sRef_unparse (fref)));
1319
1320   if (sRef_isObserver (fref) || sRef_isExposed (fref)
1321       || sRef_isPartial (fref))
1322     {
1323       DPRINTF (("Its exposed!"));;
1324     }
1325   else
1326     {
1327       (void) checkCompletelyDestroyed (exprNode_undefined, fref, TRUE, FALSE,
1328                                        loc, 0, DSC_STRUCT, FALSE);
1329     }
1330 }
1331
1332 static bool
1333 checkCompletelyDestroyed (exprNode fexp, sRef fref, bool topLevel, bool isField,
1334                           fileloc loc, int depth,
1335                           dscCode desc, bool hideErrors)
1336 {
1337   ctype ct;
1338   
1339   DPRINTF (("Check completely destroyed: %s / %s",
1340             sRef_unparse (fref),
1341             bool_unparse (hideErrors)));
1342
1343   if (depth > MAXDEPTH)
1344     {
1345       llquietbug (message ("checkCompletelyDestroyed: too deep: %s / %q", 
1346                            exprNode_unparse (fexp),
1347                            sRef_unparseFull (fref)));
1348       return TRUE;
1349     }
1350
1351   if (!sRef_isKnown (fref)) return TRUE;
1352
1353   /* evans 2001-03-24: added this.  Definitely null values are always destroyed. */
1354
1355   if (sRef_isDefinitelyNull (fref))
1356     {
1357       return TRUE;
1358     }
1359
1360   if (sRef_isDependent (fref) || sRef_isShared (fref) || sRef_isKept (fref))
1361     {
1362       return TRUE;
1363     }
1364
1365   {
1366     /*
1367     ** evans 2001-03-24: if there is a dependent reference to this storage,
1368     **    no need to destroy, but make it responsible.
1369     */
1370                                                          
1371     sRef depRef = dependentReference (fref);
1372
1373     DPRINTF (("Destroyed? %s / %s",
1374               sRef_unparseFull (fref),
1375               sRef_unparseFull (depRef)));
1376
1377     DPRINTF (("Aliases: %s", usymtab_unparseAliases ()));
1378
1379     if (sRef_isValid (depRef))
1380       {
1381         /*
1382         ** If the referenced storage was not dependent, we make
1383         ** the reference the owner since it must eventually be
1384         ** destroyed.
1385         */
1386
1387         if (!sRef_isDependent (depRef)) 
1388           {
1389             sRef_setOnly (depRef, loc); /* could be owned? */
1390           }
1391
1392         sRef_kill (fref, loc);
1393         return TRUE;
1394       }
1395   }
1396
1397   ct = ctype_realType (sRef_getType (fref));
1398
1399   if (sRef_isPdefined (fref) 
1400       && ctype_isAP (ct)
1401       && !isField
1402       && !context_getFlag (FLG_STRICTDESTROY))
1403     {
1404       /*
1405       ** Don't report errors for array elements (unless strictdestroy)
1406       ** when at least one appears to have been destroyed.
1407       */
1408
1409       DPRINTF (("Partial: %s / hiding errors: %s", sRef_unparseFull (fref),
1410                 ctype_unparse (ct)));
1411       hideErrors = TRUE;
1412       /* Don't report any more errors, but still change ownership. */
1413     }
1414   
1415   if (usymtab_isDefinitelyNull (fref)) 
1416     {
1417       DPRINTF (("Probably null!"));
1418       return TRUE;
1419     }
1420
1421   /*
1422   ** evans 2002-01-02: removed this
1423   ** if (!context_flagOn (FLG_COMPDESTROY, loc)) 
1424   ** {
1425   ** return TRUE;
1426   ** }
1427   ** 
1428   ** if (!context_getFlag (FLG_MUSTFREEONLY)) return TRUE;
1429   */
1430   
1431   DPRINTF (("Here: %s", ctype_unparse (ct)));
1432
1433   if (!topLevel)
1434     {
1435       bool docheck = FALSE;
1436       bool reportederror;
1437
1438       if (sRef_isFresh (fref) || sRef_isOnly (fref))
1439         {
1440           docheck = TRUE;
1441           
1442           DPRINTF (("Here: %s", ctype_unparse (ct)));
1443           if (sRef_isDead (fref) 
1444               || sRef_isUnuseable (fref)
1445               || sRef_definitelyNull (fref)
1446               || sRef_isObserver (fref) 
1447               || sRef_isExposed (fref))
1448             {
1449               docheck = FALSE;
1450             }
1451         }
1452       
1453       if (docheck)
1454         {
1455           if (sRef_isPossiblyDead (fref) || sRef_isRelDef (fref))
1456             {
1457               if (exprNode_isDefined (fexp))
1458                 {
1459                   reportederror = 
1460                     !hideErrors 
1461                     && 
1462                     optgenerror2 
1463                     (FLG_COMPDESTROY, FLG_STRICTDESTROY,
1464                      message ("Only storage %q (type %s) derived from %s "
1465                               "may not have been released: %s",
1466                               sRef_unparse (fref), 
1467                               ctype_unparse (sRef_getType (fref)),
1468                               dscCode_unparse (desc),
1469                               exprNode_unparse (fexp)),
1470                      loc);
1471                 }
1472               else
1473                 {
1474                   reportederror =
1475                     !hideErrors
1476                     &&
1477                     optgenerror2 
1478                     (FLG_COMPDESTROY, FLG_STRICTDESTROY,
1479                      message 
1480                      ("Only storage %q (type %s) derived from %s "
1481                       "may not have been released",
1482                       sRef_unparse (fref), 
1483                       ctype_unparse (sRef_getType (fref)),
1484                       dscCode_unparse (desc)),
1485                      loc);
1486                 }
1487               
1488               if (reportederror)
1489                 {
1490                   sRef_kill (fref, loc); /* prevent further errors */
1491                 }
1492             }
1493           else 
1494             {
1495               if (sRef_isStateUndefined (fref))
1496                 {
1497                   DPRINTF (("Here: %s", ctype_unparse (ct)));
1498                   return TRUE;
1499                 }
1500               else
1501                 {
1502                   if (exprNode_isDefined (fexp))
1503                     {
1504                       DPRINTF (("Here: %s", sRef_unparseFull (fref)));
1505
1506                       reportederror =
1507                         !hideErrors
1508                         &&
1509                         optgenerror 
1510                         (FLG_COMPDESTROY,
1511                          message ("Only storage %q (type %s) derived from %s "
1512                                   "is not released (memory leak): %s",
1513                                   sRef_unparse (fref),
1514                                   ctype_unparse (sRef_getType (fref)),  
1515                                   dscCode_unparse (desc),
1516                                   exprNode_unparse (fexp)),
1517                          loc);
1518                     }
1519                   else
1520                     {
1521                       reportederror = 
1522                         !hideErrors
1523                         &&
1524                         optgenerror 
1525                         (FLG_COMPDESTROY,
1526                          message ("Only storage %q (type %s) derived from %s "
1527                                   "is not released (memory leak)",
1528                                   sRef_unparse (fref),
1529                                   ctype_unparse (sRef_getType (fref)),
1530                                   dscCode_unparse (desc)),
1531                          loc);
1532                     }
1533
1534                   if (reportederror)
1535                     {
1536                       hideErrors = TRUE;
1537                       
1538                       /* sRef_kill (fref, loc); */ /* prevent further errors */
1539                       DPRINTF (("Killed: %s", sRef_unparseFull (fref)));
1540                     }
1541                 }
1542             }
1543
1544           DPRINTF (("Here: %s", ctype_unparse (ct)));
1545           return FALSE;
1546         }
1547       
1548       if (/*! evs-2002-03-24 sRef_isAnyDefined (fref) || */
1549           sRef_isDead (fref)
1550           || (sRef_isPdefined (fref) 
1551               && sRefSet_isEmpty (sRef_derivedFields (fref)))) 
1552         {
1553           DPRINTF (("Here: %s [%s / %s]", 
1554                     sRef_unparseFull (fref),
1555                     bool_unparse (sRef_isAnyDefined (fref)),
1556                     bool_unparse (sRef_isDead (fref))));
1557           return TRUE; 
1558         }
1559     }
1560
1561   DPRINTF (("Here..."));
1562
1563   if (ctype_isPointer (ct))
1564     {
1565       sRef fptr = sRef_constructDeadDeref (fref);
1566       bool res;
1567
1568       res = checkCompletelyDestroyed (fexp, fptr, FALSE, FALSE,
1569                                       loc, depth + 1, desc, hideErrors);
1570       
1571       return res;
1572     }
1573   else if (ctype_isArray (ct))
1574     {
1575       if ((sRef_isStateUnknown (fref) || sRef_isAllocated (fref))
1576           && !sRef_hasDerived (fref))
1577         {
1578           /*
1579           ** Bogosity necessary to prevent infinite depth.
1580           */
1581
1582           return FALSE;
1583         }
1584       else
1585         {
1586           sRef farr = sRef_constructDeadDeref (fref);
1587           
1588           return (checkCompletelyDestroyed (fexp, farr, FALSE, FALSE,
1589                                             loc, depth + 1, desc, hideErrors));
1590         }
1591     }
1592   else if (ctype_isStruct (ct))
1593     {
1594       /*
1595       ** for structures, each field must be completely destroyed
1596       */
1597
1598       bool isOk = TRUE;
1599       uentryList fields = ctype_getFields (ct);
1600
1601       DPRINTF (("Struct fields: %s", uentryList_unparse (fields)));
1602
1603       if (depth >= MAXDEPTH)
1604         {
1605           llquietbug (message ("checkCompletelyDestroyed (fields): too deep: %s / %q", 
1606                                exprNode_unparse (fexp),
1607                                sRef_unparseFull (fref)));
1608                               
1609           return TRUE;
1610         }
1611       else
1612         {
1613           uentryList_elements (fields, ue)
1614             {
1615               sRef field = sRef_makeField (fref, uentry_rawName (ue));
1616               
1617               /*
1618               ** note order of && operands --- want to report multiple errors
1619               */
1620               
1621               DPRINTF (("Check field: %s", sRef_unparseFull (field)));
1622
1623               isOk = (checkCompletelyDestroyed (fexp, field, FALSE, TRUE,
1624                                                 loc, depth + 1, desc, hideErrors)
1625                       && isOk);
1626             } end_uentryList_elements;
1627         }
1628       
1629       return isOk;
1630     }
1631   else
1632     {
1633       return TRUE;
1634     }
1635 }
1636
1637 void
1638 transferChecks_return (exprNode fexp, uentry rval)
1639 {
1640   sRef uref = uentry_getSref (rval);
1641   sRef rref = sRef_makeNew (sRef_getType (uref), uref, cstring_undefined);
1642   uentry fcn = context_getHeader ();
1643   sRef fref = exprNode_getSref (fexp);
1644   stateClauseList clauses = uentry_getStateClauseList (fcn);
1645   
1646   DPRINTF (("Check return: %s as %s = %s",
1647             exprNode_unparse (fexp),
1648             sRef_unparseFull (uref),
1649             sRef_unparseFull (rref)));
1650
1651   /* evans 2001-07-18: removed: if (sRef_isStateSpecial (rref)) */
1652
1653   DPRINTF (("Check state clauses: %s",
1654             stateClauseList_unparse (clauses)));
1655   
1656   stateClauseList_postElements (clauses, cl)
1657     {
1658       if (stateClause_isGlobal (cl))
1659         {
1660           ; 
1661         }
1662       else if (stateClause_setsMetaState (cl))
1663         {
1664           sRefSet refs = stateClause_getRefs (cl);
1665           qual ql = stateClause_getMetaQual (cl);
1666           annotationInfo ainfo = qual_getAnnotationInfo (ql);
1667           metaStateInfo minfo = annotationInfo_getState (ainfo);
1668           cstring key = metaStateInfo_getName (minfo);
1669           int mvalue = annotationInfo_getValue (ainfo);
1670           
1671           DPRINTF (("Return check: %s", stateClause_unparse (cl)));
1672           
1673           sRefSet_elements (refs, el)
1674             {
1675               sRef base = sRef_getRootBase (el);
1676               
1677               DPRINTF (("Sets meta state! %s", stateClause_unparse (cl)));
1678               
1679               if (sRef_isResult (base))
1680                 {
1681                   sRef sr = sRef_fixBase (el, fref);
1682                   
1683                   if (!sRef_checkMetaStateValue (sr, key, mvalue))
1684                     {
1685                       if (optgenerror 
1686                           (FLG_STATETRANSFER,
1687                            message ("Result state %q does not satisfy ensures "
1688                                     "clause: %q (state is %q, should be %s): %s",
1689                                     sRef_unparse (sr),
1690                                     stateClause_unparse (cl),
1691                                     stateValue_unparseValue (sRef_getMetaStateValue (sr, key),
1692                                                              minfo),
1693                                     metaStateInfo_unparseValue (minfo, mvalue),
1694                                     exprNode_unparse (fexp)),
1695                            exprNode_loc (fexp)))
1696                         {
1697                           sRef_showAliasInfo (sr); 
1698                         }
1699                     }
1700                 }
1701               else 
1702                 {
1703                   /*
1704                   ** Non-results are checked in exit scope.
1705                   */
1706                 }
1707             } end_sRefSet_elements ;
1708         }
1709       else
1710         {
1711           sRefSet refs = stateClause_getRefs (cl);
1712           sRefTest tst = stateClause_getPostTestFunction (cl);
1713           sRefMod modf = stateClause_getReturnEffectFunction (cl);
1714           
1715           DPRINTF (("Clause: %s / %s",
1716                     stateClause_unparse (cl),
1717                     sRefSet_unparse (refs)));
1718           
1719           sRefSet_elements (refs, el)
1720             {
1721               sRef base = sRef_getRootBase (el);
1722               
1723               DPRINTF (("el: %s / %s", sRef_unparse (el),
1724                         sRef_unparse (base)));
1725               
1726               if (sRef_isResult (base) 
1727                   && !sRef_isDefinitelyNull (fref)) /* evans 2002-07-22: don't report allocation errors for null results */
1728                 {
1729                   sRef sr = sRef_fixBase (el, fref);
1730                   
1731                   if (tst != NULL && !(tst (sr)))
1732                     {
1733                       if (optgenerror 
1734                           (stateClause_postErrorCode (cl),
1735                            message ("%s storage %q corresponds to "
1736                                     "storage %q listed in %q clause: %s",
1737                                     stateClause_postErrorString (cl, sr),
1738                                     sRef_unparse (sr),
1739                                     sRef_unparse (el),
1740                                     stateClause_unparseKind (cl),
1741                                     exprNode_unparse (fexp)),
1742                            exprNode_loc (fexp)))
1743                         {
1744                           sRefShower ss = stateClause_getPostTestShower (cl);
1745                           
1746                           if (ss != NULL)
1747                             {
1748                               ss (sr);
1749                             }
1750                         }
1751                     }
1752                   
1753                   if (modf != NULL)
1754                     {
1755                       modf (sr, exprNode_loc (fexp));
1756                     }
1757                 }
1758               else
1759                 {
1760                   /* 
1761                   ** Non-results are checked in exit scope.
1762                   */
1763                 }
1764             } end_sRefSet_elements ;
1765         }
1766     } end_stateClauseList_postElements ;
1767   
1768   if (ctype_isRealSU (exprNode_getType (fexp)))
1769     {
1770       sRef ffref = exprNode_getSref (fexp);
1771           
1772       checkStructTransfer (exprNode_undefined, rref, 
1773                            fexp, ffref,
1774                            exprNode_loc (fexp),
1775                            TT_FCNRETURN);
1776     }
1777   else
1778     {
1779       (void) checkTransfer (fexp, exprNode_getSref (fexp),
1780                             exprNode_undefined, rref, 
1781                             exprNode_undefined,
1782                             exprNode_loc (fexp), TT_FCNRETURN);
1783     }
1784 }
1785
1786 static void
1787   checkPassstateClauseList (uentry ue, exprNode fexp, sRef fref, int argno)
1788 {
1789   stateClauseList clauses = uentry_getStateClauseList (ue);
1790
1791   DPRINTF (("Check pass special: %s / %s",
1792             exprNode_unparse (fexp), sRef_unparseFull (fref)));
1793   
1794   stateClauseList_preElements (clauses, cl)
1795     {
1796       if (stateClause_isGlobal (cl))
1797         {
1798           ;
1799         }
1800       else
1801         {
1802           sRefSet refs = stateClause_getRefs (cl);
1803           sRefTest tst = stateClause_getPreTestFunction (cl);
1804           sRefMod modf = stateClause_getEffectFunction (cl);
1805           
1806           sRefSet_elements (refs, el)
1807             {
1808               sRef base = sRef_getRootBase (el);
1809               
1810               if (sRef_isResult (base))
1811                 {
1812                   ; /* nothing to check before */
1813                 }
1814               else if (sRef_isParam (base))
1815                 {
1816                   if (sRef_getParam (base) == argno - 1)
1817                     {
1818                       sRef sb;
1819                       
1820                       DPRINTF (("Fix base: %s / %s",
1821                                 sRef_unparseFull (el),
1822                                 sRef_unparseFull (fref)));
1823                       
1824                       sb = sRef_fixBase (el, fref);
1825                       
1826                       if (tst != NULL && !(tst(sb)))
1827                         {
1828                           voptgenerror 
1829                             (stateClause_preErrorCode (cl),
1830                              message ("%s storage %qcorresponds to "
1831                                       "storage listed in %q clause of "
1832                                       "called function: %s",
1833                                       stateClause_preErrorString (cl, sb),
1834                                       sRef_unparseOpt (sb),
1835                                       stateClause_unparseKind (cl),
1836                                       exprNode_unparse (fexp)),
1837                              exprNode_loc (fexp));
1838                         }
1839                       
1840                       if (modf != NULL)
1841                         {
1842                           DPRINTF (("Fixing: %s", sRef_unparseFull (sb)));
1843                           modf (sb, exprNode_loc (fexp));
1844                           DPRINTF (("==> %s", sRef_unparseFull (sb)));
1845                         }
1846                     }
1847                 }
1848               else
1849                 {
1850                   BADBRANCH;
1851                 }
1852             } end_sRefSet_elements ;      
1853         }
1854     } end_stateClauseList_preElements ;
1855
1856     DPRINTF (("After: %s", sRef_unparseFull (fref)));
1857 }
1858
1859 /*
1860 ** should not modify arg
1861 */
1862
1863 void
1864 transferChecks_passParam (exprNode fexp, uentry arg, bool isSpec,
1865                           /*@dependent@*/ exprNode fcn, int argno, int totargs)
1866 {
1867   sRef tref = uentry_getSref (arg);
1868   sRef fref = exprNode_getSref (fexp);
1869   bool isOut = FALSE;
1870   bool isPartial = FALSE;
1871   bool isImpOut = FALSE;
1872   ctype ct = uentry_getType (arg);
1873
1874   DPRINTF (("Check pass: %s -> %s",
1875             sRef_unparseFull (fref),
1876             sRef_unparseFull (tref)));
1877   
1878   atFunction = fcn;
1879   atArgNo = argno;
1880   atNumArgs = totargs;
1881
1882   if (ctype_isElips (ct))
1883     {
1884       ct = ctype_unknown;
1885     }
1886
1887   DPRINTF (("Out arg: %s", bool_unparse (uentry_isOut (arg))));
1888
1889   if (!ctype_isElips (ct) && 
1890       (ctype_isVoidPointer (ct) && uentry_isOut (arg) && sRef_isOnly (tref)))
1891     {
1892       if (ctype_isRealAP (ct))
1893         {
1894           if (sRef_aliasCheckSimplePred (sRef_isDead, fref))
1895             {
1896               if (optgenerror
1897                   (FLG_USERELEASED,
1898                    message ("Dead storage %qpassed as out parameter to %s: %s",
1899                             sRef_unparseOpt (fref),
1900                             exprNode_unparse (fcn),
1901                             exprNode_unparse (fexp)),
1902                    exprNode_loc (fexp)))
1903                 {
1904                   if (sRef_isDead (fref))
1905                     {
1906                       sRef_showStateInfo (fref);
1907                     }
1908                   else
1909                     {
1910                       DPRINTF (("Not really dead!"));
1911                       sRef_showStateInfo (fref);
1912                     }
1913                 }
1914               
1915               sRef_setAllocated (fref, exprNode_loc (fexp));
1916             }
1917           else if (context_getFlag (FLG_STRICTUSERELEASED)
1918                    && sRef_aliasCheckSimplePred (sRef_isPossiblyDead, fref))
1919             {
1920               if (optgenerror2 
1921                   (FLG_USERELEASED, FLG_STRICTUSERELEASED,
1922                    message ("Possibly dead storage %qpassed as out parameter: %s",
1923                             sRef_unparseOpt (fref),
1924                             exprNode_unparse (fexp)),
1925                    exprNode_loc (fexp)))
1926                 {
1927                   if (sRef_isPossiblyDead (fref))
1928                     {
1929                       sRef_showStateInfo (fref);
1930                     }
1931                 }
1932               
1933               sRef_setAllocated (fref, exprNode_loc (fexp));
1934             }
1935           else if (sRef_aliasCheckSimplePred (sRef_isStateUndefined, fref) 
1936                    || sRef_aliasCheckSimplePred (sRef_isUnuseable, fref))
1937             {
1938               voptgenerror
1939                 (FLG_USEDEF,
1940                  message ("Unallocated storage %qpassed as out parameter: %s",
1941                           sRef_unparseOpt (fref),
1942                           exprNode_unparse (fexp)),
1943                  exprNode_loc (fexp));
1944
1945               sRef_setAllocated (fref, exprNode_loc (fexp));
1946             }
1947           else
1948             {
1949               ;
1950             }
1951         }
1952       
1953       (void) checkCompletelyDestroyed (fexp, fref, TRUE, FALSE,
1954                                        exprNode_loc (fexp), 0, DSC_PARAM, FALSE);
1955
1956       /* make it defined now, so checkTransfer is okay */
1957       sRef_setDefined (fref, exprNode_loc (fexp)); 
1958     }
1959   else if (uentry_isOut (arg))
1960     {
1961       DPRINTF (("Here we are!"));
1962
1963       if (ctype_isRealAP (ct)
1964           && (sRef_isStateUndefined (fref) || sRef_isUnuseable (fref)))
1965         {
1966           voptgenerror
1967             (FLG_USEDEF,
1968              message ("Unallocated storage %qpassed as out parameter to %s: %s",
1969                       sRef_unparseOpt (fref),
1970                       exprNode_unparse (fcn),
1971                       exprNode_unparse (fexp)),
1972              exprNode_loc (fexp));
1973           sRef_setAllocated (fref, exprNode_loc (fexp));
1974         }
1975       else if (sRef_isDead (fref))
1976         {
1977           if (optgenerror
1978               (FLG_USERELEASED,
1979                message ("Dead storage %qpassed as out parameter to %s: %s",
1980                         sRef_unparseOpt (fref),
1981                         exprNode_unparse (fcn),
1982                         exprNode_unparse (fexp)),
1983                exprNode_loc (fexp)))
1984             {
1985               sRef_showStateInfo (fref);
1986               sRef_setAllocated (fref, exprNode_loc (fexp));
1987             }
1988         }
1989       else if (sRef_isPossiblyDead (fref))
1990         {
1991           if (optgenerror2
1992               (FLG_USERELEASED, FLG_STRICTUSERELEASED,
1993                message ("Possibly dead storage %qpassed as out parameter to %s: %s",
1994                         sRef_unparseOpt (fref),
1995                         exprNode_unparse (fcn),
1996                         exprNode_unparse (fexp)),
1997                exprNode_loc (fexp)))
1998             {
1999               sRef_showStateInfo (fref);
2000               sRef_setAllocated (fref, exprNode_loc (fexp));
2001             }
2002         }
2003       else
2004         {
2005           ;
2006         }
2007       
2008       isOut = TRUE;
2009     }
2010   else if (uentry_isPartial (arg))
2011     {
2012       if (ctype_isRealAP (ct) 
2013           && (sRef_isStateUndefined (fref) || sRef_isUnuseable (fref)))
2014         {
2015           voptgenerror 
2016             (FLG_USEDEF,
2017              message ("Unallocated storage %qpassed as partial parameter: %s",
2018                       sRef_unparseOpt (fref),
2019                       exprNode_unparse (fexp)),
2020              exprNode_loc (fexp));
2021           sRef_setAllocated (fref, exprNode_loc (fexp));
2022         }
2023       else if (sRef_isDead (fref))
2024         {
2025           if (optgenerror
2026               (FLG_USERELEASED,
2027                message ("Dead storage %qpassed as partial parameter to %s: %s",
2028                         sRef_unparseOpt (fref),
2029                         exprNode_unparse (fcn),
2030                         exprNode_unparse (fexp)),
2031                exprNode_loc (fexp)))
2032             {
2033               sRef_showStateInfo (fref);
2034               sRef_setAllocated (fref, exprNode_loc (fexp));
2035             }
2036         }
2037       else if (sRef_isPossiblyDead (fref))
2038         {
2039           if (optgenerror2
2040               (FLG_USERELEASED, FLG_STRICTUSERELEASED,
2041                message ("Possibly dead storage %qpassed as partial parameter to %s: %s",
2042                         sRef_unparseOpt (fref),
2043                         exprNode_unparse (fcn),
2044                         exprNode_unparse (fexp)),
2045                exprNode_loc (fexp)))
2046             {
2047               sRef_showStateInfo (fref);
2048               sRef_setAllocated (fref, exprNode_loc (fexp));
2049             }
2050         }
2051       else
2052         {
2053           ;
2054         }
2055
2056       isPartial = TRUE;
2057     }
2058   else if (uentry_isStateSpecial (arg))
2059     {
2060       uentry ue = exprNode_getUentry (fcn);
2061
2062       if (ctype_isRealAP (ct) 
2063           && (sRef_isStateUndefined (fref) || sRef_isUnuseable (fref)))
2064         {
2065           voptgenerror 
2066             (FLG_USEDEF,
2067              message ("Unallocated storage %qpassed as special parameter: %s",
2068                       sRef_unparseOpt (fref),
2069                       exprNode_unparse (fexp)),
2070              exprNode_loc (fexp));
2071           sRef_setAllocated (fref, exprNode_loc (fexp));
2072         }
2073       else if (sRef_isDead (fref))
2074         {
2075           if (optgenerror
2076               (FLG_USERELEASED,
2077                message ("Dead storage %qpassed as special parameter to %s: %s",
2078                         sRef_unparseOpt (fref),
2079                         exprNode_unparse (fcn),
2080                         exprNode_unparse (fexp)),
2081                exprNode_loc (fexp)))
2082             {
2083               sRef_showStateInfo (fref);
2084               sRef_setAllocated (fref, exprNode_loc (fexp));
2085             }
2086         }
2087       else if (sRef_isPossiblyDead (fref))
2088         {
2089           if (optgenerror2
2090               (FLG_USERELEASED, FLG_STRICTUSERELEASED,
2091                message ("Possibly dead storage %qpassed as special parameter to %s: %s",
2092                         sRef_unparseOpt (fref),
2093                         exprNode_unparse (fcn),
2094                         exprNode_unparse (fexp)),
2095                exprNode_loc (fexp)))
2096             {
2097               sRef_showStateInfo (fref);
2098               sRef_setAllocated (fref, exprNode_loc (fexp));
2099             }
2100         }
2101       else
2102         {
2103           ;
2104         }
2105
2106       if (uentry_hasStateClauseList (ue))
2107         {
2108           checkPassstateClauseList (ue, fexp, fref, argno);
2109         }
2110       
2111       return; /* ??? */
2112     }
2113   else if (sRef_isStateDefined (tref))
2114     {
2115       exprNode_checkUseParam (fexp);
2116     }
2117   else
2118     {
2119       if (isSpec || (!context_getFlag (FLG_IMPOUTS)))
2120         {
2121           exprNode_checkUseParam (fexp);
2122         }
2123       else
2124         {
2125           if (!sRef_isMacroParamRef (fref) 
2126               && (ctype_isRealAP (ct)))
2127             {
2128               if (sRef_isAddress (fref))
2129                 {
2130                   if (sRef_isStateUndefined (fref) || sRef_isUnuseable (fref))
2131                     {
2132                       voptgenerror 
2133                         (FLG_USEDEF,
2134                          message 
2135                          ("Unallocated address %qpassed as implicit "
2136                           "out parameter: %s",
2137                           sRef_unparseOpt (fref),
2138                           exprNode_unparse (fexp)),
2139                          exprNode_loc (fexp));
2140                       sRef_setAllocated (fref, exprNode_loc (fexp));
2141                     }
2142                 }
2143               
2144               /* yes, I really mean this! */
2145               tref = sRef_copy (tref);
2146               sRef_setAllocated (tref, exprNode_loc (fexp)); 
2147
2148               isOut = TRUE;
2149               isImpOut = TRUE;
2150             }
2151           else 
2152             {
2153               exprNode_checkUseParam (fexp);
2154             }
2155         }
2156     }
2157
2158   if (sRef_isNew (fref))
2159     {
2160       alkind tkind = sRef_getAliasKind (tref);
2161
2162       if ((sRef_isFresh (fref) || sRef_isOnly (fref))
2163           && !alkind_isOnly (tkind) 
2164           && !alkind_isKeep (tkind) 
2165           && !alkind_isOwned (tkind)
2166           && !alkind_isError (tkind)
2167           && !uentry_isReturned (arg))
2168         
2169         {
2170           voptgenerror 
2171             (FLG_MUSTFREEFRESH,
2172              message ("New fresh storage %q(type %s) passed as %s (not released): %s",
2173                       sRef_unparseOpt (fref),
2174                       ctype_unparse (sRef_getType (fref)),
2175                       alkind_unparse (sRef_getAliasKind (tref)),
2176                       exprNode_unparse (fexp)),
2177              exprNode_loc (fexp));
2178
2179           DPRINTF (("Fresh: %s", sRef_unparseFull (fref)));
2180         }
2181       else 
2182         {
2183           if (sRef_isNewRef (fref) && !sRef_isKillRef (tref))
2184             {
2185               alkind ak = sRef_getAliasKind (tref);
2186               
2187               if (!alkind_isError (ak))
2188                 {
2189                   voptgenerror 
2190                     (FLG_MUSTFREEFRESH,
2191                      message ("New reference %q(type %s) passed as %s (not released): %s",
2192                               sRef_unparseOpt (fref),
2193                               ctype_unparse (sRef_getType (fref)),
2194                               alkind_unparse (sRef_getAliasKind (tref)),
2195                               exprNode_unparse (fexp)),
2196                      exprNode_loc (fexp));
2197                 }
2198             }
2199         }
2200     }
2201   
2202   (void) checkTransfer (fexp, exprNode_getSref (fexp),
2203                         exprNode_undefined, tref,
2204                         fcn,
2205                         exprNode_loc (fexp), TT_FCNPASS);
2206
2207   setCodePoint ();
2208   fref = exprNode_getSref (fexp);
2209   
2210   if (isOut && !sRef_isDead (fref) && !sRef_isPossiblyDead (fref))
2211     {
2212       sRef base;
2213
2214       if (ctype_isRealAP (sRef_getType (fref)))
2215         {
2216           base = sRef_makePointer (fref); 
2217         }
2218       else
2219         {
2220           base = fref;
2221         }
2222
2223       if (isImpOut)
2224         {
2225           exprNode_checkMSet (fexp, base);
2226         }
2227       else
2228         {
2229           exprNode_checkSet (fexp, base);
2230         }
2231
2232       if (sRef_isValid (base))
2233         {
2234           setCodePoint ();
2235
2236           sRef_clearDerived (base);
2237           sRef_setDefined (base, exprNode_loc (fexp));
2238           usymtab_clearAlias (base);
2239           /* evans 2004-07-31: Don't change state of constants! */
2240           if (!sRef_isConst (base)) {
2241             sRef_setNullUnknown (base, exprNode_loc (fexp));
2242           }
2243         }
2244     }
2245
2246   if (isPartial)
2247     {
2248       if (sRef_isValid (fref))
2249         {
2250           sRef_setPartial (fref, exprNode_loc (fexp)); 
2251         }
2252     }
2253
2254   atFunction = exprNode_undefined;
2255   atArgNo = 0;
2256   atNumArgs = 0;
2257   
2258   /* need to fixup here: derived refs could be bogus */
2259   /* (better to change sRef to not add derivs for "protected" ref) */
2260
2261   uentry_fixupSref (arg);
2262
2263   setCodePoint ();
2264
2265   DPRINTF (("Check pass: ==> %s",
2266             sRef_unparseFull (fref)));
2267 }
2268
2269 void
2270 transferChecks_globalReturn (uentry glob)
2271 {
2272   sRef_protectDerivs ();
2273   checkGlobTrans (glob, TT_GLOBRETURN);
2274   sRef_clearProtectDerivs ();
2275 }
2276
2277 void transferChecks_paramReturn (uentry actual)
2278 {
2279   checkLeaveTrans (actual, TT_PARAMRETURN);
2280 }
2281
2282 void transferChecks_loseReference (uentry actual)
2283 {
2284   checkLeaveTrans (actual, TT_LEAVETRANS);
2285 }
2286
2287 static void
2288 checkLeaveTrans (uentry actual, transferKind transferType)
2289 {
2290   sRef aref = uentry_getSref (actual);
2291   sRef origref = uentry_getOrigSref (actual);
2292
2293   if (transferType == TT_PARAMRETURN 
2294       && (sRef_isKeep (origref) || sRef_isOnly (origref)
2295           || sRef_isOwned (origref)))
2296     {
2297       /* caller cannot use, nothing to check */
2298     }
2299   else
2300     {
2301       if (sRef_isNSLocalVar (origref))
2302         {
2303           ;
2304         }
2305       else
2306         {
2307           DPRINTF (("Leave trans: %s", uentry_unparseFull (actual)));
2308
2309           (void) checkCompletelyDefined (exprNode_undefined, aref, aref,
2310                                          exprNode_undefined, origref,
2311                                          TRUE, FALSE, FALSE,
2312                                          g_currentloc, transferType,
2313                                          0, TRUE);
2314         }
2315     }
2316 }
2317
2318 static void
2319 checkGlobTrans (uentry glob, transferKind type)
2320 {
2321   sRef eref = uentry_getOrigSref (glob);
2322  
2323   DPRINTF (("Completely defined: %s", uentry_unparseFull (glob)));
2324
2325   (void) checkCompletelyDefined (exprNode_undefined, uentry_getSref (glob), 
2326                                  uentry_getSref (glob),
2327                                  exprNode_undefined, eref, 
2328                                  TRUE, FALSE, FALSE,
2329                                  g_currentloc, type, 0, TRUE);
2330 }
2331
2332 /*
2333 ** For lhs of assignment, alias kind is set from basic type.
2334 ** Yoikes!
2335 */
2336
2337 static void
2338 fixAssignLhs (sRef s)
2339 {
2340   sRef_resetStateComplete (s);
2341 }
2342
2343 static void checkStructTransfer (exprNode lhs, sRef slhs, exprNode rhs, sRef srhs,
2344                                  fileloc loc,
2345                                  transferKind tt)
2346 {
2347   ctype st = ctype_realType (sRef_getType (srhs));
2348   
2349   if (ctype_isSU (st) && ctype_isRealSU (sRef_getType (slhs))
2350       && ctype_match (sRef_getType (slhs), st))
2351     {
2352       if ((tt == TT_DOASSIGN || tt == TT_FIELDASSIGN) && sRef_isStateDefined (srhs))
2353         {
2354           sRef_setDefinedComplete (slhs, loc);
2355         }
2356           
2357       if (sRef_isDependent (slhs)
2358           || sRef_isObserver (slhs)
2359           || sRef_isExposed (slhs))
2360         {
2361           ;
2362         }
2363       else
2364         {
2365           if (sRef_isLocalVar (slhs)
2366               && sRef_isFileOrGlobalScope (sRef_getRootBase (srhs)))
2367             {
2368               DPRINTF (("Global scope!"));
2369               sRef_setDependent (slhs, exprNode_loc (lhs));
2370             }
2371         }
2372
2373       /*
2374       ** evans 2003-07-10: should always copy the fields!
2375       */
2376
2377       if (ctype_isUnion (st))
2378         {
2379           sRef_setDefState (slhs, sRef_getDefState (srhs), 
2380                             exprNode_loc (lhs));
2381           
2382           sRefSet_realElements (sRef_derivedFields (srhs), sr)
2383             {
2384               if (sRef_isField (sr))
2385                 {
2386                   cstring fieldname = sRef_getField (sr);
2387                   sRef lfld = sRef_makeField (slhs, fieldname);
2388                   
2389                   (void) checkTransfer (rhs, sr, lhs, lfld, 
2390                                         exprNode_undefined,
2391                                         exprNode_loc (lhs), tt);
2392                 }
2393             } end_sRefSet_realElements ;
2394         }
2395       else
2396         {
2397           uentryList fields = ctype_getFields (st);
2398           
2399           uentryList_elements (fields, field)
2400             {
2401               sRef rfld = sRef_makeField (srhs, uentry_rawName (field));
2402               sRef lfld = sRef_makeField (slhs, uentry_rawName (field));
2403               DPRINTF (("Transfer field: %s := %s", 
2404                         sRef_unparse (lfld), sRef_unparse (rfld)));
2405               (void) checkTransfer (rhs, rfld, lhs, lfld, 
2406                                     exprNode_undefined,
2407                                     exprNode_loc (lhs), tt);
2408             } end_uentryList_elements ;
2409         }
2410       
2411       if (sRef_isOnly (srhs))
2412         {
2413           sRef_setKeptComplete (srhs, loc);
2414         }
2415     }
2416 }
2417
2418 void
2419 transferChecks_initialization (exprNode lhs, exprNode rhs)
2420 {
2421   sRef slhs = exprNode_getSref (lhs);
2422   
2423   if (sRef_isFileOrGlobalScope (slhs) || (!sRef_isCvar (slhs)))
2424     {
2425       (void) checkTransfer (rhs, exprNode_getSref (rhs), 
2426                             lhs, slhs, 
2427                             exprNode_undefined,
2428                             exprNode_loc (rhs), TT_GLOBINIT);
2429     }
2430   else
2431     {
2432       transferChecks_assign (lhs, rhs);
2433     }
2434 }
2435
2436 void
2437 transferChecks_assign (exprNode lhs, exprNode rhs)
2438 {
2439   sRef slhs = exprNode_getSref (lhs);
2440   sRef srhs = exprNode_getSref (rhs);
2441   sRef base = sRef_getBaseSafe (slhs);
2442   nstate ns;
2443   
2444   DPRINTF (("Check assign: %s = %s", exprNode_unparse (lhs),
2445             exprNode_unparse (rhs)));
2446   DPRINTF (("lhs: %s", sRef_unparseFull (slhs)));
2447   DPRINTF (("rhs: %s", sRef_unparseFull (srhs)));
2448
2449   if (ctype_isRealSU (sRef_getType (srhs)))
2450     {
2451       DPRINTF (("Check struct transfer: %s := %s", exprNode_unparse (lhs),
2452                 exprNode_unparse (rhs)));
2453       checkStructTransfer (lhs, slhs, rhs, srhs, exprNode_loc (lhs), TT_FIELDASSIGN);
2454     }
2455   else
2456     {
2457       DPRINTF (("lhs: %s", sRef_unparseFull (slhs)));
2458       DPRINTF (("rhs: %s", sRef_unparseFull (srhs)));
2459       (void) checkTransfer (rhs, srhs, lhs, slhs, 
2460                             exprNode_undefined,
2461                             exprNode_loc (lhs), TT_DOASSIGN);
2462       DPRINTF (("lhs: %s", sRef_unparseFull (slhs)));
2463       DPRINTF (("rhs: %s", sRef_unparseFull (srhs)));
2464     }
2465
2466   if (sRef_isConst (srhs) && sRef_isLocalState (srhs))
2467     {
2468       /* constants can match anything (e.g., NULL) */
2469       sRef_setAliasKind (slhs, AK_ERROR, fileloc_undefined);
2470     }
2471
2472   if (sRef_isValid (base) && sRef_isStateDefined (base))
2473     {
2474       sRef_setPdefined (base, g_currentloc); 
2475     }
2476
2477   if (sRef_isPartial (srhs))
2478     {
2479       sRef_setPartial (slhs, exprNode_loc (rhs));
2480     }
2481
2482   ns = sRef_getNullState (srhs);
2483
2484   if (nstate_possiblyNull (ns))
2485     {
2486       if (usymtab_isGuarded (srhs))
2487         {
2488           ns = NS_NOTNULL;
2489         }
2490     }
2491
2492   sRef_setNullStateInnerComplete (slhs, ns, exprNode_loc (rhs));
2493
2494   if (sRef_isExposed (srhs) || sRef_isObserver (srhs))
2495     {
2496       sRef_setExKind (slhs, sRef_getExKind (srhs), exprNode_loc (rhs));
2497     }
2498   
2499   DPRINTF (("Done transfer: %s", sRef_unparseFull (slhs)));
2500 }
2501
2502 static void
2503 checkTransferNullAux (sRef fref, exprNode fexp, /*@unused@*/ bool ffix,
2504                       sRef tref, exprNode texp, /*@unused@*/ bool tfix,
2505                       fileloc loc, transferKind transferType)
2506 {
2507   alkind tkind = sRef_getAliasKind (tref);
2508   ctype ttyp = ctype_realType (sRef_getType (tref));
2509
2510   DPRINTF (("Null transfer: %s => %s", sRef_unparseFull (fref), sRef_unparseFull (tref)));
2511
2512   if (ctype_isUnknown (ttyp))
2513     {
2514       ttyp = exprNode_getType (texp);
2515       
2516       if (ctype_isUnknown (ttyp))
2517         {
2518           ttyp = exprNode_getType (fexp);
2519
2520           if (ctype_isUnknown (ttyp))
2521             {
2522               ttyp = sRef_getType (fref);
2523             }
2524         }
2525     }
2526
2527   if (ctype_isFunction (ttyp) && (transferType == TT_FCNRETURN))
2528     {
2529       ttyp = ctype_getReturnType (ttyp);
2530     }
2531
2532   /*
2533   ** check for null (don't need to check aliases??)
2534   */
2535
2536   if (sRef_possiblyNull (fref) 
2537       && !usymtab_isGuarded (fref) 
2538       && ctype_isRealAP (ttyp))
2539     {
2540       if (!alkind_isLocal (tkind) && !alkind_isFresh (tkind)
2541           && !sRef_perhapsNull (tref)
2542           && !(transferType == TT_DOASSIGN))
2543         {
2544           if (transferType == TT_GLOBINIT)
2545             {
2546               if (sRef_isNotNull (tref))
2547                 {
2548                   if (optgenerror
2549                       (FLG_NULLINIT, /* kuldge flag... */
2550                        message ("%s %q initialized to %s value: %q",
2551                                 sRef_getScopeName (tref),
2552                                 sRef_unparse (tref),
2553                                 sRef_nullMessage (fref),
2554                                 generateText (fexp, texp, tref, transferType)),
2555                        loc))
2556                     {
2557                       sRef_showNullInfo (fref);
2558                       sRef_setNullError (tref);
2559                     }
2560                 }
2561               else
2562                 {
2563                   if (optgenerror
2564                       (FLG_NULLASSIGN,
2565                        message ("%s %q initialized to %s value: %q",
2566                                 sRef_getScopeName (tref),
2567                                 sRef_unparse (tref),
2568                                 sRef_nullMessage (fref),
2569                                 generateText (fexp, texp, tref, transferType)),
2570                        loc))
2571                     {
2572                       sRef_showNullInfo (fref);
2573                       sRef_setNullError (tref);
2574                     }
2575                 }
2576             }
2577           else
2578             {
2579               if (optgenerror
2580                   ((transferType == TT_FCNPASS) ? FLG_NULLPASS : FLG_NULLRET,
2581                    message ("%q storage %q%s: %q",
2582                             cstring_capitalize (sRef_nullMessage (fref)),
2583                             sRef_unparseOpt (fref),
2584                             transferNullMessage (transferType), 
2585                             generateText (fexp, texp, tref, transferType)),
2586                    loc))
2587                 {
2588                   sRef_showNullInfo (fref);
2589                   sRef_setNullError (fref);
2590                 }
2591             }
2592         }
2593       else
2594         {
2595           ;
2596         }
2597     }  
2598 }
2599
2600
2601 static void
2602 checkTransferAssignAux (sRef fref, exprNode fexp, /*@unused@*/ bool ffix,
2603                         /*@exposed@*/ sRef tref, exprNode texp, bool tfix,
2604                         fileloc loc, transferKind transferType)
2605 {
2606   alkind tkind = sRef_getAliasKind (tref);
2607
2608   /*
2609   ** Assignment to same --- no errors, or state changes.
2610   ** This can happen when returned params are used.
2611   */
2612
2613   if (sRef_sameName (fref, tref))
2614     {
2615       sRef_copyState (tref, fref); 
2616       return;
2617     }
2618   
2619   if ((alkind_isOnly (tkind) || alkind_isFresh (tkind) 
2620        || alkind_isNewRef (tkind) || alkind_isOwned (tkind))
2621       && !(sRef_isDead (tref) 
2622            || sRef_isStateUndefined (tref) 
2623            || sRef_isUnuseable (tref) 
2624            || sRef_isPartial (tref)
2625            || sRef_definitelyNull (tref) 
2626            || sRef_isStackAllocated (tref) 
2627            || sRef_isAllocIndexRef (tref))
2628       && !(sRef_same (fref, tref)) /* okay to assign to self (returned params) */
2629       && !(usymtab_isDefinitelyNull (tref))) 
2630     {
2631       if (transferChecks_canLoseReference (tref, loc))
2632         {
2633           ; /* no error */
2634         }
2635       else
2636         {
2637           flagcode flg = sRef_isFresh (tref) ? FLG_MUSTFREEFRESH : FLG_MUSTFREEONLY;
2638
2639           if (sRef_hasLastReference (tref))
2640             {
2641               if (optgenerror 
2642                   (flg,
2643                    message ("Last reference %q to %s storage %q(type %s) not released "
2644                             "before assignment: %q",
2645                             sRef_unparse (tref),
2646                             alkind_unparse (tkind),
2647                             sRef_unparseOpt (sRef_getAliasInfoRef (tref)),
2648                             ctype_unparse (sRef_getType (tref)),
2649                             generateText (fexp, texp, tref, transferType)),
2650                    loc))
2651                 {
2652                   sRef_showRefLost (tref);
2653                 }
2654             }
2655           else
2656             {
2657               if (context_inGlobalScope ())
2658                 {
2659                   /* no errors for static initializations */
2660                 }
2661               else 
2662                 {
2663                   /*
2664                   ** don't report this error for a[i], since it could
2665                   ** be a new element.
2666                   */
2667                   
2668                   if (alkind_isNewRef (tkind))
2669                     {
2670                       if (optgenerror 
2671                           (flg,
2672                            message 
2673                            ("%q %q(type %s) not released before assignment: %q",
2674                             cstring_makeLiteral
2675                             (alkind_isKillRef (sRef_getOrigAliasKind (tref))
2676                              ? "Kill reference parameter" : "New reference"),
2677                             sRef_unparseOpt (tref),
2678                             ctype_unparse (sRef_getType (tref)),
2679                             generateText (fexp, texp, tref, transferType)),
2680                            loc))
2681                         {
2682                           sRef_showAliasInfo (tref);
2683                           sRef_setAliasKind (tref, AK_ERROR, loc);
2684                         }
2685                     }
2686                   else if
2687                     (!(sRef_isUnknownArrayFetch (tref)
2688                        && !context_getFlag (FLG_STRICTDESTROY))
2689                      && !sRef_isUnionField (tref)
2690                      && !sRef_isRelDef (tref)
2691                      && optgenerror 
2692                      (flg,
2693                       message 
2694                       ("%s storage %q(type %s) not released before assignment: %q",
2695                        alkind_capName (tkind),
2696                        sRef_unparseOpt (tref),
2697                        ctype_unparse (sRef_getType (tref)),
2698                        generateText (fexp, texp, tref, transferType)),
2699                       loc))
2700                     {
2701                       sRef_showAliasInfo (tref);
2702                     }
2703                   else
2704                     {
2705                       ;
2706                     }
2707                 }
2708             }
2709         }
2710     }
2711
2712   fixAssignLhs (tref);
2713
2714   if (sRef_isRefCounted (tref)) /* tkind might not be correct now */
2715     {
2716       if (sRef_isNewRef (fref))
2717         {
2718           sRef_setAliasKind (tref, AK_NEWREF, loc);
2719         }
2720       else if (sRef_isConst (fref))
2721         {
2722           /* for now, constants are not ref counted */
2723           sRef_setAliasKind (tref, AK_ERROR, loc);
2724         }
2725       else
2726         {
2727           ;
2728         }
2729
2730       if (!sRef_isNSLocalVar (tref) 
2731           && sRef_isRefCounted (fref)
2732           && sRef_isStateDefined (fref))
2733         {
2734           voptgenerror 
2735             (FLG_NEWREFTRANS,
2736              message ("New reference %qto reference counted storage: %q",
2737                       sRef_unparseOpt (tref),
2738                       generateText (fexp, texp, tref, transferType)),
2739              loc);
2740         }
2741     }
2742
2743   /*
2744   ** Not for structures and unions, since assignments copy.
2745   */
2746
2747   if (sRef_isStack (fref)
2748       && !ctype_isSU (ctype_realType (sRef_getType (fref))))
2749     {
2750       sRef_setAliasKindComplete (tref, AK_STACK, loc);
2751     }
2752
2753   if (sRef_isNSLocalVar (tref) 
2754       && !sRef_isOwned (tref) /*< should only apply to static >*/
2755       && ctype_isMutable (sRef_getType (tref)))
2756     {
2757       if (sRef_isOnly (fref) && sRef_isNew (fref)) 
2758         {
2759           if (!tfix) 
2760             {
2761               sRef_setFresh (tref, loc);
2762             }
2763         }
2764     }
2765
2766   DPRINTF (("Transfer ==> %s", sRef_unparseFull (tref)));
2767 }
2768
2769 /*
2770 ** requires sRef_isOnly (fref)
2771 */
2772
2773 static void
2774 checkOnlyTransferAux (sRef fref, exprNode fexp, bool ffix,
2775                       sRef tref, exprNode texp, /*@unused@*/ bool tfix,
2776                       fileloc loc, transferKind transferType)
2777 {     
2778   alkind tkind = sRef_getAliasKind (tref);
2779
2780   if (sRef_isExposed (tref) || sRef_isObserver (tref))
2781     {
2782       if (transferType == TT_FCNRETURN && sRef_isNew (fref)
2783           && !alkind_isError (tkind))
2784         {
2785           if (optgenerror 
2786               (FLG_ONLYTRANS,
2787                message ("Only storage %q%q (will not be released): %q",
2788                         sRef_unparseOpt (fref),
2789                         transferErrorMessage (transferType, tkind),
2790                         generateText (fexp, texp, tref, transferType)),
2791                loc))
2792             {
2793               sRef_showAliasInfo (fref);
2794             }
2795         }
2796       
2797       /* no errors for exposed transfers (is this good enough?) */
2798     }
2799   else if (alkind_isOnly (tkind) || alkind_isKeep (tkind) || alkind_isOwned (tkind))
2800     {
2801       ; /* okay */
2802     }
2803   else if ((transferType == TT_FCNPASS)
2804            && (alkind_isUnknown (tkind) 
2805                || alkind_isTemp (tkind) || alkind_isUnique (tkind)))
2806     {
2807       if (sRef_isFresh (fref) 
2808           && alkind_isUnknown (tkind) && !context_getFlag (FLG_PASSUNKNOWN))
2809         {
2810           if (!ffix) sRef_setAliasKind (fref, AK_UNKNOWN, loc); 
2811         }
2812     }
2813   else if (alkind_isLocal (tkind) 
2814            || alkind_isFresh (tkind) || alkind_isUnknown (tkind))
2815     {
2816       if ((transferType == TT_DOASSIGN)
2817           && sRef_isNew (fref) 
2818           && sRef_isOnly (fref))
2819         {
2820           bool error = FALSE;
2821
2822           if (alkind_isUnknown (tkind)
2823               && sRef_isFileOrGlobalScope (sRef_getRootBase (tref)))
2824             {
2825               if (optgenerror 
2826                   (FLG_ONLYUNQGLOBALTRANS,
2827                    message ("Only storage %q%q: %q",
2828                             sRef_unparseOpt (fref),
2829                             transferErrorMessage (transferType, tkind),
2830                             generateText (fexp, texp, tref, transferType)),
2831                    loc))
2832                 {
2833                   sRef_showAliasInfo (fref);
2834                   sRef_setAliasKind (tref, AK_ERROR, loc);
2835                   error = TRUE;
2836                 }
2837             }
2838
2839           if (!error && !ffix) 
2840             {
2841               sRef_setFresh (tref, loc);
2842             }
2843         }
2844       else
2845         {
2846           if (alkind_isLocal (tkind))
2847             {
2848               if (sRef_sameName (tref, fref))
2849                 {
2850                   ; /* don't set this --- corresponds to return transfer */
2851                 }
2852               else
2853                 {
2854                   /*
2855                   ** Don't set local to dependent.  Error will
2856                   ** be detected through aliasing.  Except for
2857                   ** arrays.
2858                   */
2859                   
2860                   if (!tfix && sRef_isThroughArrayFetch (fref)
2861                       && context_getFlag (FLG_DEPARRAYS))
2862                     {
2863                       sRef_setDependent (tref, loc);
2864                     }
2865                 }
2866             }
2867           else
2868             {
2869               if (optgenerror 
2870                   (FLG_ONLYTRANS,
2871                    message ("Only storage %q%q: %q",
2872                             sRef_unparseOpt (fref),
2873                             transferErrorMessage (transferType, tkind),
2874                             generateText (fexp, texp, tref, transferType)),
2875                    loc))
2876                 {
2877                   sRef_showAliasInfo (fref);
2878                 }
2879             }
2880         }
2881     }
2882   else
2883     {
2884       if (alkind_isError (tkind) 
2885           || (alkind_isUnknown (tkind) && !context_getFlag (FLG_MEMIMPLICIT)))
2886         {
2887           flagcode_recordSuppressed (FLG_ONLYTRANS);
2888         }
2889       else
2890         {
2891           if ((alkind_isKept (tkind) || alkind_isStack (tkind) 
2892                || alkind_isDependent (tkind))
2893               && sRef_isNSLocalVar (tref))
2894             {
2895               ; /* okay */
2896             }
2897           else
2898             {
2899               if (optgenerror 
2900                   (FLG_ONLYTRANS,
2901                    message ("Only storage %q%q: %q",
2902                             sRef_unparseOpt (fref),
2903                             transferErrorMessage (transferType, tkind),
2904                             generateText (fexp, texp, tref, transferType)),
2905                    loc))
2906                 {
2907                   sRef_showAliasInfo (fref);
2908                   
2909                   if (transferType == TT_DOASSIGN)
2910                     {
2911                       /*
2912                       ** alias kind unknown to suppress future messages
2913                       */
2914                       
2915                       if (!ffix && sRef_isNSLocalVar (sRef_getRootBase (fref)))
2916                         {
2917                           sRef_clearAliasKind (fref);
2918                         }
2919                     }
2920                 }
2921             }
2922         }
2923     }
2924 }
2925
2926 /*
2927 ** ??? same as checkOnly ?
2928 */
2929
2930 static void
2931 checkOwnedTransferAux (sRef fref, exprNode fexp, bool ffix,
2932                        sRef tref, exprNode texp, bool tfix,
2933                        fileloc loc, transferKind transferType)
2934 {     
2935   alkind tkind = sRef_getAliasKind (tref);
2936
2937   if (sRef_isExposed (tref) || sRef_isObserver (tref))
2938     {
2939       if (transferType == TT_FCNRETURN && sRef_isNew (fref))
2940         {
2941           if (optgenerror 
2942               (FLG_OWNEDTRANS,
2943                message ("Owned storage %q%q (will not be released): %q",
2944                         sRef_unparseOpt (fref),
2945                         transferErrorMessage (transferType, tkind),
2946                         generateText (fexp, texp, tref, transferType)),
2947                loc))
2948             {
2949               sRef_showAliasInfo (fref);
2950             }
2951         }
2952     }
2953   else if (alkind_isOnly (tkind) || alkind_isKeep (tkind) 
2954            || alkind_isDependent (tkind)
2955            || alkind_isOwned (tkind))
2956     {
2957       /* okay */
2958     }
2959   else if (alkind_isLocal (tkind)
2960            || alkind_isFresh (tkind) || alkind_isUnknown (tkind))
2961     {
2962       if ((transferType == TT_DOASSIGN)
2963           && sRef_isNew (fref) && sRef_isOnly (fref))
2964         {
2965           if (!tfix) 
2966             { 
2967               sRef_setFresh (tref, loc); 
2968             }
2969         }
2970       else
2971         {
2972         }
2973     }
2974   else if ((transferType == TT_FCNPASS)
2975            && (alkind_isUnknown (tkind) 
2976                || alkind_isTemp (tkind) || alkind_isUnique (tkind)))
2977     {
2978       if (sRef_isFresh (fref) 
2979           && alkind_isUnknown (tkind) && !context_getFlag (FLG_PASSUNKNOWN))
2980         {
2981           if (!ffix) { sRef_clearAliasKind (fref); }
2982         }
2983     }
2984   else
2985     {
2986       if (alkind_isUnknown (tkind) && !context_getFlag (FLG_MEMIMPLICIT))
2987         {
2988           flagcode_recordSuppressed (FLG_OWNEDTRANS);
2989         }
2990       else
2991         {
2992           if (alkind_isKept (tkind) && sRef_isNSLocalVar (tref))
2993             {
2994               ; /* okay */
2995             }
2996           else
2997             {
2998               voptgenerror
2999                 (FLG_OWNEDTRANS,
3000                  message ("Owned storage %q%q: %q",
3001                           sRef_unparseOpt (fref),
3002                           transferErrorMessage (transferType, tkind),
3003                           generateText (fexp, texp, tref, transferType)),
3004                  loc);
3005             }
3006         }
3007       
3008       if (transferType == TT_DOASSIGN)
3009         {
3010           /*
3011            ** alias kind unknown to suppress future messages
3012            */
3013           
3014           if (!ffix) { sRef_clearAliasKind (fref); }
3015         }
3016     }
3017 }
3018   
3019 static void
3020 checkFreshTransferAux (sRef fref, exprNode fexp, bool ffix,
3021                        sRef tref, exprNode texp, /*@unused@*/ bool tfix,
3022                        fileloc loc, transferKind transferType)
3023 {     
3024   alkind tkind = sRef_getAliasKind (tref);
3025
3026   /*
3027   ** error to return fresh as non-only
3028   */
3029
3030   if (transferType == TT_FCNRETURN
3031       && !(alkind_isOnly (tkind) || alkind_isNewRef (tkind)))
3032     {
3033       if (alkind_isUnknown (tkind) && !context_getFlag (FLG_MEMIMPLICIT))
3034         {
3035           flagcode_recordSuppressed (FLG_NEWREFTRANS);
3036         }
3037       else
3038         {
3039           if (alkind_isError (tkind))
3040             {
3041               if (!ffix) 
3042                 { 
3043                   sRef_killComplete (fref, loc); 
3044                 }
3045             }
3046           else if (alkind_isRefCounted (tkind))
3047             {
3048               if (optgenerror 
3049                   (FLG_NEWREFTRANS,
3050                    message
3051                    ("New reference returned without newref qualifier: %q",
3052                     generateText (fexp, texp, tref, transferType)),
3053                    loc))
3054                 {
3055                   sRef_showAliasInfo (fref);
3056                   sRef_killComplete (fref, loc);
3057                 }
3058               }
3059           else 
3060             {
3061               if (optgenerror 
3062                   (FLG_FRESHTRANS,
3063                    message ("Fresh storage %q (should be only): %q",
3064                             transferErrorMessage (transferType, tkind),
3065                             generateText (fexp, texp, tref, transferType)),
3066                    loc))
3067                 {
3068                   sRef_showAliasInfo (fref);
3069                   sRef_killComplete (fref, loc);
3070                 }
3071             }
3072         }
3073     }
3074   
3075   /*
3076   ** Okay to assign fresh to only, shared or unqualified.
3077   ** 
3078   ** should generate other errors? 
3079   */
3080
3081   if (alkind_isOnly (tkind))
3082     {
3083       if (transferType == TT_DOASSIGN && !sRef_isFileOrGlobalScope (tref))
3084         {
3085           if (!ffix) 
3086             { 
3087               if (!sRef_isNSLocalVar (tref))
3088                 {
3089                   sRef_setKeptComplete (fref, loc); 
3090                 }
3091             }
3092         }
3093       else
3094         {
3095           if (sRef_isConst (fref))
3096             {
3097               ;
3098             }
3099           else
3100             {
3101               if (!ffix) 
3102                 { 
3103                   sRef_killComplete (fref, loc); 
3104                 }
3105             }
3106         }
3107     }
3108   else if (alkind_isOwned (tkind))
3109     {
3110       if (!ffix) 
3111         { 
3112           sRef_setDependentComplete (fref, loc); 
3113         }
3114     }
3115   else if (alkind_isRefCounted (tkind)
3116            && (transferType == TT_FCNRETURN) && sRef_isFresh (fref))
3117     {
3118       if (!ffix) 
3119         { 
3120           sRef_killComplete (fref, loc); 
3121         }
3122     }
3123   else if (alkind_isKeep (tkind))
3124     {
3125       if (!ffix) 
3126         { 
3127           if (!sRef_isNSLocalVar (tref))
3128             {
3129               sRef_setKeptComplete (fref, loc); 
3130             }
3131         }
3132     }
3133   else if (alkind_isShared (tkind))
3134     {
3135       if (!ffix) { sRef_setShared (fref, loc); }
3136     }
3137   else if (alkind_isLocal (tkind) || alkind_isUnknown (tkind))
3138     {
3139       if (transferType == TT_DOASSIGN || transferType == TT_FCNRETURN)
3140         {
3141           /*
3142           ** local shares fresh.  Make it owned/dependent. 
3143           */
3144
3145           if (!tfix) 
3146             { 
3147               sRef_setOwned (tref, loc); 
3148             }
3149
3150           if (!ffix && !tfix) 
3151             { 
3152               sRef_setDependentComplete (fref, loc); 
3153             }
3154
3155           /* NO! sRef_clearAliasKind (fref); */
3156         }
3157       else 
3158         {
3159           if (context_getFlag (FLG_PASSUNKNOWN))
3160             {
3161               sRef_clearAliasKind (fref);
3162             }
3163         }
3164     }
3165   else
3166     {
3167       ;
3168     }
3169 }
3170
3171 static void
3172 checkTransferExposure (sRef fref, exprNode fexp, /*@unused@*/ bool ffix,
3173                        sRef tref, exprNode texp, bool tfix,
3174                        fileloc loc, 
3175                        transferKind transferType)
3176 {
3177   alkind fkind = sRef_getAliasKind (fref);
3178   alkind tkind = sRef_getAliasKind (tref);
3179   exkind tekind = sRef_getExKind (tref);
3180
3181   if (sRef_isObserver (fref) && ctype_isMutable (sRef_getType (fref)))
3182     {
3183       /*
3184       ** observer -> exposed or observer
3185       */
3186       
3187       /*
3188       ** observer -> temp is okay [NO!  really? only in function calls]
3189       */
3190
3191       if (sRef_isExposed (tref) || sRef_isObserver (tref)
3192           || alkind_isLocal (tkind))
3193         {
3194           /* okay */
3195           
3196           if ((transferType == TT_DOASSIGN) && alkind_isLocal (tkind))
3197             {
3198               if (!tfix) 
3199                 {
3200                   sRef_setAliasKindComplete (tref, fkind, loc); 
3201                 }
3202             }
3203         }
3204       else
3205         {
3206           if (transferType == TT_FCNRETURN 
3207               || transferType == TT_DOASSIGN
3208               || transferType == TT_FIELDASSIGN
3209               || transferType == TT_GLOBINIT)
3210             {
3211               bool hasError = FALSE;
3212               
3213               if (exprNode_isStringLiteral (fexp)
3214                   && transferType == TT_GLOBINIT)
3215                 {
3216                   hasError = optgenerror
3217                     (FLG_READONLYTRANS,
3218                      message ("Read-only string literal storage %q%q: %q",
3219                               sRef_unparseOpt (fref),
3220                               transferErrorExpMessage (transferType, tekind),
3221                               generateText (fexp, texp, tref, transferType)),
3222                      loc);
3223
3224                   sRef_setAliasKind (fref, AK_ERROR, fileloc_undefined);
3225                 }
3226               else 
3227                 {
3228                   if ((transferType == TT_DOASSIGN
3229                        || transferType == TT_FIELDASSIGN)
3230                       && (sRef_isNSLocalVar (tref)
3231                           || (exprNode_isStringLiteral (fexp)
3232                               && ctype_isRealArray (exprNode_getType (texp)))))
3233                     {
3234                       ; /* No error for local assignment or assignment
3235                            to static array (copies string). */
3236                     }
3237                   else
3238                     {
3239                       if (exprNode_isStringLiteral (fexp))
3240                         {
3241                           hasError = optgenerror 
3242                             (FLG_READONLYTRANS,
3243                              message
3244                              ("Read-only string literal storage %q%q: %q",
3245                               sRef_unparseOpt (fref),
3246                               transferErrorExpMessage (transferType, tekind),
3247                               generateText (fexp, texp, tref, transferType)),
3248                              loc);
3249                           
3250                         }
3251
3252                       if (!hasError)
3253                         {
3254                           hasError = optgenerror 
3255                             (FLG_OBSERVERTRANS,
3256                              message
3257                              ("Observer storage %q%q: %q",
3258                               sRef_unparseOpt (fref),
3259                               transferErrorExpMessage (transferType, tekind),
3260                               generateText (fexp, texp, tref, transferType)),
3261                              loc);
3262                         }
3263                     }
3264                 }
3265               
3266               if (hasError)
3267                 {
3268                   if (transferType != TT_GLOBINIT)
3269                     {
3270                       sRef_showExpInfo (fref);
3271                       sRef_setAliasKind (tref, AK_ERROR, loc);
3272                     }
3273                 }
3274               else 
3275                 {
3276                   if (transferType == TT_DOASSIGN && !tfix)
3277                     {
3278                       DPRINTF (("Setting unknown!"));
3279                       /* sRef_setAliasKind (tref, AK_ERROR, loc); */
3280                     }
3281                 }
3282             }
3283           else /* TT_FCNPASS */
3284             {
3285               llassert (transferType == TT_FCNPASS);
3286
3287               if (alkind_isTemp (tkind) 
3288                   || alkind_isDependent (tkind)
3289                   || alkind_isRefCounted (tkind))
3290                 {
3291                   ; /* okay */
3292                 }
3293               else 
3294                 {
3295                   if (!alkind_isError (tkind))
3296                     {
3297                       if (optgenerror 
3298                           (FLG_OBSERVERTRANS,
3299                            message ("Observer storage %q%q: %q",
3300                                     sRef_unparseOpt (fref),
3301                                     transferErrorMessage (transferType, tkind),
3302                                     generateText (fexp, texp, tref, transferType)),
3303                            loc))
3304                         {
3305                           sRef_showExpInfo (fref);
3306                           sRef_clearAliasState (fref, loc); 
3307                         }
3308                     }
3309                 }
3310             }
3311         }
3312     }
3313   else if (sRef_isExposed (fref) && ctype_isMutable (sRef_getType (fref)))
3314     {
3315       if (transferType == TT_FCNRETURN)
3316         {
3317           if (!(sRef_isExposed (tref) || sRef_isObserver (tref)
3318                 || sRef_isParam (fref)))
3319             {
3320               if (optgenerror
3321                   (FLG_EXPOSETRANS,
3322                    message ("Exposed storage %q%q: %q",
3323                             sRef_unparseOpt (fref),
3324                             transferErrorExpMessage (transferType, tekind),
3325                             generateText (fexp, texp, tref, transferType)),
3326                    loc))
3327                 {
3328                   sRef_showExpInfo (fref);
3329                 }
3330             }
3331         }
3332       else if (transferType == TT_FCNPASS)
3333         {
3334           if (!(sRef_isExposed (tref) 
3335                 || sRef_isObserver (tref)
3336                 || (alkind_isUnknown (tkind) 
3337                     || alkind_isDependent (tkind)
3338                     || alkind_isTemp (tkind)
3339                     || alkind_isKillRef (tkind)
3340                     || alkind_isRefCounted (tkind))))
3341             {
3342               if (alkind_isUnique (tkind) || alkind_isError (tkind))
3343                 {
3344                 }
3345               else 
3346                 {
3347                   if (optgenerror 
3348                       (FLG_EXPOSETRANS,
3349                        message ("Exposed storage %q%q: %q",
3350                                 sRef_unparseOpt (fref),
3351                                 transferErrorMessage (transferType, tkind),
3352                                 generateText (fexp, texp, tref, transferType)),
3353                        loc))
3354                     {
3355                       sRef_showExpInfo (fref);
3356                       sRef_clearAliasState (fref, loc); 
3357                     }
3358                 }
3359
3360             }
3361           else
3362             {
3363               ;
3364             }
3365         }
3366       else if (transferType == TT_DOASSIGN
3367                /* evans 2001-10-05: added TT_FIELDASSIGN: */
3368                || transferType == TT_FIELDASSIGN)
3369         {
3370           if (!(sRef_isExposed (tref) 
3371                 || !sRef_isCvar (tref)
3372                 || (alkind_isUnknown (tkind)
3373                     || alkind_isDependent (tkind)
3374                     || alkind_isRefCounted (tkind) 
3375                     || alkind_isNewRef (tkind)
3376                     || alkind_isFresh (tkind)
3377                     || alkind_isLocal (tkind))))
3378             {
3379               if (optgenerror 
3380                   (FLG_EXPOSETRANS,
3381                    message ("Exposed storage %q%q: %q",
3382                             sRef_unparseOpt (fref),
3383                             transferErrorExpMessage (transferType, tekind),
3384                             generateText (fexp, texp, tref, transferType)),
3385                    loc))
3386                 {
3387                   sRef_showExpInfo (fref);
3388                 }
3389             }
3390           if (!tfix) { sRef_setExposed (tref, loc); }
3391         }
3392       else
3393         {
3394           llassert (transferType == TT_GLOBPASS
3395                     || transferType == TT_GLOBRETURN
3396                     || transferType == TT_PARAMRETURN
3397                     || transferType == TT_LEAVETRANS
3398                     || transferType == TT_GLOBINIT);
3399         }
3400     }
3401   else
3402     {
3403       ;
3404     }
3405 }
3406
3407 /*
3408 ** returns TRUE if there is no error reported
3409 **
3410 ** if fixt, don't change tref (except if error reported.)
3411 ** if fixf, don't change fref (except if error reported.)
3412 */
3413
3414 static void
3415 checkTransferAux (exprNode fexp, /*@exposed@*/ sRef fref, bool ffix,
3416                   exprNode texp, /*@exposed@*/ sRef tref, bool tfix,
3417                   fileloc loc, transferKind transferType)
3418 {
3419   alkind fkind;
3420   alkind tkind;
3421   bool isassign = (transferType == TT_DOASSIGN);
3422   bool isfieldassign = (transferType == TT_FIELDASSIGN);
3423   bool iseitherassign = isassign || (transferType == TT_FIELDASSIGN);
3424   bool isfcnpass = (transferType == TT_FCNPASS);
3425   bool isfcnreturn = (transferType == TT_FCNRETURN);
3426
3427   DPRINTF (("Check transfer: %s [%s] => %s [%s]",
3428             exprNode_unparse (fexp),
3429             sRef_unparseFull (fref),
3430             exprNode_unparse (texp),
3431             sRef_unparseFull (tref)));
3432
3433   setCodePoint ();
3434
3435   if (!ffix && !tfix)
3436     {
3437       setCodePoint ();
3438       checkTransferNullAux (fref, fexp, ffix, tref, texp, tfix, 
3439                             loc, transferType);
3440       DPRINTF (("Transfer ==> %s", sRef_unparseFull (fref)));
3441     }
3442
3443   if (isassign)
3444     {
3445       setCodePoint ();
3446       checkTransferAssignAux (fref, fexp, ffix, tref, texp, tfix,
3447                               loc, transferType);
3448       DPRINTF (("Transfer ==> %s", sRef_unparseFull (fref)));
3449     }
3450
3451   /*
3452   ** Check for definition 
3453   */
3454
3455   /*
3456   ** errors passing out params already detected in checkAnyCall
3457   */
3458
3459   if (!ffix && !tfix)
3460     {
3461       bool defok = TRUE;
3462
3463       if (!iseitherassign 
3464           || (!sRef_isNSLocalVar (tref) 
3465               && (sRef_isAnyDefined (tref) || !sRef_stateKnown (tref))))
3466         {
3467           setCodePoint ();
3468
3469           if (!ynm_toBoolRelaxed 
3470               (checkCompletelyDefined (fexp, fref, fref,
3471                                        texp, tref,
3472                                        TRUE, FALSE, FALSE, 
3473                                        loc, transferType, 0, TRUE)))
3474             {
3475               defok = FALSE;
3476             }
3477         }
3478
3479       setCodePoint ();
3480       
3481       if (defok && iseitherassign)
3482         {
3483           sRef_setDefState (tref, sRef_getDefState (fref), loc);
3484         }
3485     }
3486
3487   /*
3488   ** check exposure
3489   */
3490
3491   setCodePoint ();
3492   checkTransferExposure (fref, fexp, ffix, tref, texp, tfix, 
3493                          loc, transferType);
3494
3495   fkind = sRef_getAliasKind (fref);
3496   tkind = sRef_getAliasKind (tref);
3497
3498   /*
3499   ** check aliasing
3500   */
3501
3502   if (alkind_isOnly (fkind))
3503     {
3504       setCodePoint ();
3505       checkOnlyTransferAux (fref, fexp, ffix,
3506                             tref, texp, tfix, 
3507                             loc, transferType);
3508     }
3509   else if (alkind_isFresh (fkind))
3510     {
3511       setCodePoint ();
3512       checkFreshTransferAux (fref, fexp, ffix,
3513                              tref, texp, tfix,
3514                              loc, transferType);
3515     }
3516   else if (alkind_isOwned (fkind))
3517     {
3518       setCodePoint ();
3519       checkOwnedTransferAux (fref, fexp, ffix,
3520                              tref, texp, tfix,
3521                              loc, transferType);
3522     }
3523   else if (alkind_isDependent (fkind))
3524     {
3525       setCodePoint ();
3526       if (isfcnreturn && 
3527           (sRef_isExposed (tref) || sRef_isObserver (tref)))
3528         {
3529           ; /* okay */
3530         }
3531       else if ((alkind_isOnly (tkind) || alkind_isKeep (tkind)
3532                 || alkind_isOwned (tkind))
3533                || (!isfcnpass && alkind_isTemp (tkind)))
3534         {
3535           bool error = TRUE;
3536
3537           if (sRef_isLocalVar (fref))
3538             {
3539               sRef depRef = dependentReference (fref);
3540
3541               if (sRef_isValid (depRef) && sRef_isLocalVar (depRef))
3542                 {
3543                   error = FALSE;
3544                   sRef_kill (depRef, loc);
3545                   sRef_kill (fref, loc);
3546                 }
3547
3548             }
3549
3550           if (isfieldassign)
3551             {
3552               error = FALSE;
3553             }
3554
3555           if (canLoseLocalReference (fref, loc))
3556             {
3557               ;
3558             }
3559           else
3560             {
3561               if (error &&
3562                   (optgenerror 
3563                    (FLG_DEPENDENTTRANS,
3564                     message ("%s storage %q%q: %q",
3565                              alkind_capName (fkind),
3566                              sRef_unparseOpt (fref),
3567                              transferErrorMessage (transferType, tkind),
3568                              generateText (fexp, texp, tref, transferType)),
3569                     loc)))
3570                 {
3571                   DPRINTF (("Here: %s / %s", 
3572                             sRef_unparseFull (fref),
3573                             sRef_unparseFull (tref)));
3574
3575                   sRef_showAliasInfo (fref);
3576                 }
3577             }
3578         }
3579       else 
3580         {
3581           if (isassign && (alkind_isFresh (tkind) || alkind_isLocal (tkind)))
3582             {
3583               if (!tfix && !ffix)
3584                 {
3585                   sRef_setDependent (tref, loc);
3586                 }
3587             }
3588         }
3589     }
3590   else if (alkind_isShared (fkind))
3591     {
3592       setCodePoint ();
3593       /*
3594       ** xxx <- shared
3595       */
3596
3597       if (alkind_isOnly (tkind) 
3598           || (!isfcnpass 
3599               && (!(sRef_isObserver (tref) || sRef_isExposed (tref)) 
3600                   && alkind_isTemp (tkind))))
3601         {
3602           if (optgenerror
3603               (FLG_SHAREDTRANS,
3604                message ("%s storage %q%q: %q",
3605                         alkind_capName (fkind),
3606                         sRef_unparseOpt (fref),
3607                         transferErrorMessage (transferType, tkind),
3608                         generateText (fexp, texp, tref, transferType)),
3609                loc))
3610             {
3611               sRef_showAliasInfo (fref);
3612             }
3613         }
3614       else 
3615         {
3616           if (alkind_isFresh (tkind) || alkind_isLocal (tkind))
3617             {
3618               sRef_setShared (tref, loc);
3619             }
3620         }
3621     }
3622   else if (alkind_isKeep (fkind))
3623     {
3624       setCodePoint ();
3625
3626       if (alkind_isKeep (tkind) 
3627           || alkind_isLocal (tkind)
3628           || (isfcnreturn && sRef_isExposed (tref))
3629           || (iseitherassign 
3630               && (alkind_isOnly (tkind) || alkind_isOwned (tkind))))
3631         {
3632           sRef_setKept (fref, loc);
3633         }
3634       else if (isfcnpass 
3635                && (alkind_isTemp (tkind) || alkind_isOwned (tkind)))
3636         {
3637           ;
3638         }
3639       else 
3640         {
3641           if (!alkind_isError (tkind))
3642             {
3643               if (optgenerror
3644                   (FLG_KEEPTRANS,
3645                    message ("%s storage %q: %q",
3646                             alkind_capName (fkind),
3647                             transferErrorMessage (transferType, tkind),
3648                             generateText (fexp, texp, tref, transferType)),
3649                    loc))
3650                 {
3651                   sRef_showAliasInfo (fref);
3652                 }
3653             }
3654         }
3655     }
3656   else if (alkind_isTemp (fkind) || alkind_isKept (fkind))
3657     {
3658       /*
3659       ** xxx <- temp
3660       */
3661       
3662       if (alkind_isOnly (tkind)
3663           || alkind_isShared (tkind) 
3664           || (alkind_isTemp (fkind)
3665               && !isfcnreturn && alkind_isDependent (tkind))
3666           || alkind_isOwned (tkind)
3667           || alkind_isKeep (tkind))
3668         {
3669           if (!exprNode_isNullValue (fexp)
3670               && (ctype_isMutable (exprNode_getType (fexp))
3671                   || (ctype_isArray (exprNode_getType (fexp))
3672                       && sRef_isParam (fref)))
3673               && (!iseitherassign || sRef_isReference (tref)))
3674             {
3675               if (sRef_isThroughArrayFetch (fref))
3676                 {
3677                   if (optgenerror2
3678                       (alkind_isTemp (fkind) ? FLG_TEMPTRANS : FLG_KEPTTRANS,
3679                        FLG_STRICTUSERELEASED,
3680                        message ("%s storage %q%q: %q",
3681                                 alkind_capName (fkind),
3682                                 sRef_unparseOpt (fref),
3683                                 transferErrorMessage (transferType, tkind),
3684                                 generateText (fexp, texp, tref, transferType)),
3685                        loc))
3686                     {
3687                       sRef_showAliasInfo (fref);
3688                     }
3689                 }
3690               else
3691                 {
3692                   if (optgenerror
3693                       (alkind_isTemp (fkind) ? FLG_TEMPTRANS : FLG_KEPTTRANS,
3694                        message ("%s storage %q%q: %q",
3695                                 alkind_capName (fkind),
3696                                 sRef_unparseOpt (fref),
3697                                 transferErrorMessage (transferType, tkind),
3698                                 generateText (fexp, texp, tref, transferType)),
3699                        loc))
3700                     {
3701                       sRef_showAliasInfo (fref);
3702                     }
3703                 }
3704             }
3705         }
3706     }
3707   else if (alkind_isRefCounted (fkind) || alkind_isKillRef (fkind))
3708     {
3709       if (alkind_isNewRef (tkind))
3710         {
3711           /*
3712           ** check that the refs field has been modified
3713           */
3714
3715           if (!sRef_isConst (fref))
3716             {
3717               voptgenerror 
3718                 (FLG_REFCOUNTTRANS,
3719                  message ("Reference counted storage returned without modifying "
3720                           "reference count: %s",
3721                           exprNode_unparse (fexp)),
3722                  loc);
3723             }
3724         }
3725       else if (iseitherassign)
3726         {
3727           if (alkind_isRefCounted (fkind))
3728             {
3729               if (!sRef_isLocalVar (tref))
3730                 {
3731                   vgenhinterror 
3732                     (FLG_REFCOUNTTRANS,
3733                      message 
3734                      ("Assignment to non-local from reference counted storage: %s",
3735                       exprNode_unparse (fexp)),
3736                      cstring_makeLiteral 
3737                      ("Reference counted storage should call a function returning "
3738                       "a newref instead of direct assignments."),
3739                      loc);
3740                 }
3741               else
3742                 {
3743                   ;
3744                 }
3745             }
3746         }
3747       else /* fcnpass */
3748         {
3749           if (alkind_isRefCounted (tkind) || alkind_isTemp (tkind))
3750             {
3751               /* okay --- no change in state */
3752             }
3753           else if (alkind_isKillRef (tkind))
3754             {
3755               if (!ffix && !tfix && !(transferType == TT_FCNRETURN))
3756                 { 
3757                   sRef_killComplete (fref, loc); 
3758                 }
3759             }
3760           else 
3761             {
3762               if (!alkind_isError (tkind))
3763                 {
3764                   voptgenerror
3765                     (FLG_REFCOUNTTRANS,
3766                      message ("Reference counted storage %q: %q",
3767                               transferErrorMessage (transferType, tkind),
3768                               generateText (fexp, texp, tref, transferType)),
3769                      loc);
3770                 }
3771             }
3772         }
3773     }
3774   else
3775     {
3776       ;
3777     }
3778
3779   setCodePoint ();
3780   
3781   if (alkind_isOnly (tkind) || alkind_isKeep (tkind))
3782     {
3783       if (sRef_isAddress (fref))
3784         {
3785           voptgenerror
3786             (FLG_IMMEDIATETRANS,
3787              message ("Immediate address %q %q: %q", 
3788                       sRef_unparse (fref),
3789                       transferErrorMessage (transferType, tkind),
3790                       generateText (fexp, texp, tref, transferType)),
3791              loc);
3792           
3793           sRef_setAliasKind (fref, AK_ERROR, loc);
3794         }
3795       else 
3796         {
3797           if ((alkind_isUnknown (fkind) || alkind_isStatic (fkind))
3798               && !sRef_isDefinitelyNull (fref)
3799               && (!ffix && !tfix)
3800               && (!exprNode_isNullValue (fexp)))
3801             {
3802               flagcode errkind = alkind_isStatic (fkind) 
3803                 ? FLG_STATICTRANS : FLG_UNKNOWNTRANS;
3804
3805               if (transferType == TT_GLOBINIT)
3806                 {
3807                   if (errkind == FLG_STATICTRANS)
3808                     {
3809                       errkind = FLG_STATICINITTRANS;
3810                     }
3811                   else
3812                     {
3813                       errkind = FLG_UNKNOWNINITTRANS;
3814                     }
3815                 }
3816
3817               if (optgenerror 
3818                   (errkind,
3819                    message ("%s storage %s %q: %q",
3820                             alkind_capName (fkind),
3821                             exprNode_unparse (fexp),
3822                             transferErrorMessage (transferType, tkind),
3823                             generateText (fexp, texp, tref, transferType)),
3824                    loc))
3825                 {
3826                   sRef_showAliasInfo (fref);
3827                 }
3828             }
3829         }
3830       
3831       /* don't kill shared to suppress future messages */
3832       if (!alkind_isShared (fkind))
3833         {
3834           if (isassign)
3835             {
3836               if (!ffix) 
3837                 {
3838                   /*< yuk! should do this in aliasaux >*/
3839                    
3840                   if (!sRef_isNSLocalVar (tref) && !sRef_sameName (fref, tref))
3841                     {
3842                       if (!tfix)
3843                         {
3844                           sRef_setKeptComplete (fref, loc);
3845                         }
3846                       else
3847                         {
3848                           sRef_setKept (fref, loc);
3849                         }
3850                     }
3851                 }
3852             }
3853           else
3854             {
3855               if (!ffix) 
3856                 {
3857                   if (!tfix)
3858                     {
3859                       if (alkind_isKeep (tkind))
3860                         {
3861                           sRef_setKeptComplete (fref, loc);
3862                         }
3863                       else
3864                         {
3865                           sRef_killComplete (fref, loc); 
3866                         }
3867                     }
3868                   else
3869                     {
3870                       if (alkind_isKeep (tkind))
3871                         {
3872                           sRef_setKept (fref, loc);
3873                         }
3874                       else
3875                         {
3876                           sRef_kill (fref, loc);
3877                         }
3878                     }
3879                 }
3880             }
3881         }
3882     }
3883   else if (alkind_isOwned (tkind))
3884     {
3885       /* don't kill shared to suppress future messages */
3886       if (!alkind_isShared (fkind)) 
3887         {
3888           if (!isassign 
3889               || !sRef_sameName (fref, tref)) /* result of return parameter */
3890             {
3891               if (!ffix)
3892                 {
3893                   if (!tfix)
3894                     {
3895                       sRef_setDependentComplete (fref, loc);
3896                     }
3897                   else
3898                     {
3899                       sRef_setDependent (fref, loc);
3900                     }
3901                 }
3902             }
3903         }
3904     }
3905   else if (alkind_isShared (tkind))
3906     {
3907       if (alkind_isFresh (fkind) || alkind_isLocal (fkind))
3908         {
3909           if (!ffix) 
3910             {
3911               sRef_setShared (fref, loc);
3912             }
3913         }
3914     }
3915   else if (alkind_isUnknown (tkind) && context_getFlag (FLG_MEMIMPLICIT))
3916     {
3917       if (alkind_isDependent (fkind))
3918         {
3919           if (!exprNode_isNullValue (fexp)
3920               && ctype_isMutable (exprNode_getType (fexp))
3921               && (!iseitherassign || sRef_isReference (tref)))
3922             {
3923               if (transferChecks_canLoseReference (fref, loc))
3924                 {
3925                   ;
3926                 }
3927               else
3928                 {
3929                   if (optgenerror
3930                       (FLG_DEPENDENTTRANS,
3931                        message ("%s storage %q%q: %q",
3932                                 alkind_capName (fkind),
3933                                 sRef_unparseOpt (fref),
3934                                 transferErrorMessage (transferType, tkind),
3935                                 generateText (fexp, texp, tref, transferType)),
3936                        loc))
3937                     {
3938                       DPRINTF (("Here: %s / %s", sRef_unparseFull (fref),
3939                                 sRef_unparseFull (tref)));
3940                       sRef_showAliasInfo (fref);
3941                     }
3942                 }
3943             }
3944         }
3945     }
3946   else if (alkind_isNewRef (tkind))
3947     {
3948       if (!ffix && !tfix)
3949         { 
3950           sRef_killComplete (fref, loc);  
3951         }
3952     }
3953   else if (alkind_isKillRef (tkind))
3954     {
3955       if (transferType == TT_FCNRETURN)
3956         {
3957           if (sRef_isNewRef (fref))
3958             {
3959               if (optgenerror
3960                   (FLG_REFCOUNTTRANS,
3961                    message ("New reference returned as temp reference: %q",
3962                             generateText (fexp, texp, tref, transferType)),
3963                    loc))
3964                 {
3965                   sRef_showAliasInfo (fref);
3966                 }
3967               }
3968         }
3969       else
3970         {
3971           if (sRef_isNewRef (fref))
3972             {
3973               sRef_killComplete (fref, loc);
3974             }
3975           else 
3976             {
3977               if (sRef_isRefCounted (fref) 
3978                   && sRef_isCvar (fref)
3979                   && !sRef_isLocalVar (fref))
3980                 {
3981                   if (optgenerror
3982                       (FLG_REFCOUNTTRANS,
3983                        message 
3984                        ("External reference counted storage released: %q",
3985                         generateText (fexp, texp, tref, transferType)),
3986                        loc))
3987                     {
3988                       sRef_showAliasInfo (fref);
3989                     }
3990                 }
3991             }
3992         }
3993           
3994     }
3995   else
3996     {
3997       ;
3998     }
3999
4000   DPRINTF (("Transfer ==> %s", sRef_unparseFull (fref)));
4001   DPRINTF (("Transfer ==> %s", sRef_unparseFull (tref)));
4002   setCodePoint ();
4003 }
4004
4005 static void
4006 checkMetaStateConsistent (/*@exposed@*/ sRef fref, sRef tref, 
4007                           fileloc loc, /*@unused@*/ transferKind transferType)
4008 {
4009   /*
4010   ** Checks if it is consistent to leave storage marked as tref in state of fref.
4011   */
4012
4013   valueTable fvalues = sRef_getValueTable (fref);
4014   valueTable tvalues = sRef_getValueTable (tref);
4015   
4016   DPRINTF (("Metastate consistent: %s => %s",
4017             sRef_unparseFull (fref),
4018             sRef_unparseFull (tref)));
4019   
4020   if (valueTable_isUndefined (tvalues) || valueTable_isUndefined (fvalues)) {
4021     /* Cannot check without value tables.  An error was already detected. */
4022     DPRINTF (("No value table: %s / %s",
4023               bool_unparse (valueTable_isUndefined (tvalues)),
4024               bool_unparse (valueTable_isUndefined (fvalues))));
4025     return;
4026   }
4027
4028   valueTable_elements (fvalues, fkey, fval) {
4029     stateValue tval;
4030     metaStateInfo minfo;
4031
4032     DPRINTF (("Transfer: %s", fkey));
4033     tval = valueTable_lookup (tvalues, fkey);
4034     minfo = context_lookupMetaStateInfo (fkey);
4035
4036     if (!stateValue_isDefined (tval)) 
4037       {
4038         if (ctype_isUnknown (sRef_getType (fref)))
4039           {
4040             ; /* Okay, put in default values without knowing type */
4041           }
4042         else
4043           {
4044             DPRINTF (("Cannot find meta state for: %s / to: %s / %s", sRef_unparseFull (fref),
4045                       sRef_unparseFull (tref),
4046                       fkey));
4047           }
4048       }
4049     else
4050       {
4051         llassert (metaStateInfo_isDefined (minfo));
4052         
4053         if (stateValue_isError (fval) || stateValue_isError (tval))
4054           {
4055             ;
4056           }
4057         else if (sRef_isDefinitelyNull (fref)
4058                  || usymtab_isDefinitelyNull (fref))
4059           {
4060             ; /* No errors for null values in state transfers. */
4061           }
4062         
4063         else
4064           {
4065             stateCombinationTable sctable = metaStateInfo_getTransferTable (minfo);
4066             cstring msg = cstring_undefined;
4067             int nval = stateCombinationTable_lookup (sctable, 
4068                                                      stateValue_getValue (fval), 
4069                                                      stateValue_getValue (tval), 
4070                                                      &msg);
4071             
4072             if (nval == stateValue_error)
4073               {
4074                 if (transferType == TT_LEAVETRANS)
4075                   {
4076                     BADBRANCH;
4077                   }
4078                 else if (transferType == TT_GLOBRETURN)
4079                   {
4080                     if (optgenerror 
4081                         (FLG_STATETRANSFER,
4082                          message
4083                          ("Function returns with global %q in inconsistent state (%q is %q, should be %q)%q",
4084                           sRef_unparse (sRef_getRootBase (fref)),
4085                           sRef_unparse (fref),
4086                           stateValue_unparseValue (fval, minfo),
4087                           stateValue_unparseValue (tval, minfo),
4088                           cstring_isDefined (msg) 
4089                           ? message (": %s", msg) : cstring_undefined),
4090                          loc))
4091                       {
4092                         sRef_showMetaStateInfo (fref, fkey);
4093                       }             
4094                   }
4095                 else if (transferType == TT_GLOBPASS)
4096                   {
4097                     if (optgenerror 
4098                         (FLG_STATETRANSFER,
4099                          message
4100                          ("Function called with global %q in inconsistent state (%q is %q, should be %q)%q",
4101                           sRef_unparse (sRef_getRootBase (fref)),
4102                           stateValue_unparseValue (fval, minfo),
4103                           sRef_unparse (fref),
4104                           stateValue_unparseValue (tval, minfo),
4105                           cstring_isDefined (msg) 
4106                           ? message (": %s", msg) : cstring_undefined),
4107                          loc))
4108                       {
4109                         sRef_showMetaStateInfo (fref, fkey);
4110                       }             
4111                   }
4112                 else if (transferType == TT_PARAMRETURN)
4113                   {
4114                     if (optgenerror 
4115                         (FLG_STATETRANSFER,
4116                          message
4117                          ("Function returns with parameter %q in inconsistent state (%q is %q, should be %q)%q",
4118                           sRef_unparse (sRef_getRootBase (fref)),
4119                           sRef_unparse (fref),                  
4120                           stateValue_unparseValue (fval, minfo),
4121                           stateValue_unparseValue (tval, minfo),
4122                           cstring_isDefined (msg) 
4123                           ? message (": %s", msg) : cstring_undefined),
4124                          loc))
4125                       {
4126                         sRef_showMetaStateInfo (fref, fkey);
4127                       }
4128                   }
4129                 else
4130                   {
4131                     if (optgenerror 
4132                         (FLG_STATETRANSFER,
4133                          message
4134                          ("Invalid transfer from %q %x to %q (%q)%q",
4135                           stateValue_unparseValue (fval, minfo),
4136                           sRef_unparse (fref),
4137                           stateValue_unparseValue (tval, minfo),
4138                           sRef_unparse (tref),
4139                           cstring_isDefined (msg) 
4140                           ? message (": %s", msg) : cstring_undefined),
4141                          loc))
4142                       {
4143                         sRef_showMetaStateInfo (fref, fkey);
4144                       }
4145                   }
4146
4147               }
4148                     
4149             if (stateValue_getValue (fval) != nval)
4150               {
4151                 stateValue_updateValueLoc (fval, nval, loc);
4152               }
4153           }
4154       }
4155     
4156     DPRINTF (("Transfer: %s %s -> %s",
4157               fkey, stateValue_unparse (fval), stateValue_unparse (tval)));
4158   } end_valueTable_elements ;
4159 }
4160
4161 static void
4162 checkMetaStateTransfer (exprNode fexp, sRef fref, exprNode texp, sRef tref, 
4163                         exprNode fcn,
4164                         fileloc loc, transferKind transferType)
4165 {
4166   valueTable fvalues = sRef_getValueTable (fref);
4167   valueTable tvalues = sRef_getValueTable (tref);
4168
4169   DPRINTF (("Metastate transfer: from %s", exprNode_unparse (fexp)));
4170   
4171   DPRINTF (("Metastate transfer: %s => %s",
4172             sRef_unparseFull (fref),
4173             sRef_unparseFull (tref)));
4174
4175   if (valueTable_isUndefined (tvalues) || valueTable_isUndefined (fvalues)) {
4176     /* Cannot check without value tables.  An error was already detected. */
4177     DPRINTF (("No value table: %s / %s",
4178               bool_unparse (valueTable_isUndefined (tvalues)),
4179               bool_unparse (valueTable_isUndefined (fvalues))));
4180     return;
4181   }
4182
4183   valueTable_elements (fvalues, fkey, fval) {
4184     stateValue tval;
4185     metaStateInfo minfo;
4186     stateCombinationTable sctable;
4187     cstring msg;
4188     int nval;
4189
4190     DPRINTF (("Transfer: %s", fkey));
4191     tval = valueTable_lookup (tvalues, fkey);
4192     minfo = context_lookupMetaStateInfo (fkey);
4193
4194     if (!stateValue_isDefined (tval)) 
4195       {
4196         if (ctype_isUnknown (sRef_getType (fref)))
4197           {
4198             ; /* Okay, put in default values without knowing type */
4199           }
4200         else
4201           {
4202             DPRINTF (("Metastate transfer: %s => %s",
4203                       exprNode_unparse (fexp), exprNode_unparse (texp)));
4204             DPRINTF (("Cannot find meta state for: %s / to: %s / %s", sRef_unparseFull (fref),
4205                       sRef_unparseFull (tref),
4206                       fkey));
4207           }
4208       }
4209     else
4210       {
4211         llassert (metaStateInfo_isDefined (minfo));
4212         
4213         if (stateValue_isError (fval))
4214           {
4215             ;
4216           }
4217         else if (stateValue_isError (tval))
4218           {
4219             if (sRef_isLocalVar (tref) && transferType == TT_DOASSIGN)
4220               {
4221                 /* Local assignments just replace state. */
4222                 stateValue_updateValueLoc (tval, stateValue_getValue (fval), loc);
4223                 DPRINTF (("Update: %s", stateValue_unparse (tval)));
4224               }
4225             else if (transferType == TT_FCNRETURN)
4226               {
4227                 ; /* Returning from an unannotated function */
4228               }
4229             else
4230               {
4231                 DPRINTF (("Transfer to error: %s / %s", sRef_unparseFull (tref),
4232                           transferType_unparse (transferType)));
4233               }
4234           }
4235         else 
4236           {
4237             DPRINTF (("Check: %s / %s / %s / %s", fkey,
4238                       metaStateInfo_unparse (minfo),
4239                       stateValue_unparse (fval),
4240                       stateValue_unparse (tval)));
4241             
4242             sctable = metaStateInfo_getTransferTable (minfo);
4243             msg = cstring_undefined;
4244             
4245             nval = stateCombinationTable_lookup (sctable, 
4246                                                  stateValue_getValue (fval), 
4247                                                  stateValue_getValue (tval), 
4248                                                  &msg);
4249             
4250             if (transferType == TT_DOASSIGN && sRef_isLocalVar (tref))
4251               {
4252                 /* Local assignments just replace state. */
4253                 DPRINTF (("No transfer error assigning to local: %s", msg));
4254                 stateValue_updateValueLoc (tval, stateValue_getValue (fval), loc);
4255                 DPRINTF (("Update: %s", stateValue_unparse (tval)));
4256               }
4257             else
4258               {
4259                 if (nval == stateValue_error)
4260                   {
4261                     if (optgenerror 
4262                         (FLG_STATETRANSFER,
4263                          message
4264                          ("Invalid transfer from %q %x to %q%q: %q",
4265                           stateValue_unparseValue (fval, minfo),
4266                           sRef_unparse (fref),
4267                           stateValue_unparseValue (tval, minfo),
4268                           cstring_isDefined (msg) 
4269                           ? message (" (%s)", msg) : cstring_undefined,
4270                           transferErrorExcerpt (transferType, fexp, texp, fcn)),
4271                          loc))
4272                       {
4273                         sRef_showMetaStateInfo (fref, fkey);
4274                         sRef_showMetaStateInfo (tref, fkey);
4275                       }
4276                     else
4277                       {
4278                         DPRINTF (("Suppressed transfer error: %s", msg));
4279                       }
4280                   }
4281                 else
4282                   {
4283                     if (transferType == TT_FCNRETURN)
4284                       {
4285                         /*
4286                         ** Returning this reference from a function, mark this reference
4287                         ** so no lost reference errors are returned.
4288                         */ 
4289
4290                         stateValue_updateValueLoc (fval, stateValue_error, loc);
4291                       }
4292                     else if (stateValue_getValue (fval) != nval)
4293                       {
4294                         stateValue_updateValueLoc (fval, nval, loc);
4295                       }
4296                     else
4297                       {
4298                         ;
4299                       }
4300                   }
4301               }
4302           }
4303       }
4304     
4305     DPRINTF (("Transfer: %s %s -> %s",
4306               fkey, stateValue_unparse (fval), stateValue_unparse (tval)));
4307   } end_valueTable_elements ;
4308 }
4309
4310 /*
4311 ** assigns fexp := tref or passes fexp as a parameter, or returns fexp.
4312 **
4313 ** For assignments, sets alias and definition state accordingly.
4314 */
4315
4316 static void
4317 checkTransfer (exprNode fexp, /*@dependent@*/ sRef fref, 
4318                exprNode texp, /*@dependent@*/ sRef tref, 
4319                exprNode fcn,
4320                fileloc loc, transferKind transferType)
4321 {
4322   setCodePoint ();
4323
4324   if (context_inProtectVars ())
4325     {
4326       return;
4327     }
4328   
4329   DPRINTF (("Check transfer: %s => %s",
4330             sRef_unparse (fref),
4331             sRef_unparse (tref)));
4332   DPRINTF (("Check transfer: %s => %s",
4333             exprNode_unparse (fexp),
4334             exprNode_unparse (texp)));
4335
4336   checkMetaStateTransfer (fexp, fref, texp, tref, fcn,
4337                           loc, transferType);
4338
4339   /*
4340   ** for local references, we need to check
4341   ** the transfer for all possible aliases.
4342   */
4343
4344   if (sRef_isLocalVar (tref) && transferType != TT_DOASSIGN)
4345     {    
4346       sRefSet alias = usymtab_allAliases (tref);
4347
4348       sRefSet_realElements (alias, atref)
4349         {
4350           sRef abase = sRef_getRootBase (atref);
4351
4352           if (sRef_isKnown (atref)
4353               && !sRef_isLocalVar (abase) 
4354               && !sRef_isExternal (abase))
4355             {
4356               atref = sRef_updateSref (atref);
4357
4358               if (sRef_hasName (atref))
4359                 {
4360                   if (!sRef_isNew (atref) 
4361                       && !sRef_sameName (tref, atref))
4362                     {
4363                       context_setAliasAnnote (atref, tref);
4364                     }
4365                   
4366                   checkTransferAux (fexp, fref, TRUE, 
4367                                     texp, atref, FALSE,
4368                                     loc, transferType);
4369                   
4370                   context_clearAliasAnnote ();
4371                 }
4372             }
4373         } end_sRefSet_realElements;
4374
4375       sRefSet_free (alias);
4376     }
4377
4378   if (sRef_isLocalVar (fref))
4379     {    
4380       sRefSet alias = usymtab_allAliases (fref);
4381
4382       sRefSet_realElements (alias, afref)
4383         {
4384           sRef abase = sRef_getRootBase (afref);
4385
4386           if (sRef_isKnown (afref) 
4387               && !sRef_isLocalVar (abase)
4388               && !sRef_isExternal (abase))
4389             {
4390               afref = sRef_updateSref (afref);
4391
4392               if (sRef_hasName (afref))
4393                 {
4394                   if (!sRef_isNew (afref) 
4395                       && !sRef_sameName (afref, fref))
4396                     {
4397                       context_setAliasAnnote (afref, fref);
4398                     }
4399                   
4400                   checkTransferAux (fexp, afref, FALSE,
4401                                     texp, tref, TRUE,
4402                                     loc, transferType);
4403                   
4404                   context_clearAliasAnnote ();
4405                 }
4406             }
4407         } end_sRefSet_realElements;
4408
4409       sRefSet_free (alias);
4410     }
4411   
4412   setCodePoint ();
4413   checkTransferAux (fexp, fref, FALSE, texp, tref, FALSE, 
4414                     loc, transferType);
4415   setCodePoint ();  
4416 }
4417
4418 static /*@exposed@*/ sRef 
4419   dependentReference (sRef sr)
4420 {
4421   sRefSet ab = usymtab_aliasedBy (sr); /* yes, really mean aliasedBy */
4422
4423   DPRINTF (("Dependent reference: %s", sRef_unparse (sr)));
4424   DPRINTF (("Aliases: %s", sRefSet_unparse (ab)));
4425
4426   /*
4427   ** If there is a local variable that aliases sr, then there is no
4428   ** error.  Make the local an only.
4429   */
4430   
4431   if (!sRefSet_isEmpty (ab))
4432     {
4433       sRef res = sRef_undefined;
4434
4435       DPRINTF (("Here we are!"));
4436
4437       /*
4438       ** make one an only, others alias it
4439       */
4440                   
4441       sRefSet_realElements (ab, current)
4442         {
4443           if (sRef_isOwned (current))
4444             {
4445               res = current; 
4446               break;
4447             }
4448         } end_sRefSet_realElements;
4449
4450       if (sRef_isInvalid (res))
4451         {
4452           /* 
4453           ** evans - 2001-03-24
4454           ** No owned element, just choose one! 
4455           ** (Any reason for preference?)
4456           */
4457
4458           res = sRefSet_choose (ab);
4459         }
4460
4461       sRefSet_free (ab);
4462       return res;
4463     }
4464
4465   return sRef_undefined;
4466 }
4467
4468 bool transferChecks_canLoseReference (/*@dependent@*/ sRef sr, fileloc loc)
4469 {
4470   bool gotone = FALSE;
4471   sRefSet ab = usymtab_aliasedBy (sr); /* yes, really mean aliasedBy */
4472
4473   DPRINTF (("Aliased by: %s", sRefSet_unparse (ab)));
4474
4475   /*
4476   ** if there is a local variable that aliases sr, then there is no
4477   ** error.  Make the local an only.
4478   */
4479   
4480   if (!sRefSet_isEmpty (ab))
4481     {
4482       /*
4483       ** make one an only, others alias it
4484       */
4485       
4486       sRefSet_realElements (ab, current)
4487         {
4488           sRef_setLastReference (current, sr, loc);
4489           gotone = TRUE;
4490           break;
4491         } end_sRefSet_realElements;
4492
4493       sRefSet_free (ab);
4494     }
4495
4496   return gotone;
4497 }
4498
4499 bool canLoseLocalReference (/*@dependent@*/ sRef sr, fileloc loc)
4500 {
4501   bool gotone = FALSE;
4502   sRefSet ab = usymtab_aliasedBy (sr); /* yes, really mean aliasedBy */
4503     
4504   /*
4505   ** if there is a local variable that aliases sr, then there is no
4506   ** error.  Make the local an only.
4507   */
4508   
4509   if (!sRefSet_isEmpty (ab))
4510     {
4511       /*
4512       ** make one an only, others alias it
4513       */
4514       
4515       sRefSet_realElements (ab, current)
4516         {
4517           if (sRef_isRealLocalVar (sRef_getRootBase (current)))
4518             {
4519               sRef_setLastReference (current, sr, loc);
4520               gotone = TRUE;
4521               break;
4522             }
4523         } end_sRefSet_realElements;
4524
4525       sRefSet_free (ab);
4526     }
4527
4528   return gotone;
4529 }
This page took 0.420503 seconds and 5 git commands to generate.