]> andersk Git - splint.git/blob - src/transferChecks.c
Fixed problem with global struct assignments.
[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           sRef_setNullUnknown (base, exprNode_loc (fexp));
2240         }
2241     }
2242
2243   if (isPartial)
2244     {
2245       if (sRef_isValid (fref))
2246         {
2247           sRef_setPartial (fref, exprNode_loc (fexp)); 
2248         }
2249     }
2250
2251   atFunction = exprNode_undefined;
2252   atArgNo = 0;
2253   atNumArgs = 0;
2254   
2255   /* need to fixup here: derived refs could be bogus */
2256   /* (better to change sRef to not add derivs for "protected" ref) */
2257
2258   uentry_fixupSref (arg);
2259
2260   setCodePoint ();
2261
2262   DPRINTF (("Check pass: ==> %s",
2263             sRef_unparseFull (fref)));
2264 }
2265
2266 void
2267 transferChecks_globalReturn (uentry glob)
2268 {
2269   sRef_protectDerivs ();
2270   checkGlobTrans (glob, TT_GLOBRETURN);
2271   sRef_clearProtectDerivs ();
2272 }
2273
2274 void transferChecks_paramReturn (uentry actual)
2275 {
2276   checkLeaveTrans (actual, TT_PARAMRETURN);
2277 }
2278
2279 void transferChecks_loseReference (uentry actual)
2280 {
2281   checkLeaveTrans (actual, TT_LEAVETRANS);
2282 }
2283
2284 static void
2285 checkLeaveTrans (uentry actual, transferKind transferType)
2286 {
2287   sRef aref = uentry_getSref (actual);
2288   sRef origref = uentry_getOrigSref (actual);
2289
2290   if (transferType == TT_PARAMRETURN 
2291       && (sRef_isKeep (origref) || sRef_isOnly (origref)
2292           || sRef_isOwned (origref)))
2293     {
2294       /* caller cannot use, nothing to check */
2295     }
2296   else
2297     {
2298       if (sRef_isNSLocalVar (origref))
2299         {
2300           ;
2301         }
2302       else
2303         {
2304           DPRINTF (("Leave trans: %s", uentry_unparseFull (actual)));
2305
2306           (void) checkCompletelyDefined (exprNode_undefined, aref, aref,
2307                                          exprNode_undefined, origref,
2308                                          TRUE, FALSE, FALSE,
2309                                          g_currentloc, transferType,
2310                                          0, TRUE);
2311         }
2312     }
2313 }
2314
2315 static void
2316 checkGlobTrans (uentry glob, transferKind type)
2317 {
2318   sRef eref = uentry_getOrigSref (glob);
2319  
2320   DPRINTF (("Completely defined: %s", uentry_unparseFull (glob)));
2321
2322   (void) checkCompletelyDefined (exprNode_undefined, uentry_getSref (glob), 
2323                                  uentry_getSref (glob),
2324                                  exprNode_undefined, eref, 
2325                                  TRUE, FALSE, FALSE,
2326                                  g_currentloc, type, 0, TRUE);
2327 }
2328
2329 /*
2330 ** For lhs of assignment, alias kind is set from basic type.
2331 ** Yoikes!
2332 */
2333
2334 static void
2335 fixAssignLhs (sRef s)
2336 {
2337   sRef_resetStateComplete (s);
2338 }
2339
2340 static void checkStructTransfer (exprNode lhs, sRef slhs, exprNode rhs, sRef srhs,
2341                                  fileloc loc,
2342                                  transferKind tt)
2343 {
2344   ctype st = ctype_realType (sRef_getType (srhs));
2345   
2346   if (ctype_isSU (st) && ctype_isRealSU (sRef_getType (slhs))
2347       && ctype_match (sRef_getType (slhs), st))
2348     {
2349       if ((tt == TT_DOASSIGN || tt == TT_FIELDASSIGN) && sRef_isStateDefined (srhs))
2350         {
2351           sRef_setDefinedComplete (slhs, loc);
2352         }
2353           
2354       if (sRef_isDependent (slhs)
2355           || sRef_isObserver (slhs)
2356           || sRef_isExposed (slhs))
2357         {
2358           ;
2359         }
2360       else
2361         {
2362           if (sRef_isLocalVar (slhs)
2363               && sRef_isFileOrGlobalScope (sRef_getRootBase (srhs)))
2364             {
2365               DPRINTF (("Global scope!"));
2366               sRef_setDependent (slhs, exprNode_loc (lhs));
2367             }
2368         }
2369
2370       /*
2371       ** evans 2003-07-10: should always copy the fields!
2372       */
2373
2374       if (ctype_isUnion (st))
2375         {
2376           sRef_setDefState (slhs, sRef_getDefState (srhs), 
2377                             exprNode_loc (lhs));
2378           
2379           sRefSet_realElements (sRef_derivedFields (srhs), sr)
2380             {
2381               if (sRef_isField (sr))
2382                 {
2383                   cstring fieldname = sRef_getField (sr);
2384                   sRef lfld = sRef_makeField (slhs, fieldname);
2385                   
2386                   (void) checkTransfer (rhs, sr, lhs, lfld, 
2387                                         exprNode_undefined,
2388                                         exprNode_loc (lhs), tt);
2389                 }
2390             } end_sRefSet_realElements ;
2391         }
2392       else
2393         {
2394           uentryList fields = ctype_getFields (st);
2395           
2396           uentryList_elements (fields, field)
2397             {
2398               sRef rfld = sRef_makeField (srhs, uentry_rawName (field));
2399               sRef lfld = sRef_makeField (slhs, uentry_rawName (field));
2400               DPRINTF (("Transfer field: %s := %s", 
2401                         sRef_unparse (lfld), sRef_unparse (rfld)));
2402               (void) checkTransfer (rhs, rfld, lhs, lfld, 
2403                                     exprNode_undefined,
2404                                     exprNode_loc (lhs), tt);
2405             } end_uentryList_elements ;
2406         }
2407       
2408       if (sRef_isOnly (srhs))
2409         {
2410           sRef_setKeptComplete (srhs, loc);
2411         }
2412     }
2413 }
2414
2415 void
2416 transferChecks_initialization (exprNode lhs, exprNode rhs)
2417 {
2418   sRef slhs = exprNode_getSref (lhs);
2419   
2420   if (sRef_isFileOrGlobalScope (slhs) || (!sRef_isCvar (slhs)))
2421     {
2422       (void) checkTransfer (rhs, exprNode_getSref (rhs), 
2423                             lhs, slhs, 
2424                             exprNode_undefined,
2425                             exprNode_loc (rhs), TT_GLOBINIT);
2426     }
2427   else
2428     {
2429       transferChecks_assign (lhs, rhs);
2430     }
2431 }
2432
2433 void
2434 transferChecks_assign (exprNode lhs, exprNode rhs)
2435 {
2436   sRef slhs = exprNode_getSref (lhs);
2437   sRef srhs = exprNode_getSref (rhs);
2438   sRef base = sRef_getBaseSafe (slhs);
2439   nstate ns;
2440   
2441   DPRINTF (("Check assign: %s = %s", exprNode_unparse (lhs),
2442             exprNode_unparse (rhs)));
2443   DPRINTF (("lhs: %s", sRef_unparseFull (slhs)));
2444   DPRINTF (("rhs: %s", sRef_unparseFull (srhs)));
2445
2446   if (ctype_isRealSU (sRef_getType (srhs)))
2447     {
2448       DPRINTF (("Check struct transfer: %s := %s", exprNode_unparse (lhs),
2449                 exprNode_unparse (rhs)));
2450       checkStructTransfer (lhs, slhs, rhs, srhs, exprNode_loc (lhs), TT_FIELDASSIGN);
2451     }
2452   else
2453     {
2454       DPRINTF (("lhs: %s", sRef_unparseFull (slhs)));
2455       DPRINTF (("rhs: %s", sRef_unparseFull (srhs)));
2456       (void) checkTransfer (rhs, srhs, lhs, slhs, 
2457                             exprNode_undefined,
2458                             exprNode_loc (lhs), TT_DOASSIGN);
2459       DPRINTF (("lhs: %s", sRef_unparseFull (slhs)));
2460       DPRINTF (("rhs: %s", sRef_unparseFull (srhs)));
2461     }
2462
2463   if (sRef_isConst (srhs) && sRef_isLocalState (srhs))
2464     {
2465       /* constants can match anything (e.g., NULL) */
2466       sRef_setAliasKind (slhs, AK_ERROR, fileloc_undefined);
2467     }
2468
2469   if (sRef_isValid (base) && sRef_isStateDefined (base))
2470     {
2471       sRef_setPdefined (base, g_currentloc); 
2472     }
2473
2474   if (sRef_isPartial (srhs))
2475     {
2476       sRef_setPartial (slhs, exprNode_loc (rhs));
2477     }
2478
2479   ns = sRef_getNullState (srhs);
2480
2481   if (nstate_possiblyNull (ns))
2482     {
2483       if (usymtab_isGuarded (srhs))
2484         {
2485           ns = NS_NOTNULL;
2486         }
2487     }
2488
2489   sRef_setNullStateInnerComplete (slhs, ns, exprNode_loc (rhs));
2490
2491   if (sRef_isExposed (srhs) || sRef_isObserver (srhs))
2492     {
2493       sRef_setExKind (slhs, sRef_getExKind (srhs), exprNode_loc (rhs));
2494     }
2495   
2496   DPRINTF (("Done transfer: %s", sRef_unparseFull (slhs)));
2497 }
2498
2499 static void
2500 checkTransferNullAux (sRef fref, exprNode fexp, /*@unused@*/ bool ffix,
2501                       sRef tref, exprNode texp, /*@unused@*/ bool tfix,
2502                       fileloc loc, transferKind transferType)
2503 {
2504   alkind tkind = sRef_getAliasKind (tref);
2505   ctype ttyp = ctype_realType (sRef_getType (tref));
2506
2507   if (ctype_isUnknown (ttyp))
2508     {
2509       ttyp = exprNode_getType (texp);
2510       
2511       if (ctype_isUnknown (ttyp))
2512         {
2513           ttyp = exprNode_getType (fexp);
2514
2515           if (ctype_isUnknown (ttyp))
2516             {
2517               ttyp = sRef_getType (fref);
2518             }
2519         }
2520     }
2521
2522   if (ctype_isFunction (ttyp) && (transferType == TT_FCNRETURN))
2523     {
2524       ttyp = ctype_getReturnType (ttyp);
2525     }
2526
2527   /*
2528   ** check for null (don't need to check aliases??)
2529   */
2530
2531   if (sRef_possiblyNull (fref) 
2532       && !usymtab_isGuarded (fref) 
2533       && ctype_isRealAP (ttyp))
2534     {
2535       if (!alkind_isLocal (tkind) && !alkind_isFresh (tkind)
2536           && !sRef_perhapsNull (tref)
2537           && !(transferType == TT_DOASSIGN))
2538         {
2539           if (transferType == TT_GLOBINIT)
2540             {
2541               if (sRef_isNotNull (tref))
2542                 {
2543                   if (optgenerror
2544                       (FLG_NULLINIT, /* kuldge flag... */
2545                        message ("%s %q initialized to %s value: %q",
2546                                 sRef_getScopeName (tref),
2547                                 sRef_unparse (tref),
2548                                 sRef_nullMessage (fref),
2549                                 generateText (fexp, texp, tref, transferType)),
2550                        loc))
2551                     {
2552                       sRef_showNullInfo (fref);
2553                       sRef_setNullError (tref);
2554                     }
2555                 }
2556               else
2557                 {
2558                   if (optgenerror
2559                       (FLG_NULLASSIGN,
2560                        message ("%s %q initialized to %s value: %q",
2561                                 sRef_getScopeName (tref),
2562                                 sRef_unparse (tref),
2563                                 sRef_nullMessage (fref),
2564                                 generateText (fexp, texp, tref, transferType)),
2565                        loc))
2566                     {
2567                       sRef_showNullInfo (fref);
2568                       sRef_setNullError (tref);
2569                     }
2570                 }
2571             }
2572           else
2573             {
2574               if (optgenerror
2575                   ((transferType == TT_FCNPASS) ? FLG_NULLPASS : FLG_NULLRET,
2576                    message ("%q storage %q%s: %q",
2577                             cstring_capitalize (sRef_nullMessage (fref)),
2578                             sRef_unparseOpt (fref),
2579                             transferNullMessage (transferType), 
2580                             generateText (fexp, texp, tref, transferType)),
2581                    loc))
2582                 {
2583                   sRef_showNullInfo (fref);
2584                   sRef_setNullError (fref);
2585                 }
2586             }
2587         }
2588       else
2589         {
2590           ;
2591         }
2592     }  
2593 }
2594
2595
2596 static void
2597 checkTransferAssignAux (sRef fref, exprNode fexp, /*@unused@*/ bool ffix,
2598                         /*@exposed@*/ sRef tref, exprNode texp, bool tfix,
2599                         fileloc loc, transferKind transferType)
2600 {
2601   alkind tkind = sRef_getAliasKind (tref);
2602
2603   /*
2604   ** Assignment to same --- no errors, or state changes.
2605   ** This can happen when returned params are used.
2606   */
2607
2608   if (sRef_sameName (fref, tref))
2609     {
2610       sRef_copyState (tref, fref); 
2611       return;
2612     }
2613   
2614   if ((alkind_isOnly (tkind) || alkind_isFresh (tkind) 
2615        || alkind_isNewRef (tkind) || alkind_isOwned (tkind))
2616       && !(sRef_isDead (tref) 
2617            || sRef_isStateUndefined (tref) 
2618            || sRef_isUnuseable (tref) 
2619            || sRef_isPartial (tref)
2620            || sRef_definitelyNull (tref) 
2621            || sRef_isStackAllocated (tref) 
2622            || sRef_isAllocIndexRef (tref))
2623       && !(sRef_same (fref, tref)) /* okay to assign to self (returned params) */
2624       && !(usymtab_isDefinitelyNull (tref))) 
2625     {
2626       if (transferChecks_canLoseReference (tref, loc))
2627         {
2628           ; /* no error */
2629         }
2630       else
2631         {
2632           flagcode flg = sRef_isFresh (tref) ? FLG_MUSTFREEFRESH : FLG_MUSTFREEONLY;
2633
2634           if (sRef_hasLastReference (tref))
2635             {
2636               if (optgenerror 
2637                   (flg,
2638                    message ("Last reference %q to %s storage %q(type %s) not released "
2639                             "before assignment: %q",
2640                             sRef_unparse (tref),
2641                             alkind_unparse (tkind),
2642                             sRef_unparseOpt (sRef_getAliasInfoRef (tref)),
2643                             ctype_unparse (sRef_getType (tref)),
2644                             generateText (fexp, texp, tref, transferType)),
2645                    loc))
2646                 {
2647                   sRef_showRefLost (tref);
2648                 }
2649             }
2650           else
2651             {
2652               if (context_inGlobalScope ())
2653                 {
2654                   /* no errors for static initializations */
2655                 }
2656               else 
2657                 {
2658                   /*
2659                   ** don't report this error for a[i], since it could
2660                   ** be a new element.
2661                   */
2662                   
2663                   if (alkind_isNewRef (tkind))
2664                     {
2665                       if (optgenerror 
2666                           (flg,
2667                            message 
2668                            ("%q %q(type %s) not released before assignment: %q",
2669                             cstring_makeLiteral
2670                             (alkind_isKillRef (sRef_getOrigAliasKind (tref))
2671                              ? "Kill reference parameter" : "New reference"),
2672                             sRef_unparseOpt (tref),
2673                             ctype_unparse (sRef_getType (tref)),
2674                             generateText (fexp, texp, tref, transferType)),
2675                            loc))
2676                         {
2677                           sRef_showAliasInfo (tref);
2678                           sRef_setAliasKind (tref, AK_ERROR, loc);
2679                         }
2680                     }
2681                   else if
2682                     (!(sRef_isUnknownArrayFetch (tref)
2683                        && !context_getFlag (FLG_STRICTDESTROY))
2684                      && !sRef_isUnionField (tref)
2685                      && !sRef_isRelDef (tref)
2686                      && optgenerror 
2687                      (flg,
2688                       message 
2689                       ("%s storage %q(type %s) not released before assignment: %q",
2690                        alkind_capName (tkind),
2691                        sRef_unparseOpt (tref),
2692                        ctype_unparse (sRef_getType (tref)),
2693                        generateText (fexp, texp, tref, transferType)),
2694                       loc))
2695                     {
2696                       sRef_showAliasInfo (tref);
2697                     }
2698                   else
2699                     {
2700                       ;
2701                     }
2702                 }
2703             }
2704         }
2705     }
2706
2707   fixAssignLhs (tref);
2708
2709   if (sRef_isRefCounted (tref)) /* tkind might not be correct now */
2710     {
2711       if (sRef_isNewRef (fref))
2712         {
2713           sRef_setAliasKind (tref, AK_NEWREF, loc);
2714         }
2715       else if (sRef_isConst (fref))
2716         {
2717           /* for now, constants are not ref counted */
2718           sRef_setAliasKind (tref, AK_ERROR, loc);
2719         }
2720       else
2721         {
2722           ;
2723         }
2724
2725       if (!sRef_isNSLocalVar (tref) 
2726           && sRef_isRefCounted (fref)
2727           && sRef_isStateDefined (fref))
2728         {
2729           voptgenerror 
2730             (FLG_NEWREFTRANS,
2731              message ("New reference %qto reference counted storage: %q",
2732                       sRef_unparseOpt (tref),
2733                       generateText (fexp, texp, tref, transferType)),
2734              loc);
2735         }
2736     }
2737
2738   /*
2739   ** Not for structures and unions, since assignments copy.
2740   */
2741
2742   if (sRef_isStack (fref)
2743       && !ctype_isSU (ctype_realType (sRef_getType (fref))))
2744     {
2745       sRef_setAliasKindComplete (tref, AK_STACK, loc);
2746     }
2747
2748   if (sRef_isNSLocalVar (tref) 
2749       && !sRef_isOwned (tref) /*< should only apply to static >*/
2750       && ctype_isMutable (sRef_getType (tref)))
2751     {
2752       if (sRef_isOnly (fref) && sRef_isNew (fref)) 
2753         {
2754           if (!tfix) 
2755             {
2756               sRef_setFresh (tref, loc);
2757             }
2758         }
2759     }
2760 }
2761
2762 /*
2763 ** requires sRef_isOnly (fref)
2764 */
2765
2766 static void
2767 checkOnlyTransferAux (sRef fref, exprNode fexp, bool ffix,
2768                       sRef tref, exprNode texp, /*@unused@*/ bool tfix,
2769                       fileloc loc, transferKind transferType)
2770 {     
2771   alkind tkind = sRef_getAliasKind (tref);
2772
2773   if (sRef_isExposed (tref) || sRef_isObserver (tref))
2774     {
2775       if (transferType == TT_FCNRETURN && sRef_isNew (fref)
2776           && !alkind_isError (tkind))
2777         {
2778           if (optgenerror 
2779               (FLG_ONLYTRANS,
2780                message ("Only storage %q%q (will not be released): %q",
2781                         sRef_unparseOpt (fref),
2782                         transferErrorMessage (transferType, tkind),
2783                         generateText (fexp, texp, tref, transferType)),
2784                loc))
2785             {
2786               sRef_showAliasInfo (fref);
2787             }
2788         }
2789       
2790       /* no errors for exposed transfers (is this good enough?) */
2791     }
2792   else if (alkind_isOnly (tkind) || alkind_isKeep (tkind) || alkind_isOwned (tkind))
2793     {
2794       ; /* okay */
2795     }
2796   else if ((transferType == TT_FCNPASS)
2797            && (alkind_isUnknown (tkind) 
2798                || alkind_isTemp (tkind) || alkind_isUnique (tkind)))
2799     {
2800       if (sRef_isFresh (fref) 
2801           && alkind_isUnknown (tkind) && !context_getFlag (FLG_PASSUNKNOWN))
2802         {
2803           if (!ffix) sRef_setAliasKind (fref, AK_UNKNOWN, loc); 
2804         }
2805     }
2806   else if (alkind_isLocal (tkind) 
2807            || alkind_isFresh (tkind) || alkind_isUnknown (tkind))
2808     {
2809       if ((transferType == TT_DOASSIGN)
2810           && sRef_isNew (fref) 
2811           && sRef_isOnly (fref))
2812         {
2813           bool error = FALSE;
2814
2815           if (alkind_isUnknown (tkind)
2816               && sRef_isFileOrGlobalScope (sRef_getRootBase (tref)))
2817             {
2818               if (optgenerror 
2819                   (FLG_ONLYUNQGLOBALTRANS,
2820                    message ("Only storage %q%q: %q",
2821                             sRef_unparseOpt (fref),
2822                             transferErrorMessage (transferType, tkind),
2823                             generateText (fexp, texp, tref, transferType)),
2824                    loc))
2825                 {
2826                   sRef_showAliasInfo (fref);
2827                   sRef_setAliasKind (tref, AK_ERROR, loc);
2828                   error = TRUE;
2829                 }
2830             }
2831
2832           if (!error && !ffix) 
2833             {
2834               sRef_setFresh (tref, loc);
2835             }
2836         }
2837       else
2838         {
2839           if (alkind_isLocal (tkind))
2840             {
2841               if (sRef_sameName (tref, fref))
2842                 {
2843                   ; /* don't set this --- corresponds to return transfer */
2844                 }
2845               else
2846                 {
2847                   /*
2848                   ** Don't set local to dependent.  Error will
2849                   ** be detected through aliasing.  Except for
2850                   ** arrays.
2851                   */
2852                   
2853                   if (!tfix && sRef_isThroughArrayFetch (fref)
2854                       && context_getFlag (FLG_DEPARRAYS))
2855                     {
2856                       sRef_setDependent (tref, loc);
2857                     }
2858                 }
2859             }
2860           else
2861             {
2862               if (optgenerror 
2863                   (FLG_ONLYTRANS,
2864                    message ("Only storage %q%q: %q",
2865                             sRef_unparseOpt (fref),
2866                             transferErrorMessage (transferType, tkind),
2867                             generateText (fexp, texp, tref, transferType)),
2868                    loc))
2869                 {
2870                   sRef_showAliasInfo (fref);
2871                 }
2872             }
2873         }
2874     }
2875   else
2876     {
2877       if (alkind_isError (tkind) 
2878           || (alkind_isUnknown (tkind) && !context_getFlag (FLG_MEMIMPLICIT)))
2879         {
2880           flagcode_recordSuppressed (FLG_ONLYTRANS);
2881         }
2882       else
2883         {
2884           if ((alkind_isKept (tkind) || alkind_isStack (tkind) 
2885                || alkind_isDependent (tkind))
2886               && sRef_isNSLocalVar (tref))
2887             {
2888               ; /* okay */
2889             }
2890           else
2891             {
2892               if (optgenerror 
2893                   (FLG_ONLYTRANS,
2894                    message ("Only storage %q%q: %q",
2895                             sRef_unparseOpt (fref),
2896                             transferErrorMessage (transferType, tkind),
2897                             generateText (fexp, texp, tref, transferType)),
2898                    loc))
2899                 {
2900                   sRef_showAliasInfo (fref);
2901                   
2902                   if (transferType == TT_DOASSIGN)
2903                     {
2904                       /*
2905                       ** alias kind unknown to suppress future messages
2906                       */
2907                       
2908                       if (!ffix && sRef_isNSLocalVar (sRef_getRootBase (fref)))
2909                         {
2910                           sRef_clearAliasKind (fref);
2911                         }
2912                     }
2913                 }
2914             }
2915         }
2916     }
2917 }
2918
2919 /*
2920 ** ??? same as checkOnly ?
2921 */
2922
2923 static void
2924 checkOwnedTransferAux (sRef fref, exprNode fexp, bool ffix,
2925                        sRef tref, exprNode texp, bool tfix,
2926                        fileloc loc, transferKind transferType)
2927 {     
2928   alkind tkind = sRef_getAliasKind (tref);
2929
2930   if (sRef_isExposed (tref) || sRef_isObserver (tref))
2931     {
2932       if (transferType == TT_FCNRETURN && sRef_isNew (fref))
2933         {
2934           if (optgenerror 
2935               (FLG_OWNEDTRANS,
2936                message ("Owned storage %q%q (will not be released): %q",
2937                         sRef_unparseOpt (fref),
2938                         transferErrorMessage (transferType, tkind),
2939                         generateText (fexp, texp, tref, transferType)),
2940                loc))
2941             {
2942               sRef_showAliasInfo (fref);
2943             }
2944         }
2945     }
2946   else if (alkind_isOnly (tkind) || alkind_isKeep (tkind) 
2947            || alkind_isDependent (tkind)
2948            || alkind_isOwned (tkind))
2949     {
2950       /* okay */
2951     }
2952   else if (alkind_isLocal (tkind)
2953            || alkind_isFresh (tkind) || alkind_isUnknown (tkind))
2954     {
2955       if ((transferType == TT_DOASSIGN)
2956           && sRef_isNew (fref) && sRef_isOnly (fref))
2957         {
2958           if (!tfix) 
2959             { 
2960               sRef_setFresh (tref, loc); 
2961             }
2962         }
2963       else
2964         {
2965         }
2966     }
2967   else if ((transferType == TT_FCNPASS)
2968            && (alkind_isUnknown (tkind) 
2969                || alkind_isTemp (tkind) || alkind_isUnique (tkind)))
2970     {
2971       if (sRef_isFresh (fref) 
2972           && alkind_isUnknown (tkind) && !context_getFlag (FLG_PASSUNKNOWN))
2973         {
2974           if (!ffix) { sRef_clearAliasKind (fref); }
2975         }
2976     }
2977   else
2978     {
2979       if (alkind_isUnknown (tkind) && !context_getFlag (FLG_MEMIMPLICIT))
2980         {
2981           flagcode_recordSuppressed (FLG_OWNEDTRANS);
2982         }
2983       else
2984         {
2985           if (alkind_isKept (tkind) && sRef_isNSLocalVar (tref))
2986             {
2987               ; /* okay */
2988             }
2989           else
2990             {
2991               voptgenerror
2992                 (FLG_OWNEDTRANS,
2993                  message ("Owned storage %q%q: %q",
2994                           sRef_unparseOpt (fref),
2995                           transferErrorMessage (transferType, tkind),
2996                           generateText (fexp, texp, tref, transferType)),
2997                  loc);
2998             }
2999         }
3000       
3001       if (transferType == TT_DOASSIGN)
3002         {
3003           /*
3004            ** alias kind unknown to suppress future messages
3005            */
3006           
3007           if (!ffix) { sRef_clearAliasKind (fref); }
3008         }
3009     }
3010 }
3011   
3012 static void
3013 checkFreshTransferAux (sRef fref, exprNode fexp, bool ffix,
3014                        sRef tref, exprNode texp, /*@unused@*/ bool tfix,
3015                        fileloc loc, transferKind transferType)
3016 {     
3017   alkind tkind = sRef_getAliasKind (tref);
3018
3019   /*
3020   ** error to return fresh as non-only
3021   */
3022
3023   if (transferType == TT_FCNRETURN
3024       && !(alkind_isOnly (tkind) || alkind_isNewRef (tkind)))
3025     {
3026       if (alkind_isUnknown (tkind) && !context_getFlag (FLG_MEMIMPLICIT))
3027         {
3028           flagcode_recordSuppressed (FLG_NEWREFTRANS);
3029         }
3030       else
3031         {
3032           if (alkind_isError (tkind))
3033             {
3034               if (!ffix) 
3035                 { 
3036                   sRef_killComplete (fref, loc); 
3037                 }
3038             }
3039           else if (alkind_isRefCounted (tkind))
3040             {
3041               if (optgenerror 
3042                   (FLG_NEWREFTRANS,
3043                    message
3044                    ("New reference returned without newref qualifier: %q",
3045                     generateText (fexp, texp, tref, transferType)),
3046                    loc))
3047                 {
3048                   sRef_showAliasInfo (fref);
3049                   sRef_killComplete (fref, loc);
3050                 }
3051               }
3052           else 
3053             {
3054               if (optgenerror 
3055                   (FLG_FRESHTRANS,
3056                    message ("Fresh storage %q (should be only): %q",
3057                             transferErrorMessage (transferType, tkind),
3058                             generateText (fexp, texp, tref, transferType)),
3059                    loc))
3060                 {
3061                   sRef_showAliasInfo (fref);
3062                   sRef_killComplete (fref, loc);
3063                 }
3064             }
3065         }
3066     }
3067   
3068   /*
3069   ** Okay to assign fresh to only, shared or unqualified.
3070   ** 
3071   ** should generate other errors? 
3072   */
3073
3074   if (alkind_isOnly (tkind))
3075     {
3076       if (transferType == TT_DOASSIGN && !sRef_isFileOrGlobalScope (tref))
3077         {
3078           if (!ffix) 
3079             { 
3080               if (!sRef_isNSLocalVar (tref))
3081                 {
3082                   sRef_setKeptComplete (fref, loc); 
3083                 }
3084             }
3085         }
3086       else
3087         {
3088           if (sRef_isConst (fref))
3089             {
3090               ;
3091             }
3092           else
3093             {
3094               if (!ffix) 
3095                 { 
3096                   sRef_killComplete (fref, loc); 
3097                 }
3098             }
3099         }
3100     }
3101   else if (alkind_isOwned (tkind))
3102     {
3103       if (!ffix) 
3104         { 
3105           sRef_setDependentComplete (fref, loc); 
3106         }
3107     }
3108   else if (alkind_isRefCounted (tkind)
3109            && (transferType == TT_FCNRETURN) && sRef_isFresh (fref))
3110     {
3111       if (!ffix) 
3112         { 
3113           sRef_killComplete (fref, loc); 
3114         }
3115     }
3116   else if (alkind_isKeep (tkind))
3117     {
3118       if (!ffix) 
3119         { 
3120           if (!sRef_isNSLocalVar (tref))
3121             {
3122               sRef_setKeptComplete (fref, loc); 
3123             }
3124         }
3125     }
3126   else if (alkind_isShared (tkind))
3127     {
3128       if (!ffix) { sRef_setShared (fref, loc); }
3129     }
3130   else if (alkind_isLocal (tkind) || alkind_isUnknown (tkind))
3131     {
3132       if (transferType == TT_DOASSIGN || transferType == TT_FCNRETURN)
3133         {
3134           /*
3135           ** local shares fresh.  Make it owned/dependent. 
3136           */
3137
3138           if (!tfix) 
3139             { 
3140               sRef_setOwned (tref, loc); 
3141             }
3142
3143           if (!ffix && !tfix) 
3144             { 
3145               sRef_setDependentComplete (fref, loc); 
3146             }
3147
3148           /* NO! sRef_clearAliasKind (fref); */
3149         }
3150       else 
3151         {
3152           if (context_getFlag (FLG_PASSUNKNOWN))
3153             {
3154               sRef_clearAliasKind (fref);
3155             }
3156         }
3157     }
3158   else
3159     {
3160       ;
3161     }
3162 }
3163
3164 static void
3165 checkTransferExposure (sRef fref, exprNode fexp, /*@unused@*/ bool ffix,
3166                        sRef tref, exprNode texp, bool tfix,
3167                        fileloc loc, 
3168                        transferKind transferType)
3169 {
3170   alkind fkind = sRef_getAliasKind (fref);
3171   alkind tkind = sRef_getAliasKind (tref);
3172   exkind tekind = sRef_getExKind (tref);
3173
3174   if (sRef_isObserver (fref) && ctype_isMutable (sRef_getType (fref)))
3175     {
3176       /*
3177       ** observer -> exposed or observer
3178       */
3179       
3180       /*
3181       ** observer -> temp is okay [NO!  really? only in function calls]
3182       */
3183
3184       if (sRef_isExposed (tref) || sRef_isObserver (tref)
3185           || alkind_isLocal (tkind))
3186         {
3187           /* okay */
3188           
3189           if ((transferType == TT_DOASSIGN) && alkind_isLocal (tkind))
3190             {
3191               if (!tfix) 
3192                 {
3193                   sRef_setAliasKindComplete (tref, fkind, loc); 
3194                 }
3195             }
3196         }
3197       else
3198         {
3199           if (transferType == TT_FCNRETURN 
3200               || transferType == TT_DOASSIGN
3201               || transferType == TT_FIELDASSIGN
3202               || transferType == TT_GLOBINIT)
3203             {
3204               bool hasError = FALSE;
3205               
3206               if (exprNode_isStringLiteral (fexp)
3207                   && transferType == TT_GLOBINIT)
3208                 {
3209                   hasError = optgenerror
3210                     (FLG_READONLYTRANS,
3211                      message ("Read-only string literal storage %q%q: %q",
3212                               sRef_unparseOpt (fref),
3213                               transferErrorExpMessage (transferType, tekind),
3214                               generateText (fexp, texp, tref, transferType)),
3215                      loc);
3216
3217                   sRef_setAliasKind (fref, AK_ERROR, fileloc_undefined);
3218                 }
3219               else 
3220                 {
3221                   if ((transferType == TT_DOASSIGN
3222                        || transferType == TT_FIELDASSIGN)
3223                       && (sRef_isNSLocalVar (tref)
3224                           || (exprNode_isStringLiteral (fexp)
3225                               && ctype_isRealArray (exprNode_getType (texp)))))
3226                     {
3227                       ; /* No error for local assignment or assignment
3228                            to static array (copies string). */
3229                     }
3230                   else
3231                     {
3232                       if (exprNode_isStringLiteral (fexp))
3233                         {
3234                           hasError = optgenerror 
3235                             (FLG_READONLYTRANS,
3236                              message
3237                              ("Read-only string literal storage %q%q: %q",
3238                               sRef_unparseOpt (fref),
3239                               transferErrorExpMessage (transferType, tekind),
3240                               generateText (fexp, texp, tref, transferType)),
3241                              loc);
3242                           
3243                         }
3244
3245                       if (!hasError)
3246                         {
3247                           hasError = optgenerror 
3248                             (FLG_OBSERVERTRANS,
3249                              message
3250                              ("Observer storage %q%q: %q",
3251                               sRef_unparseOpt (fref),
3252                               transferErrorExpMessage (transferType, tekind),
3253                               generateText (fexp, texp, tref, transferType)),
3254                              loc);
3255                         }
3256                     }
3257                 }
3258               
3259               if (hasError)
3260                 {
3261                   if (transferType != TT_GLOBINIT)
3262                     {
3263                       sRef_showExpInfo (fref);
3264                       sRef_setAliasKind (tref, AK_ERROR, loc);
3265                     }
3266                 }
3267               else 
3268                 {
3269                   if (transferType == TT_DOASSIGN && !tfix)
3270                     {
3271                       DPRINTF (("Setting unknown!"));
3272                       /* sRef_setAliasKind (tref, AK_ERROR, loc); */
3273                     }
3274                 }
3275             }
3276           else /* TT_FCNPASS */
3277             {
3278               llassert (transferType == TT_FCNPASS);
3279
3280               if (alkind_isTemp (tkind) 
3281                   || alkind_isDependent (tkind)
3282                   || alkind_isRefCounted (tkind))
3283                 {
3284                   ; /* okay */
3285                 }
3286               else 
3287                 {
3288                   if (!alkind_isError (tkind))
3289                     {
3290                       if (optgenerror 
3291                           (FLG_OBSERVERTRANS,
3292                            message ("Observer storage %q%q: %q",
3293                                     sRef_unparseOpt (fref),
3294                                     transferErrorMessage (transferType, tkind),
3295                                     generateText (fexp, texp, tref, transferType)),
3296                            loc))
3297                         {
3298                           sRef_showExpInfo (fref);
3299                           sRef_clearAliasState (fref, loc); 
3300                         }
3301                     }
3302                 }
3303             }
3304         }
3305     }
3306   else if (sRef_isExposed (fref) && ctype_isMutable (sRef_getType (fref)))
3307     {
3308       if (transferType == TT_FCNRETURN)
3309         {
3310           if (!(sRef_isExposed (tref) || sRef_isObserver (tref)
3311                 || sRef_isParam (fref)))
3312             {
3313               if (optgenerror
3314                   (FLG_EXPOSETRANS,
3315                    message ("Exposed storage %q%q: %q",
3316                             sRef_unparseOpt (fref),
3317                             transferErrorExpMessage (transferType, tekind),
3318                             generateText (fexp, texp, tref, transferType)),
3319                    loc))
3320                 {
3321                   sRef_showExpInfo (fref);
3322                 }
3323             }
3324         }
3325       else if (transferType == TT_FCNPASS)
3326         {
3327           if (!(sRef_isExposed (tref) 
3328                 || sRef_isObserver (tref)
3329                 || (alkind_isUnknown (tkind) 
3330                     || alkind_isDependent (tkind)
3331                     || alkind_isTemp (tkind)
3332                     || alkind_isKillRef (tkind)
3333                     || alkind_isRefCounted (tkind))))
3334             {
3335               if (alkind_isUnique (tkind) || alkind_isError (tkind))
3336                 {
3337                 }
3338               else 
3339                 {
3340                   if (optgenerror 
3341                       (FLG_EXPOSETRANS,
3342                        message ("Exposed storage %q%q: %q",
3343                                 sRef_unparseOpt (fref),
3344                                 transferErrorMessage (transferType, tkind),
3345                                 generateText (fexp, texp, tref, transferType)),
3346                        loc))
3347                     {
3348                       sRef_showExpInfo (fref);
3349                       sRef_clearAliasState (fref, loc); 
3350                     }
3351                 }
3352
3353             }
3354           else
3355             {
3356               ;
3357             }
3358         }
3359       else if (transferType == TT_DOASSIGN
3360                /* evans 2001-10-05: added TT_FIELDASSIGN: */
3361                || transferType == TT_FIELDASSIGN)
3362         {
3363           if (!(sRef_isExposed (tref) 
3364                 || !sRef_isCvar (tref)
3365                 || (alkind_isUnknown (tkind)
3366                     || alkind_isDependent (tkind)
3367                     || alkind_isRefCounted (tkind) 
3368                     || alkind_isNewRef (tkind)
3369                     || alkind_isFresh (tkind)
3370                     || alkind_isLocal (tkind))))
3371             {
3372               if (optgenerror 
3373                   (FLG_EXPOSETRANS,
3374                    message ("Exposed storage %q%q: %q",
3375                             sRef_unparseOpt (fref),
3376                             transferErrorExpMessage (transferType, tekind),
3377                             generateText (fexp, texp, tref, transferType)),
3378                    loc))
3379                 {
3380                   sRef_showExpInfo (fref);
3381                 }
3382             }
3383           if (!tfix) { sRef_setExposed (tref, loc); }
3384         }
3385       else
3386         {
3387           llassert (transferType == TT_GLOBPASS
3388                     || transferType == TT_GLOBRETURN
3389                     || transferType == TT_PARAMRETURN
3390                     || transferType == TT_LEAVETRANS
3391                     || transferType == TT_GLOBINIT);
3392         }
3393     }
3394   else
3395     {
3396       ;
3397     }
3398 }
3399
3400 /*
3401 ** returns TRUE if there is no error reported
3402 **
3403 ** if fixt, don't change tref (except if error reported.)
3404 ** if fixf, don't change fref (except if error reported.)
3405 */
3406
3407 static void
3408 checkTransferAux (exprNode fexp, /*@exposed@*/ sRef fref, bool ffix,
3409                   exprNode texp, /*@exposed@*/ sRef tref, bool tfix,
3410                   fileloc loc, transferKind transferType)
3411 {
3412   alkind fkind;
3413   alkind tkind;
3414   bool isassign = (transferType == TT_DOASSIGN);
3415   bool isfieldassign = (transferType == TT_FIELDASSIGN);
3416   bool iseitherassign = isassign || (transferType == TT_FIELDASSIGN);
3417   bool isfcnpass = (transferType == TT_FCNPASS);
3418   bool isfcnreturn = (transferType == TT_FCNRETURN);
3419
3420   setCodePoint ();
3421
3422   if (!ffix && !tfix)
3423     {
3424       setCodePoint ();
3425       checkTransferNullAux (fref, fexp, ffix, tref, texp, tfix, 
3426                             loc, transferType);
3427     }
3428
3429   if (isassign)
3430     {
3431       setCodePoint ();
3432       checkTransferAssignAux (fref, fexp, ffix, tref, texp, tfix,
3433                               loc, transferType);
3434     }
3435
3436   /*
3437   ** Check for definition 
3438   */
3439
3440   /*
3441   ** errors passing out params already detected in checkAnyCall
3442   */
3443
3444   if (!ffix && !tfix)
3445     {
3446       bool defok = TRUE;
3447
3448       if (!iseitherassign 
3449           || (!sRef_isNSLocalVar (tref) 
3450               && (sRef_isAnyDefined (tref) || !sRef_stateKnown (tref))))
3451         {
3452           setCodePoint ();
3453
3454           if (!ynm_toBoolRelaxed 
3455               (checkCompletelyDefined (fexp, fref, fref,
3456                                        texp, tref,
3457                                        TRUE, FALSE, FALSE, 
3458                                        loc, transferType, 0, TRUE)))
3459             {
3460               defok = FALSE;
3461             }
3462         }
3463
3464       setCodePoint ();
3465       
3466       if (defok && iseitherassign)
3467         {
3468           sRef_setDefState (tref, sRef_getDefState (fref), loc);
3469         }
3470     }
3471
3472   /*
3473   ** check exposure
3474   */
3475
3476   setCodePoint ();
3477   checkTransferExposure (fref, fexp, ffix, tref, texp, tfix, 
3478                          loc, transferType);
3479
3480   fkind = sRef_getAliasKind (fref);
3481   tkind = sRef_getAliasKind (tref);
3482
3483   /*
3484   ** check aliasing
3485   */
3486
3487   if (alkind_isOnly (fkind))
3488     {
3489       setCodePoint ();
3490       checkOnlyTransferAux (fref, fexp, ffix,
3491                             tref, texp, tfix, 
3492                             loc, transferType);
3493     }
3494   else if (alkind_isFresh (fkind))
3495     {
3496       setCodePoint ();
3497       checkFreshTransferAux (fref, fexp, ffix,
3498                              tref, texp, tfix,
3499                              loc, transferType);
3500     }
3501   else if (alkind_isOwned (fkind))
3502     {
3503       setCodePoint ();
3504       checkOwnedTransferAux (fref, fexp, ffix,
3505                              tref, texp, tfix,
3506                              loc, transferType);
3507     }
3508   else if (alkind_isDependent (fkind))
3509     {
3510       setCodePoint ();
3511       if (isfcnreturn && 
3512           (sRef_isExposed (tref) || sRef_isObserver (tref)))
3513         {
3514           ; /* okay */
3515         }
3516       else if ((alkind_isOnly (tkind) || alkind_isKeep (tkind)
3517                 || alkind_isOwned (tkind))
3518                || (!isfcnpass && alkind_isTemp (tkind)))
3519         {
3520           bool error = TRUE;
3521
3522           if (sRef_isLocalVar (fref))
3523             {
3524               sRef depRef = dependentReference (fref);
3525
3526               if (sRef_isValid (depRef) && sRef_isLocalVar (depRef))
3527                 {
3528                   error = FALSE;
3529                   sRef_kill (depRef, loc);
3530                   sRef_kill (fref, loc);
3531                 }
3532
3533             }
3534
3535           if (isfieldassign)
3536             {
3537               error = FALSE;
3538             }
3539
3540           if (canLoseLocalReference (fref, loc))
3541             {
3542               ;
3543             }
3544           else
3545             {
3546               if (error &&
3547                   (optgenerror 
3548                    (FLG_DEPENDENTTRANS,
3549                     message ("%s storage %q%q: %q",
3550                              alkind_capName (fkind),
3551                              sRef_unparseOpt (fref),
3552                              transferErrorMessage (transferType, tkind),
3553                              generateText (fexp, texp, tref, transferType)),
3554                     loc)))
3555                 {
3556                   DPRINTF (("Here: %s / %s", 
3557                             sRef_unparseFull (fref),
3558                             sRef_unparseFull (tref)));
3559
3560                   sRef_showAliasInfo (fref);
3561                 }
3562             }
3563         }
3564       else 
3565         {
3566           if (isassign && (alkind_isFresh (tkind) || alkind_isLocal (tkind)))
3567             {
3568               if (!tfix && !ffix)
3569                 {
3570                   sRef_setDependent (tref, loc);
3571                 }
3572             }
3573         }
3574     }
3575   else if (alkind_isShared (fkind))
3576     {
3577       setCodePoint ();
3578       /*
3579       ** xxx <- shared
3580       */
3581
3582       if (alkind_isOnly (tkind) 
3583           || (!isfcnpass 
3584               && (!(sRef_isObserver (tref) || sRef_isExposed (tref)) 
3585                   && alkind_isTemp (tkind))))
3586         {
3587           if (optgenerror
3588               (FLG_SHAREDTRANS,
3589                message ("%s storage %q%q: %q",
3590                         alkind_capName (fkind),
3591                         sRef_unparseOpt (fref),
3592                         transferErrorMessage (transferType, tkind),
3593                         generateText (fexp, texp, tref, transferType)),
3594                loc))
3595             {
3596               sRef_showAliasInfo (fref);
3597             }
3598         }
3599       else 
3600         {
3601           if (alkind_isFresh (tkind) || alkind_isLocal (tkind))
3602             {
3603               sRef_setShared (tref, loc);
3604             }
3605         }
3606     }
3607   else if (alkind_isKeep (fkind))
3608     {
3609       setCodePoint ();
3610
3611       if (alkind_isKeep (tkind) 
3612           || alkind_isLocal (tkind)
3613           || (isfcnreturn && sRef_isExposed (tref))
3614           || (iseitherassign 
3615               && (alkind_isOnly (tkind) || alkind_isOwned (tkind))))
3616         {
3617           sRef_setKept (fref, loc);
3618         }
3619       else if (isfcnpass 
3620                && (alkind_isTemp (tkind) || alkind_isOwned (tkind)))
3621         {
3622           ;
3623         }
3624       else 
3625         {
3626           if (!alkind_isError (tkind))
3627             {
3628               if (optgenerror
3629                   (FLG_KEEPTRANS,
3630                    message ("%s storage %q: %q",
3631                             alkind_capName (fkind),
3632                             transferErrorMessage (transferType, tkind),
3633                             generateText (fexp, texp, tref, transferType)),
3634                    loc))
3635                 {
3636                   sRef_showAliasInfo (fref);
3637                 }
3638             }
3639         }
3640     }
3641   else if (alkind_isTemp (fkind) || alkind_isKept (fkind))
3642     {
3643       /*
3644       ** xxx <- temp
3645       */
3646       
3647       if (alkind_isOnly (tkind)
3648           || alkind_isShared (tkind) 
3649           || (alkind_isTemp (fkind)
3650               && !isfcnreturn && alkind_isDependent (tkind))
3651           || alkind_isOwned (tkind)
3652           || alkind_isKeep (tkind))
3653         {
3654           if (!exprNode_isNullValue (fexp)
3655               && (ctype_isMutable (exprNode_getType (fexp))
3656                   || (ctype_isArray (exprNode_getType (fexp))
3657                       && sRef_isParam (fref)))
3658               && (!iseitherassign || sRef_isReference (tref)))
3659             {
3660               if (sRef_isThroughArrayFetch (fref))
3661                 {
3662                   if (optgenerror2
3663                       (alkind_isTemp (fkind) ? FLG_TEMPTRANS : FLG_KEPTTRANS,
3664                        FLG_STRICTUSERELEASED,
3665                        message ("%s storage %q%q: %q",
3666                                 alkind_capName (fkind),
3667                                 sRef_unparseOpt (fref),
3668                                 transferErrorMessage (transferType, tkind),
3669                                 generateText (fexp, texp, tref, transferType)),
3670                        loc))
3671                     {
3672                       sRef_showAliasInfo (fref);
3673                     }
3674                 }
3675               else
3676                 {
3677                   if (optgenerror
3678                       (alkind_isTemp (fkind) ? FLG_TEMPTRANS : FLG_KEPTTRANS,
3679                        message ("%s storage %q%q: %q",
3680                                 alkind_capName (fkind),
3681                                 sRef_unparseOpt (fref),
3682                                 transferErrorMessage (transferType, tkind),
3683                                 generateText (fexp, texp, tref, transferType)),
3684                        loc))
3685                     {
3686                       sRef_showAliasInfo (fref);
3687                     }
3688                 }
3689             }
3690         }
3691     }
3692   else if (alkind_isRefCounted (fkind) || alkind_isKillRef (fkind))
3693     {
3694       if (alkind_isNewRef (tkind))
3695         {
3696           /*
3697           ** check that the refs field has been modified
3698           */
3699
3700           if (!sRef_isConst (fref))
3701             {
3702               voptgenerror 
3703                 (FLG_REFCOUNTTRANS,
3704                  message ("Reference counted storage returned without modifying "
3705                           "reference count: %s",
3706                           exprNode_unparse (fexp)),
3707                  loc);
3708             }
3709         }
3710       else if (iseitherassign)
3711         {
3712           if (alkind_isRefCounted (fkind))
3713             {
3714               if (!sRef_isLocalVar (tref))
3715                 {
3716                   vgenhinterror 
3717                     (FLG_REFCOUNTTRANS,
3718                      message 
3719                      ("Assignment to non-local from reference counted storage: %s",
3720                       exprNode_unparse (fexp)),
3721                      cstring_makeLiteral 
3722                      ("Reference counted storage should call a function returning "
3723                       "a newref instead of direct assignments."),
3724                      loc);
3725                 }
3726               else
3727                 {
3728                   ;
3729                 }
3730             }
3731         }
3732       else /* fcnpass */
3733         {
3734           if (alkind_isRefCounted (tkind) || alkind_isTemp (tkind))
3735             {
3736               /* okay --- no change in state */
3737             }
3738           else if (alkind_isKillRef (tkind))
3739             {
3740               if (!ffix && !tfix && !(transferType == TT_FCNRETURN))
3741                 { 
3742                   sRef_killComplete (fref, loc); 
3743                 }
3744             }
3745           else 
3746             {
3747               if (!alkind_isError (tkind))
3748                 {
3749                   voptgenerror
3750                     (FLG_REFCOUNTTRANS,
3751                      message ("Reference counted storage %q: %q",
3752                               transferErrorMessage (transferType, tkind),
3753                               generateText (fexp, texp, tref, transferType)),
3754                      loc);
3755                 }
3756             }
3757         }
3758     }
3759   else
3760     {
3761       ;
3762     }
3763
3764   setCodePoint ();
3765   
3766   if (alkind_isOnly (tkind) || alkind_isKeep (tkind))
3767     {
3768       if (sRef_isAddress (fref))
3769         {
3770           voptgenerror
3771             (FLG_IMMEDIATETRANS,
3772              message ("Immediate address %q %q: %q", 
3773                       sRef_unparse (fref),
3774                       transferErrorMessage (transferType, tkind),
3775                       generateText (fexp, texp, tref, transferType)),
3776              loc);
3777           
3778           sRef_setAliasKind (fref, AK_ERROR, loc);
3779         }
3780       else 
3781         {
3782           if ((alkind_isUnknown (fkind) || alkind_isStatic (fkind))
3783               && !sRef_isDefinitelyNull (fref)
3784               && (!ffix && !tfix)
3785               && (!exprNode_isNullValue (fexp)))
3786             {
3787               flagcode errkind = alkind_isStatic (fkind) 
3788                 ? FLG_STATICTRANS : FLG_UNKNOWNTRANS;
3789
3790               if (transferType == TT_GLOBINIT)
3791                 {
3792                   if (errkind == FLG_STATICTRANS)
3793                     {
3794                       errkind = FLG_STATICINITTRANS;
3795                     }
3796                   else
3797                     {
3798                       errkind = FLG_UNKNOWNINITTRANS;
3799                     }
3800                 }
3801
3802               if (optgenerror 
3803                   (errkind,
3804                    message ("%s storage %s %q: %q",
3805                             alkind_capName (fkind),
3806                             exprNode_unparse (fexp),
3807                             transferErrorMessage (transferType, tkind),
3808                             generateText (fexp, texp, tref, transferType)),
3809                    loc))
3810                 {
3811                   sRef_showAliasInfo (fref);
3812                 }
3813             }
3814         }
3815       
3816       /* don't kill shared to suppress future messages */
3817       if (!alkind_isShared (fkind))
3818         {
3819           if (isassign)
3820             {
3821               if (!ffix) 
3822                 {
3823                   /*< yuk! should do this in aliasaux >*/
3824                    
3825                   if (!sRef_isNSLocalVar (tref) && !sRef_sameName (fref, tref))
3826                     {
3827                       if (!tfix)
3828                         {
3829                           sRef_setKeptComplete (fref, loc);
3830                         }
3831                       else
3832                         {
3833                           sRef_setKept (fref, loc);
3834                         }
3835                     }
3836                 }
3837             }
3838           else
3839             {
3840               if (!ffix) 
3841                 {
3842                   if (!tfix)
3843                     {
3844                       if (alkind_isKeep (tkind))
3845                         {
3846                           sRef_setKeptComplete (fref, loc);
3847                         }
3848                       else
3849                         {
3850                           sRef_killComplete (fref, loc); 
3851                         }
3852                     }
3853                   else
3854                     {
3855                       if (alkind_isKeep (tkind))
3856                         {
3857                           sRef_setKept (fref, loc);
3858                         }
3859                       else
3860                         {
3861                           sRef_kill (fref, loc);
3862                         }
3863                     }
3864                 }
3865             }
3866         }
3867     }
3868   else if (alkind_isOwned (tkind))
3869     {
3870       /* don't kill shared to suppress future messages */
3871       if (!alkind_isShared (fkind)) 
3872         {
3873           if (!isassign 
3874               || !sRef_sameName (fref, tref)) /* result of return parameter */
3875             {
3876               if (!ffix)
3877                 {
3878                   if (!tfix)
3879                     {
3880                       sRef_setDependentComplete (fref, loc);
3881                     }
3882                   else
3883                     {
3884                       sRef_setDependent (fref, loc);
3885                     }
3886                 }
3887             }
3888         }
3889     }
3890   else if (alkind_isShared (tkind))
3891     {
3892       if (alkind_isFresh (fkind) || alkind_isLocal (fkind))
3893         {
3894           if (!ffix) 
3895             {
3896               sRef_setShared (fref, loc);
3897             }
3898         }
3899     }
3900   else if (alkind_isUnknown (tkind) && context_getFlag (FLG_MEMIMPLICIT))
3901     {
3902       if (alkind_isDependent (fkind))
3903         {
3904           if (!exprNode_isNullValue (fexp)
3905               && ctype_isMutable (exprNode_getType (fexp))
3906               && (!iseitherassign || sRef_isReference (tref)))
3907             {
3908               if (transferChecks_canLoseReference (fref, loc))
3909                 {
3910                   ;
3911                 }
3912               else
3913                 {
3914                   if (optgenerror
3915                       (FLG_DEPENDENTTRANS,
3916                        message ("%s storage %q%q: %q",
3917                                 alkind_capName (fkind),
3918                                 sRef_unparseOpt (fref),
3919                                 transferErrorMessage (transferType, tkind),
3920                                 generateText (fexp, texp, tref, transferType)),
3921                        loc))
3922                     {
3923                       DPRINTF (("Here: %s / %s", sRef_unparseFull (fref),
3924                                 sRef_unparseFull (tref)));
3925                       sRef_showAliasInfo (fref);
3926                     }
3927                 }
3928             }
3929         }
3930     }
3931   else if (alkind_isNewRef (tkind))
3932     {
3933       if (!ffix && !tfix)
3934         { 
3935           sRef_killComplete (fref, loc);  
3936         }
3937     }
3938   else if (alkind_isKillRef (tkind))
3939     {
3940       if (transferType == TT_FCNRETURN)
3941         {
3942           if (sRef_isNewRef (fref))
3943             {
3944               if (optgenerror
3945                   (FLG_REFCOUNTTRANS,
3946                    message ("New reference returned as temp reference: %q",
3947                             generateText (fexp, texp, tref, transferType)),
3948                    loc))
3949                 {
3950                   sRef_showAliasInfo (fref);
3951                 }
3952               }
3953         }
3954       else
3955         {
3956           if (sRef_isNewRef (fref))
3957             {
3958               sRef_killComplete (fref, loc);
3959             }
3960           else 
3961             {
3962               if (sRef_isRefCounted (fref) 
3963                   && sRef_isCvar (fref)
3964                   && !sRef_isLocalVar (fref))
3965                 {
3966                   if (optgenerror
3967                       (FLG_REFCOUNTTRANS,
3968                        message 
3969                        ("External reference counted storage released: %q",
3970                         generateText (fexp, texp, tref, transferType)),
3971                        loc))
3972                     {
3973                       sRef_showAliasInfo (fref);
3974                     }
3975                 }
3976             }
3977         }
3978           
3979     }
3980   else
3981     {
3982       ;
3983     }
3984
3985   setCodePoint ();
3986 }
3987
3988 static void
3989 checkMetaStateConsistent (/*@exposed@*/ sRef fref, sRef tref, 
3990                           fileloc loc, /*@unused@*/ transferKind transferType)
3991 {
3992   /*
3993   ** Checks if it is consistent to leave storage marked as tref in state of fref.
3994   */
3995
3996   valueTable fvalues = sRef_getValueTable (fref);
3997   valueTable tvalues = sRef_getValueTable (tref);
3998   
3999   DPRINTF (("Metastate consistent: %s => %s",
4000             sRef_unparseFull (fref),
4001             sRef_unparseFull (tref)));
4002   
4003   if (valueTable_isUndefined (tvalues) || valueTable_isUndefined (fvalues)) {
4004     /* Cannot check without value tables.  An error was already detected. */
4005     DPRINTF (("No value table: %s / %s",
4006               bool_unparse (valueTable_isUndefined (tvalues)),
4007               bool_unparse (valueTable_isUndefined (fvalues))));
4008     return;
4009   }
4010
4011   valueTable_elements (fvalues, fkey, fval) {
4012     stateValue tval;
4013     metaStateInfo minfo;
4014
4015     DPRINTF (("Transfer: %s", fkey));
4016     tval = valueTable_lookup (tvalues, fkey);
4017     minfo = context_lookupMetaStateInfo (fkey);
4018
4019     if (!stateValue_isDefined (tval)) 
4020       {
4021         if (ctype_isUnknown (sRef_getType (fref)))
4022           {
4023             ; /* Okay, put in default values without knowing type */
4024           }
4025         else
4026           {
4027             DPRINTF (("Cannot find meta state for: %s / to: %s / %s", sRef_unparseFull (fref),
4028                       sRef_unparseFull (tref),
4029                       fkey));
4030           }
4031       }
4032     else
4033       {
4034         llassert (metaStateInfo_isDefined (minfo));
4035         
4036         if (stateValue_isError (fval) || stateValue_isError (tval))
4037           {
4038             ;
4039           }
4040         else if (sRef_isDefinitelyNull (fref)
4041                  || usymtab_isDefinitelyNull (fref))
4042           {
4043             ; /* No errors for null values in state transfers. */
4044           }
4045         
4046         else
4047           {
4048             stateCombinationTable sctable = metaStateInfo_getTransferTable (minfo);
4049             cstring msg = cstring_undefined;
4050             int nval = stateCombinationTable_lookup (sctable, 
4051                                                      stateValue_getValue (fval), 
4052                                                      stateValue_getValue (tval), 
4053                                                      &msg);
4054             
4055             if (nval == stateValue_error)
4056               {
4057                 if (transferType == TT_LEAVETRANS)
4058                   {
4059                     BADBRANCH;
4060                   }
4061                 else if (transferType == TT_GLOBRETURN)
4062                   {
4063                     if (optgenerror 
4064                         (FLG_STATETRANSFER,
4065                          message
4066                          ("Function returns with global %q in inconsistent state (%q is %q, should be %q)%q",
4067                           sRef_unparse (sRef_getRootBase (fref)),
4068                           sRef_unparse (fref),
4069                           stateValue_unparseValue (fval, minfo),
4070                           stateValue_unparseValue (tval, minfo),
4071                           cstring_isDefined (msg) 
4072                           ? message (": %s", msg) : cstring_undefined),
4073                          loc))
4074                       {
4075                         sRef_showMetaStateInfo (fref, fkey);
4076                       }             
4077                   }
4078                 else if (transferType == TT_GLOBPASS)
4079                   {
4080                     if (optgenerror 
4081                         (FLG_STATETRANSFER,
4082                          message
4083                          ("Function called with global %q in inconsistent state (%q is %q, should be %q)%q",
4084                           sRef_unparse (sRef_getRootBase (fref)),
4085                           stateValue_unparseValue (fval, minfo),
4086                           sRef_unparse (fref),
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_PARAMRETURN)
4096                   {
4097                     if (optgenerror 
4098                         (FLG_STATETRANSFER,
4099                          message
4100                          ("Function returns with parameter %q in inconsistent state (%q is %q, should be %q)%q",
4101                           sRef_unparse (sRef_getRootBase (fref)),
4102                           sRef_unparse (fref),                  
4103                           stateValue_unparseValue (fval, minfo),
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
4113                   {
4114                     if (optgenerror 
4115                         (FLG_STATETRANSFER,
4116                          message
4117                          ("Invalid transfer from %q %x to %q (%q)%q",
4118                           stateValue_unparseValue (fval, minfo),
4119                           sRef_unparse (fref),
4120                           stateValue_unparseValue (tval, minfo),
4121                           sRef_unparse (tref),
4122                           cstring_isDefined (msg) 
4123                           ? message (": %s", msg) : cstring_undefined),
4124                          loc))
4125                       {
4126                         sRef_showMetaStateInfo (fref, fkey);
4127                       }
4128                   }
4129
4130               }
4131                     
4132             if (stateValue_getValue (fval) != nval)
4133               {
4134                 stateValue_updateValueLoc (fval, nval, loc);
4135               }
4136           }
4137       }
4138     
4139     DPRINTF (("Transfer: %s %s -> %s",
4140               fkey, stateValue_unparse (fval), stateValue_unparse (tval)));
4141   } end_valueTable_elements ;
4142 }
4143
4144 static void
4145 checkMetaStateTransfer (exprNode fexp, sRef fref, exprNode texp, sRef tref, 
4146                         exprNode fcn,
4147                         fileloc loc, transferKind transferType)
4148 {
4149   valueTable fvalues = sRef_getValueTable (fref);
4150   valueTable tvalues = sRef_getValueTable (tref);
4151
4152   DPRINTF (("Metastate transfer: from %s", exprNode_unparse (fexp)));
4153   
4154   DPRINTF (("Metastate transfer: %s => %s",
4155             sRef_unparseFull (fref),
4156             sRef_unparseFull (tref)));
4157
4158   if (valueTable_isUndefined (tvalues) || valueTable_isUndefined (fvalues)) {
4159     /* Cannot check without value tables.  An error was already detected. */
4160     DPRINTF (("No value table: %s / %s",
4161               bool_unparse (valueTable_isUndefined (tvalues)),
4162               bool_unparse (valueTable_isUndefined (fvalues))));
4163     return;
4164   }
4165
4166   valueTable_elements (fvalues, fkey, fval) {
4167     stateValue tval;
4168     metaStateInfo minfo;
4169     stateCombinationTable sctable;
4170     cstring msg;
4171     int nval;
4172
4173     DPRINTF (("Transfer: %s", fkey));
4174     tval = valueTable_lookup (tvalues, fkey);
4175     minfo = context_lookupMetaStateInfo (fkey);
4176
4177     if (!stateValue_isDefined (tval)) 
4178       {
4179         if (ctype_isUnknown (sRef_getType (fref)))
4180           {
4181             ; /* Okay, put in default values without knowing type */
4182           }
4183         else
4184           {
4185             DPRINTF (("Metastate transfer: %s => %s",
4186                       exprNode_unparse (fexp), exprNode_unparse (texp)));
4187             DPRINTF (("Cannot find meta state for: %s / to: %s / %s", sRef_unparseFull (fref),
4188                       sRef_unparseFull (tref),
4189                       fkey));
4190           }
4191       }
4192     else
4193       {
4194         llassert (metaStateInfo_isDefined (minfo));
4195         
4196         if (stateValue_isError (fval))
4197           {
4198             ;
4199           }
4200         else if (stateValue_isError (tval))
4201           {
4202             if (sRef_isLocalVar (tref) && transferType == TT_DOASSIGN)
4203               {
4204                 /* Local assignments just replace state. */
4205                 stateValue_updateValueLoc (tval, stateValue_getValue (fval), loc);
4206                 DPRINTF (("Update: %s", stateValue_unparse (tval)));
4207               }
4208             else if (transferType == TT_FCNRETURN)
4209               {
4210                 ; /* Returning from an unannotated function */
4211               }
4212             else
4213               {
4214                 DPRINTF (("Transfer to error: %s / %s", sRef_unparseFull (tref),
4215                           transferType_unparse (transferType)));
4216               }
4217           }
4218         else 
4219           {
4220             DPRINTF (("Check: %s / %s / %s / %s", fkey,
4221                       metaStateInfo_unparse (minfo),
4222                       stateValue_unparse (fval),
4223                       stateValue_unparse (tval)));
4224             
4225             sctable = metaStateInfo_getTransferTable (minfo);
4226             msg = cstring_undefined;
4227             
4228             nval = stateCombinationTable_lookup (sctable, 
4229                                                  stateValue_getValue (fval), 
4230                                                  stateValue_getValue (tval), 
4231                                                  &msg);
4232             
4233             if (transferType == TT_DOASSIGN && sRef_isLocalVar (tref))
4234               {
4235                 /* Local assignments just replace state. */
4236                 DPRINTF (("No transfer error assigning to local: %s", msg));
4237                 stateValue_updateValueLoc (tval, stateValue_getValue (fval), loc);
4238                 DPRINTF (("Update: %s", stateValue_unparse (tval)));
4239               }
4240             else
4241               {
4242                 if (nval == stateValue_error)
4243                   {
4244                     if (optgenerror 
4245                         (FLG_STATETRANSFER,
4246                          message
4247                          ("Invalid transfer from %q %x to %q%q: %q",
4248                           stateValue_unparseValue (fval, minfo),
4249                           sRef_unparse (fref),
4250                           stateValue_unparseValue (tval, minfo),
4251                           cstring_isDefined (msg) 
4252                           ? message (" (%s)", msg) : cstring_undefined,
4253                           transferErrorExcerpt (transferType, fexp, texp, fcn)),
4254                          loc))
4255                       {
4256                         sRef_showMetaStateInfo (fref, fkey);
4257                         sRef_showMetaStateInfo (tref, fkey);
4258                       }
4259                     else
4260                       {
4261                         DPRINTF (("Suppressed transfer error: %s", msg));
4262                       }
4263                   }
4264                 else
4265                   {
4266                     if (transferType == TT_FCNRETURN)
4267                       {
4268                         /*
4269                         ** Returning this reference from a function, mark this reference
4270                         ** so no lost reference errors are returned.
4271                         */ 
4272
4273                         stateValue_updateValueLoc (fval, stateValue_error, loc);
4274                       }
4275                     else if (stateValue_getValue (fval) != nval)
4276                       {
4277                         stateValue_updateValueLoc (fval, nval, loc);
4278                       }
4279                     else
4280                       {
4281                         ;
4282                       }
4283                   }
4284               }
4285           }
4286       }
4287     
4288     DPRINTF (("Transfer: %s %s -> %s",
4289               fkey, stateValue_unparse (fval), stateValue_unparse (tval)));
4290   } end_valueTable_elements ;
4291 }
4292
4293 /*
4294 ** assigns fexp := tref or passes fexp as a parameter, or returns fexp.
4295 **
4296 ** For assignments, sets alias and definition state accordingly.
4297 */
4298
4299 static void
4300 checkTransfer (exprNode fexp, /*@dependent@*/ sRef fref, 
4301                exprNode texp, /*@dependent@*/ sRef tref, 
4302                exprNode fcn,
4303                fileloc loc, transferKind transferType)
4304 {
4305   setCodePoint ();
4306
4307   if (context_inProtectVars ())
4308     {
4309       return;
4310     }
4311   
4312   DPRINTF (("Check transfer: %s => %s",
4313             sRef_unparse (fref),
4314             sRef_unparse (tref)));
4315   DPRINTF (("Check transfer: %s => %s",
4316             exprNode_unparse (fexp),
4317             exprNode_unparse (texp)));
4318
4319   checkMetaStateTransfer (fexp, fref, texp, tref, fcn,
4320                           loc, transferType);
4321
4322   /*
4323   ** for local references, we need to check
4324   ** the transfer for all possible aliases.
4325   */
4326
4327   if (sRef_isLocalVar (tref) && transferType != TT_DOASSIGN)
4328     {    
4329       sRefSet alias = usymtab_allAliases (tref);
4330
4331       sRefSet_realElements (alias, atref)
4332         {
4333           sRef abase = sRef_getRootBase (atref);
4334
4335           if (sRef_isKnown (atref)
4336               && !sRef_isLocalVar (abase) 
4337               && !sRef_isExternal (abase))
4338             {
4339               atref = sRef_updateSref (atref);
4340
4341               if (sRef_hasName (atref))
4342                 {
4343                   if (!sRef_isNew (atref) 
4344                       && !sRef_sameName (tref, atref))
4345                     {
4346                       context_setAliasAnnote (atref, tref);
4347                     }
4348                   
4349                   checkTransferAux (fexp, fref, TRUE, 
4350                                     texp, atref, FALSE,
4351                                     loc, transferType);
4352                   
4353                   context_clearAliasAnnote ();
4354                 }
4355             }
4356         } end_sRefSet_realElements;
4357
4358       sRefSet_free (alias);
4359     }
4360
4361   if (sRef_isLocalVar (fref))
4362     {    
4363       sRefSet alias = usymtab_allAliases (fref);
4364
4365       sRefSet_realElements (alias, afref)
4366         {
4367           sRef abase = sRef_getRootBase (afref);
4368
4369           if (sRef_isKnown (afref) 
4370               && !sRef_isLocalVar (abase)
4371               && !sRef_isExternal (abase))
4372             {
4373               afref = sRef_updateSref (afref);
4374
4375               if (sRef_hasName (afref))
4376                 {
4377                   if (!sRef_isNew (afref) 
4378                       && !sRef_sameName (afref, fref))
4379                     {
4380                       context_setAliasAnnote (afref, fref);
4381                     }
4382                   
4383                   checkTransferAux (fexp, afref, FALSE,
4384                                     texp, tref, TRUE,
4385                                     loc, transferType);
4386                   
4387                   context_clearAliasAnnote ();
4388                 }
4389             }
4390         } end_sRefSet_realElements;
4391
4392       sRefSet_free (alias);
4393     }
4394   
4395   setCodePoint ();
4396   checkTransferAux (fexp, fref, FALSE, texp, tref, FALSE, 
4397                     loc, transferType);
4398   setCodePoint ();  
4399 }
4400
4401 static /*@exposed@*/ sRef 
4402   dependentReference (sRef sr)
4403 {
4404   sRefSet ab = usymtab_aliasedBy (sr); /* yes, really mean aliasedBy */
4405
4406   DPRINTF (("Dependent reference: %s", sRef_unparse (sr)));
4407   DPRINTF (("Aliases: %s", sRefSet_unparse (ab)));
4408
4409   /*
4410   ** If there is a local variable that aliases sr, then there is no
4411   ** error.  Make the local an only.
4412   */
4413   
4414   if (!sRefSet_isEmpty (ab))
4415     {
4416       sRef res = sRef_undefined;
4417
4418       DPRINTF (("Here we are!"));
4419
4420       /*
4421       ** make one an only, others alias it
4422       */
4423                   
4424       sRefSet_realElements (ab, current)
4425         {
4426           if (sRef_isOwned (current))
4427             {
4428               res = current; 
4429               break;
4430             }
4431         } end_sRefSet_realElements;
4432
4433       if (sRef_isInvalid (res))
4434         {
4435           /* 
4436           ** evans - 2001-03-24
4437           ** No owned element, just choose one! 
4438           ** (Any reason for preference?)
4439           */
4440
4441           res = sRefSet_choose (ab);
4442         }
4443
4444       sRefSet_free (ab);
4445       return res;
4446     }
4447
4448   return sRef_undefined;
4449 }
4450
4451 bool transferChecks_canLoseReference (/*@dependent@*/ sRef sr, fileloc loc)
4452 {
4453   bool gotone = FALSE;
4454   sRefSet ab = usymtab_aliasedBy (sr); /* yes, really mean aliasedBy */
4455     
4456   /*
4457   ** if there is a local variable that aliases sr, then there is no
4458   ** error.  Make the local an only.
4459   */
4460   
4461   if (!sRefSet_isEmpty (ab))
4462     {
4463       /*
4464       ** make one an only, others alias it
4465       */
4466       
4467       sRefSet_realElements (ab, current)
4468         {
4469           sRef_setLastReference (current, sr, loc);
4470           gotone = TRUE;
4471           break;
4472         } end_sRefSet_realElements;
4473
4474       sRefSet_free (ab);
4475     }
4476
4477   return gotone;
4478 }
4479
4480 bool canLoseLocalReference (/*@dependent@*/ sRef sr, fileloc loc)
4481 {
4482   bool gotone = FALSE;
4483   sRefSet ab = usymtab_aliasedBy (sr); /* yes, really mean aliasedBy */
4484     
4485   /*
4486   ** if there is a local variable that aliases sr, then there is no
4487   ** error.  Make the local an only.
4488   */
4489   
4490   if (!sRefSet_isEmpty (ab))
4491     {
4492       /*
4493       ** make one an only, others alias it
4494       */
4495       
4496       sRefSet_realElements (ab, current)
4497         {
4498           if (sRef_isRealLocalVar (sRef_getRootBase (current)))
4499             {
4500               sRef_setLastReference (current, sr, loc);
4501               gotone = TRUE;
4502               break;
4503             }
4504         } end_sRefSet_realElements;
4505
4506       sRefSet_free (ab);
4507     }
4508
4509   return gotone;
4510 }
This page took 0.660015 seconds and 5 git commands to generate.