]> andersk Git - splint.git/blame - src/specialClauses.c
Finshed basic merge. Still trying to get it through the test suit.
[splint.git] / src / specialClauses.c
CommitLineData
885824d3 1/*
2** LCLint - annotation-assisted static program checker
3** Copyright (C) 1994-2000 University of Virginia,
4** Massachusetts Institute of Technology
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** This program is distributed in the hope that it will be useful, but
12** WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14** General Public License for more details.
15**
16** The GNU General Public License is available from http://www.gnu.org/ or
17** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18** MA 02111-1307, USA.
19**
20** For information on lclint: lclint-request@cs.virginia.edu
21** To report a bug: lclint-bug@cs.virginia.edu
22** For more information: http://lclint.cs.virginia.edu
23*/
24/*
25** specialClauses.c
26*/
27
28# include "lclintMacros.nf"
29# include "basic.h"
30
31static bool specialClause_isMemoryAllocation (specialClause p_cl) /*@*/ ;
32static void specialClause_free (/*@only@*/ specialClause p_s) ;
33static cstring specialClause_dump (specialClause p_s) /*@*/ ;
34static specialClause specialClause_undump (char **p_s) /*@modifies *p_s@*/ ;
35static specialClause specialClause_copy (specialClause p_s) /*@*/ ;
36static bool specialClause_sameKind (specialClause p_s1, specialClause p_s2) /*@*/ ;
37
38specialClause
39 specialClause_create (stateConstraint st, specialClauseKind k, sRefSet s)
40{
41 specialClause ret = (specialClause) dmalloc (sizeof (*ret));
42
43 ret->state = st;
44 ret->kind = k;
45 ret->refs = s;
46
47 return ret;
48}
49
50bool specialClause_isBefore (specialClause cl)
51{
52 return (cl->state == TK_BEFORE || cl->state == TK_BOTH);
53}
54
55bool specialClause_isAfter (specialClause cl)
56{
57 return (cl->state == TK_AFTER || cl->state == TK_BOTH);
58}
59
60bool specialClause_isMemoryAllocation (specialClause cl)
61{
62 switch (cl->kind)
63 {
64 case SP_ALLOCATES:
65 case SP_RELEASES:
66 case SP_ISONLY:
67 case SP_ISSHARED:
68 case SP_ISDEPENDENT:
69 case SP_ISOWNED:
70 case SP_ISOBSERVER:
71 case SP_ISEXPOSED:
72 return TRUE;
73 case SP_USES:
74 case SP_DEFINES:
75 case SP_SETS:
76 case SP_ISNULL:
77 case SP_ISNOTNULL:
78 return FALSE;
79 }
80
81 BADEXIT;
82}
83
84/*
85** An error is reported if the test is NOT true.
86*/
87
88sRefTest specialClause_getPreTestFunction (specialClause cl)
89{
90 switch (cl->kind)
91 {
92 case SP_USES:
93 return sRef_isStrictReadable;
94 case SP_ALLOCATES:
95 return sRef_hasNoStorage;
96 case SP_DEFINES:
97 return sRef_hasNoStorage;
98 case SP_SETS:
99 return sRef_isNotUndefined;
100 case SP_RELEASES:
101 return sRef_isNotUndefined;
102 case SP_ISONLY:
103 return sRef_isOnly;
104 case SP_ISSHARED:
105 return sRef_isShared;
106 case SP_ISDEPENDENT:
107 return sRef_isDependent;
108 case SP_ISOWNED:
109 return sRef_isOwned;
110 case SP_ISOBSERVER:
111 return sRef_isObserver;
112 case SP_ISEXPOSED:
113 return sRef_isExposed;
114 case SP_ISNOTNULL:
115 return sRef_isNotNull;
116 case SP_ISNULL:
117 return sRef_isDefinitelyNull;
118 }
119
120 BADEXIT;
121}
122
123sRefTest specialClause_getPostTestFunction (specialClause cl)
124{
a0a162cd 125 llassert (specialClause_isAfter (cl));
126
885824d3 127 switch (cl->kind)
128 {
129 case SP_USES:
130 return NULL;
131 case SP_ALLOCATES:
132 return sRef_isAllocated;
133 case SP_DEFINES:
134 return sRef_isReallyDefined;
135 case SP_SETS:
136 return sRef_isReallyDefined;
137 case SP_RELEASES:
138 return sRef_isDeadStorage;
139 case SP_ISONLY:
140 return sRef_isOnly;
141 case SP_ISSHARED:
142 return sRef_isShared;
143 case SP_ISDEPENDENT:
144 return sRef_isDependent;
145 case SP_ISOWNED:
146 return sRef_isOwned;
147 case SP_ISOBSERVER:
148 return sRef_isObserver;
149 case SP_ISEXPOSED:
150 return sRef_isExposed;
151 case SP_ISNOTNULL:
152 return sRef_isNotNull;
153 case SP_ISNULL:
154 return sRef_isDefinitelyNull;
155 }
156
157 BADEXIT;
158}
159
160sRefShower specialClause_getPostTestShower (specialClause cl)
161{
162 switch (cl->kind)
163 {
164 case SP_USES:
165 case SP_ALLOCATES:
166 return NULL;
167 case SP_DEFINES:
168 case SP_SETS:
169 return sRef_showNotReallyDefined;
170 case SP_RELEASES:
171 return NULL;
172 case SP_ISONLY:
173 case SP_ISSHARED:
174 case SP_ISDEPENDENT:
175 case SP_ISOWNED:
176 return sRef_showAliasInfo;
177 case SP_ISOBSERVER:
178 case SP_ISEXPOSED:
179 return sRef_showExpInfo;
180 case SP_ISNOTNULL:
181 case SP_ISNULL:
182 return sRef_showNullInfo;
183 }
184
185 BADEXIT;
186}
187
188sRefMod specialClause_getEntryFunction (specialClause cl)
189{
190 if (cl->state == TK_BEFORE || cl->state == TK_BOTH)
191 {
192 switch (cl->kind)
193 {
194 case SP_USES:
195 return sRef_setDefinedComplete;
196 case SP_ALLOCATES:
197 return NULL;
198 case SP_DEFINES:
199 return NULL;
200 case SP_SETS:
201 return sRef_setAllocatedComplete;
202 case SP_RELEASES:
203 return sRef_setDefinedComplete;
204 case SP_ISONLY:
205 return sRef_setOnly;
206 case SP_ISSHARED:
207 return sRef_setShared;
208 case SP_ISDEPENDENT:
209 return sRef_setDependent;
210 case SP_ISOWNED:
211 return sRef_setOwned;
212 case SP_ISOBSERVER:
213 return sRef_setObserver;
214 case SP_ISEXPOSED:
215 return sRef_setExposed;
216 case SP_ISNOTNULL:
217 return sRef_setNotNull;
218 case SP_ISNULL:
219 return sRef_setDefNull;
220 }
221
222 BADBRANCH;
223 }
224 else
225 {
226 return NULL;
227 }
228}
229
230sRefMod specialClause_getEffectFunction (specialClause cl)
231{
232 if (cl->state == TK_AFTER || cl->state == TK_BOTH)
233 {
234 switch (cl->kind)
235 {
236 case SP_USES:
237 return NULL;
238 case SP_ALLOCATES:
239 return sRef_setAllocatedComplete;
240 case SP_DEFINES:
241 return sRef_setDefinedNCComplete;
242 case SP_SETS:
243 return sRef_setDefinedNCComplete;
244 case SP_RELEASES:
245 return sRef_killComplete;
246 case SP_ISONLY:
247 return sRef_setOnly;
248 case SP_ISSHARED:
249 return sRef_setShared;
250 case SP_ISDEPENDENT:
251 return sRef_setDependent;
252 case SP_ISOWNED:
253 return sRef_setOwned;
254 case SP_ISOBSERVER:
255 return sRef_setObserver;
256 case SP_ISEXPOSED:
257 return sRef_setExposed;
258 case SP_ISNOTNULL:
259 return sRef_setNotNull;
260 case SP_ISNULL:
261 return sRef_setDefNull;
262 }
263
264 BADBRANCH;
265 }
266 else
267 {
268 return NULL;
269 }
270}
271
272sRefMod specialClause_getReturnEffectFunction (specialClause cl)
273{
274 if (cl->state == TK_AFTER || cl->state == TK_BOTH)
275 {
276 switch (cl->kind)
277 {
278 case SP_USES:
279 case SP_ALLOCATES:
280 case SP_DEFINES:
281 case SP_SETS:
282 case SP_RELEASES:
283 return NULL;
284 case SP_ISONLY:
285 return sRef_killComplete;
286 case SP_ISSHARED:
287 case SP_ISDEPENDENT:
288 case SP_ISOWNED:
289 case SP_ISOBSERVER:
290 case SP_ISEXPOSED:
291 case SP_ISNULL:
292 case SP_ISNOTNULL:
293 return NULL;
294 }
295
296 BADBRANCH;
297 }
298 else
299 {
300 return NULL;
301 }
302}
303
304flagcode specialClause_preErrorCode (specialClause cl)
305{
306 llassert (cl->state == TK_BOTH || cl->state == TK_BEFORE);
307
308 switch (cl->kind)
309 {
310 case SP_USES:
311 return FLG_USEDEF;
312 case SP_ALLOCATES: /*@fallthrough@*/
313 case SP_DEFINES:
314 case SP_SETS:
315 return FLG_MUSTFREE;
316 case SP_RELEASES:
317 return FLG_USEDEF;
318 case SP_ISONLY:
319 return FLG_ONLYTRANS;
320 case SP_ISSHARED:
321 return FLG_SHAREDTRANS;
322 case SP_ISDEPENDENT:
323 return FLG_DEPENDENTTRANS;
324 case SP_ISOWNED:
325 return FLG_OWNEDTRANS;
326 case SP_ISOBSERVER:
327 return FLG_OBSERVERTRANS;
328 case SP_ISEXPOSED:
329 return FLG_EXPOSETRANS;
330 case SP_ISNULL:
331 case SP_ISNOTNULL:
332 return FLG_NULLSTATE;
333 }
334
335 BADBRANCH;
336}
337
338cstring specialClause_preErrorString (specialClause cl, sRef sr)
339{
340 llassert (cl->state == TK_BOTH || cl->state == TK_BEFORE);
341
342 switch (cl->kind)
343 {
344 case SP_USES:
345 if (sRef_isDead (sr))
346 return cstring_makeLiteralTemp ("Dead");
347 else
348 return cstring_makeLiteralTemp ("Undefined");
349 case SP_ALLOCATES: /*@fallthrough@*/
350 case SP_DEFINES:
351 case SP_SETS:
352 return cstring_makeLiteralTemp ("Allocated");
353 case SP_RELEASES:
354 if (sRef_isDead (sr))
355 {
356 return cstring_makeLiteralTemp ("Dead");
357 }
358 else if (sRef_isDependent (sr)
359 || sRef_isShared (sr))
360 {
361 return alkind_unparse (sRef_getAliasKind (sr));
362 }
363 else if (sRef_isObserver (sr) || sRef_isExposed (sr))
364 {
365 return exkind_unparse (sRef_getExKind (sr));
366 }
367 else
368 {
369 return cstring_makeLiteralTemp ("Undefined");
370 }
371 case SP_ISONLY:
372 case SP_ISSHARED:
373 case SP_ISDEPENDENT:
374 case SP_ISOWNED:
375 return alkind_capName (sRef_getAliasKind (sr));
376 case SP_ISOBSERVER:
377 return cstring_makeLiteralTemp ("Non-observer");
378 case SP_ISEXPOSED:
379 if (sRef_isObserver (sr))
380 {
381 return cstring_makeLiteralTemp ("Observer");
382 }
383 else
384 {
385 return cstring_makeLiteralTemp ("Non-exposed");
386 }
387 case SP_ISNOTNULL:
388 if (sRef_isDefinitelyNull (sr))
389 {
390 return cstring_makeLiteralTemp ("Null");
391 }
392 else
393 {
394 return cstring_makeLiteralTemp ("Possibly null");
395 }
396 case SP_ISNULL:
397 return cstring_makeLiteralTemp ("Non-null");
398 }
399
400 BADEXIT;
401}
402
403flagcode specialClause_postErrorCode (specialClause cl)
404{
405 llassert (cl->state == TK_BOTH || cl->state == TK_AFTER);
406
407 switch (cl->kind)
408 {
409 case SP_USES:
410 BADBRANCHCONT;
411 return INVALID_FLAG;
412 case SP_ALLOCATES:
413 case SP_DEFINES:
414 case SP_SETS:
415 return FLG_COMPDEF;
416 case SP_RELEASES:
417 return FLG_MUSTFREE;
418 case SP_ISONLY:
419 return FLG_ONLYTRANS;
420 case SP_ISSHARED:
421 return FLG_SHAREDTRANS;
422 case SP_ISDEPENDENT:
423 return FLG_DEPENDENTTRANS;
424 case SP_ISOWNED:
425 return FLG_OWNEDTRANS;
426 case SP_ISOBSERVER:
427 return FLG_OBSERVERTRANS;
428 case SP_ISEXPOSED:
429 return FLG_EXPOSETRANS;
430 case SP_ISNULL:
431 case SP_ISNOTNULL:
432 return FLG_NULLSTATE;
433 }
434
435 BADBRANCH;
436}
437
438cstring specialClause_postErrorString (specialClause cl, sRef sr)
439{
440 llassert (cl->state == TK_BOTH || cl->state == TK_AFTER);
441
442 switch (cl->kind)
443 {
444 case SP_USES:
445 BADBRANCHCONT;
446 return cstring_makeLiteralTemp ("<ERROR>");
447 case SP_ALLOCATES:
448 return cstring_makeLiteralTemp ("Unallocated");
449 case SP_DEFINES:
450 case SP_SETS:
451 return cstring_makeLiteralTemp ("Undefined");
452 case SP_RELEASES:
453 return cstring_makeLiteralTemp ("Unreleased");
454 case SP_ISONLY:
455 case SP_ISSHARED:
456 case SP_ISOWNED:
457 case SP_ISDEPENDENT:
458 return alkind_capName (sRef_getAliasKind (sr));
459 case SP_ISOBSERVER:
460 return cstring_makeLiteralTemp ("Non-observer");
461 case SP_ISEXPOSED:
462 if (sRef_isObserver (sr))
463 {
464 return cstring_makeLiteralTemp ("Observer");
465 }
466 else
467 {
468 return cstring_makeLiteralTemp ("Non-exposed");
469 }
470 case SP_ISNULL:
471 return cstring_makeLiteralTemp ("Non-null");
472 case SP_ISNOTNULL:
473 if (sRef_isDefinitelyNull (sr))
474 {
475 return cstring_makeLiteralTemp ("Null");
476 }
477 else
478 {
479 return cstring_makeLiteralTemp ("Possibly null");
480 }
481 }
482
483 BADEXIT;
484}
485
486cstring specialClause_dump (specialClause s)
487{
488 return (message ("%d.%d.%q",
489 (int) s->state,
490 (int) s->kind,
491 sRefSet_dump (s->refs)));
492}
493
494specialClause specialClause_undump (char **s)
495{
496 specialClause ret = (specialClause) dmalloc (sizeof (*ret));
497
498 ret->state = (stateConstraint) getInt (s);
499 checkChar (s, '.');
500 ret->kind = (specialClauseKind) getInt (s);
501 checkChar (s, '.');
502 ret->refs = sRefSet_undump (s);
503
504 return ret;
505}
506
507specialClause specialClause_copy (specialClause s)
508{
509 specialClause ret = (specialClause) dmalloc (sizeof (*ret));
510
511 ret->state = s->state;
512 ret->kind = s->kind;
513 ret->refs = sRefSet_newCopy (s->refs);
514
515 return ret;
516}
517
518bool specialClause_sameKind (specialClause s1, specialClause s2)
519{
520 return (s1->state == s2->state && s1->kind == s2->kind);
521}
522
523void specialClause_free (specialClause s)
524{
525 sRefSet_free (s->refs);
526 sfree (s);
527}
528
529static /*@observer@*/ cstring
530 specialClauseKind_unparse (specialClauseKind k)
531{
532 switch (k)
533 {
534 case SP_USES:
535 return cstring_makeLiteralTemp ("uses");
536 case SP_DEFINES:
537 return cstring_makeLiteralTemp ("defines");
538 case SP_ALLOCATES:
539 return cstring_makeLiteralTemp ("allocates");
540 case SP_RELEASES:
541 return cstring_makeLiteralTemp ("releases");
542 case SP_SETS:
543 return cstring_makeLiteralTemp ("sets");
544 case SP_ISNULL:
545 return cstring_makeLiteralTemp ("isnull");
546 case SP_ISNOTNULL:
547 return cstring_makeLiteralTemp ("notnull");
548 case SP_ISONLY:
549 return cstring_makeLiteralTemp ("only");
550 case SP_ISSHARED:
551 return cstring_makeLiteralTemp ("shared");
552 case SP_ISDEPENDENT:
553 return cstring_makeLiteralTemp ("dependent");
554 case SP_ISOWNED:
555 return cstring_makeLiteralTemp ("owned");
556 case SP_ISOBSERVER:
557 return cstring_makeLiteralTemp ("observer");
558 case SP_ISEXPOSED:
559 return cstring_makeLiteralTemp ("exposed");
560 }
561
562 BADEXIT;
563}
564
565cstring specialClause_unparseKind (specialClause s)
566{
567 return (message ("%s%s",
568 cstring_makeLiteralTemp (s->state == TK_BEFORE
569 ? "pre:"
570 : (s->state == TK_AFTER
571 ? "post:" : "")),
572 specialClauseKind_unparse (s->kind)));
573}
574
575cstring specialClause_unparse (specialClause s)
576{
577 return (message ("%q %q",
578 specialClause_unparseKind (s), sRefSet_unparse (s->refs)));
579}
580
581specialClause specialClause_createDefines (sRefSet s)
582{
583 return (specialClause_create (TK_BOTH, SP_DEFINES, s));
584}
585
586specialClause specialClause_createUses (sRefSet s)
587{
588 return (specialClause_create (TK_BOTH, SP_USES, s));
589}
590
591specialClause specialClause_createSets (sRefSet s)
592{
593 return (specialClause_create (TK_BOTH, SP_SETS, s));
594}
595
596specialClause specialClause_createReleases (sRefSet s)
597{
598 return (specialClause_create (TK_BOTH, SP_RELEASES, s));
599}
600
601specialClause specialClause_createAllocates (sRefSet s)
602{
603 return (specialClause_create (TK_BOTH, SP_ALLOCATES, s));
604}
605
606static /*@notnull@*/ specialClauses specialClauses_new (void)
607{
608 specialClauses s = (specialClauses) dmalloc (sizeof (*s));
609
610 s->nelements = 0;
611 s->nspace = specialClausesBASESIZE;
612 s->elements = (specialClause *)
613 dmalloc (sizeof (*s->elements) * specialClausesBASESIZE);
614
615 return (s);
616}
617
618static void
619specialClauses_grow (specialClauses s)
620{
621 int i;
622 specialClause *newelements;
623
624 llassert (specialClauses_isDefined (s));
625
626 s->nspace += specialClausesBASESIZE;
627
628 newelements = (specialClause *)
629 dmalloc (sizeof (*newelements) * (s->nelements + s->nspace));
630
631 for (i = 0; i < s->nelements; i++)
632 {
633 newelements[i] = s->elements[i];
634 }
635
636 sfree (s->elements);
637 s->elements = newelements;
638}
639
640specialClauses specialClauses_add (specialClauses s, specialClause el)
641{
642 if (specialClauses_isUndefined (s))
643 {
644 s = specialClauses_new ();
645 }
646 else
647 {
648 specialClauses_elements (s, cl)
649 {
650 if (specialClause_sameKind (cl, el))
651 {
652 voptgenerror
653 (FLG_SYNTAX,
654 message ("Multiple %q clauses for one function (using union)",
655 specialClause_unparseKind (cl)),
656 g_currentloc);
657
658 cl->refs = sRefSet_union (cl->refs, el->refs);
659 specialClause_free (el);
660 return s;
661 }
662 } end_specialClauses_elements ;
663 }
664
665 if (s->nspace <= 0)
666 {
667 specialClauses_grow (s);
668 }
669
670 s->nspace--;
671 s->elements[s->nelements] = el;
672 s->nelements++;
673
674 return s;
675}
676
677cstring specialClauses_unparse (specialClauses s)
678{
679 cstring st = cstring_undefined;
680 int i;
681
682 if (specialClauses_isDefined (s))
683 {
684 for (i = 0; i < specialClauses_size (s); i++)
685 {
686 if (i == 0)
687 {
688 st = message ("%q;", specialClause_unparse (s->elements[i]));
689 }
690 else
691 st = message ("%q %q;", st, specialClause_unparse (s->elements[i]));
692 }
693 }
694
695 return (st);
696}
697
698specialClauses specialClauses_copy (specialClauses s)
699{
700 if (specialClauses_isDefined (s))
701 {
702 specialClauses t = (specialClauses) dmalloc (sizeof (*t));
703 int i;
704
705 t->nelements = s->nelements;
706 t->nspace = 0;
707
708 if (s->nelements > 0)
709 {
710 t->elements = (specialClause *) dmalloc (sizeof (*t->elements) * t->nelements);
711 for (i = 0; i < s->nelements; i++)
712 {
713 t->elements[i] = specialClause_copy (s->elements[i]);
714 }
715 }
716 else
717 {
718 t->elements = NULL;
719 }
720
721 return t;
722 }
723 else
724 {
725 return specialClauses_undefined;
726 }
727}
728
729void
730specialClauses_free (specialClauses s)
731{
732 if (!specialClauses_isUndefined (s))
733 {
734 int i;
735
736 for (i = 0; i < s->nelements; i++)
737 {
738 specialClause_free (s->elements[i]);
739 }
740
741 sfree (s->elements);
742 sfree (s);
743 }
744}
745
746cstring specialClauses_dump (specialClauses s)
747{
748 cstring st = cstring_undefined;
749
750 if (specialClauses_isUndefined (s)) return st;
751
752 specialClauses_elements (s, current)
753 {
754 st = message ("%q%q$", st, specialClause_dump (current));
755 } end_specialClauses_elements;
756
757 return st;
758}
759
760specialClauses specialClauses_undump (char **s)
761{
762 char c;
763 specialClauses pn = specialClauses_new ();
764 int paramno = 0;
765
766 c = **s;
767
768 while (c != '#' && c != '@')
769 {
770 specialClause sc = specialClause_undump (s);
771
772 pn = specialClauses_add (pn, sc);
773 checkChar (s, '$');
774 c = **s;
775 paramno++;
776 }
777
778 return pn;
779}
780
781static /*@exposed@*/ sRefSet
782 specialClauses_getClause (specialClauses s, stateConstraint st,
783 specialClauseKind k)
784{
785 specialClauses_elements (s, el)
786 {
787 if (el->state == st && el->kind == k)
788 {
789 return el->refs;
790 }
791 } end_specialClauses_elements ;
792
793 return sRefSet_undefined;
794}
795
796void specialClauses_checkAll (uentry ue)
797{
798 specialClauses clauses = uentry_getSpecialClauses (ue);
799 sRef res = uentry_getSref (ue);
800 bool specialResult = FALSE;
801
802 specialClauses_elements (clauses, cl)
803 {
804 bool isPre = (cl->state == TK_BEFORE);
805 sRefSet refs = cl->refs;
806
807 sRefSet_allElements (refs, el)
808 {
809 sRef rb = sRef_getRootBase (el);
810
811 if (sRef_isResult (rb))
812 {
813 if (isPre)
814 {
815 voptgenerror
816 (FLG_INCONDEFS,
817 message ("Function result is used in %q clause of %q "
818 "(%q applies to the state before function is "
819 "called, so should not use result): %q",
820 specialClause_unparseKind (cl),
821 uentry_getName (ue),
822 specialClause_unparseKind (cl),
823 sRef_unparse (el)),
824 uentry_whereLast (ue));
825 }
826 else
827 {
828 if (!sRef_isStateSpecial (res))
829 {
830 if (!specialResult)
831 {
832 voptgenerror
833 (FLG_INCONDEFS,
834 message ("Function result is used in %q clause of %q "
835 "but not annotated with special: %q",
836 specialClause_unparseKind (cl),
837 uentry_getName (ue),
838 sRef_unparse (el)),
839 uentry_whereLast (ue));
840
841 specialResult = TRUE;
842 }
843 }
844
845 (void) sRef_fixResultType (el, sRef_getType (res), ue);
846 }
847 }
848 else if (sRef_isParam (rb))
849 {
850 if (!sRef_isStateSpecial (rb))
851 {
852 voptgenerror
853 (FLG_INCONDEFS,
854 message ("Reference %q used in %q clause of %q, "
855 "but not annotated with special: %q",
856 sRef_unparse (rb),
857 specialClause_unparseKind (cl),
858 uentry_getName (ue),
859 sRef_unparse (el)),
860 uentry_whereLast (ue));
861 }
862 }
863 else if (sRef_isInvalid (rb))
864 {
865 /*@innercontinue@*/ continue;
866 }
867 else
868 {
869 BADBRANCHCONT;
870 /*@innercontinue@*/ continue;
871 }
872
873 if (specialClause_isMemoryAllocation (cl))
874 {
875 if (!ctype_isVisiblySharable (sRef_getType (el)))
876 {
877 llerror
878 (FLG_SYNTAX,
879 message ("Special clause %q includes %q of "
880 "non-dynamically allocatated type %s",
881 specialClause_unparseKind (cl),
882 sRef_unparse (el),
883 ctype_unparse (sRef_getType (el))));
884 }
885 }
886
887 } end_sRefSet_allElements ;
888 } end_specialClauses_elements ;
889}
890
891void specialClauses_checkEqual (uentry old, uentry unew)
892{
893 specialClauses oldClauses = uentry_getSpecialClauses (old);
894 specialClauses newClauses = uentry_getSpecialClauses (unew);
895
896 if (specialClauses_isDefined (newClauses))
897 {
898 specialClauses_elements (newClauses, cl)
899 {
900 sRefSet sc = specialClauses_getClause (oldClauses, cl->state, cl->kind);
901
902 if (!sRefSet_equal (sc, cl->refs))
903 {
904 if (optgenerror
905 (FLG_INCONDEFS,
906 message ("Function %q %rdeclared with inconsistent %q clause: %q",
907 uentry_getName (old),
908 uentry_isDeclared (old),
909 specialClause_unparseKind (cl),
910 sRefSet_unparsePlain (cl->refs)),
911 g_currentloc))
912 {
913 uentry_showWhereLastExtra (old, sRefSet_unparsePlain (sc));
914 }
915 }
916 } end_specialClauses_elements ;
917
918 specialClauses_elements (oldClauses, cl)
919 {
920 sRefSet sc = specialClauses_getClause (newClauses, cl->state, cl->kind);
921
922 if (sRefSet_isUndefined (sc) && !sRefSet_isEmpty (cl->refs))
923 {
924 if (optgenerror
925 (FLG_INCONDEFS,
926 message ("Function %q %rdeclared without %q clause (either "
927 "use no special clauses in redeclaration, or "
928 "they must match exactly: %q",
929 uentry_getName (old),
930 uentry_isDeclared (old),
931 specialClause_unparseKind (cl),
932 sRefSet_unparsePlain (cl->refs)),
933 g_currentloc))
934 {
935 uentry_showWhereLastExtra (old, sRefSet_unparsePlain (sc));
936 }
937 }
938 } end_specialClauses_elements ;
939
940 }
941}
942
943
944
This page took 0.332583 seconds and 5 git commands to generate.