]> andersk Git - splint.git/blob - src/constraintResolve.c
Convert some llassert() to llassertfatal(), as we should not continue with null pointers.
[splint.git] / src / constraintResolve.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 /*
26 *
27 ** constraintResolve.c
28 */
29
30 /* #define DEBUGPRINT 1 */
31
32 # include <ctype.h> /* for isdigit */
33 # include "splintMacros.nf"
34 # include "basic.h"
35 # include "cgrammar.h"
36 # include "cgrammar_tokens.h"
37
38 # include "exprChecks.h"
39 # include "exprNodeSList.h"
40
41 /*@access constraint, exprNode @*/ /*!!! NO! Don't do this so recklessly - design your code more carefully so you don't need to! */
42
43 static constraint inequalitySubstitute (/*@returned@*/ constraint p_c, constraintList p_p);
44 static bool rangeCheck (arithType p_ar1, /*@observer@*/ constraintExpr p_expr1, arithType p_ar2, /*@observer@*/ constraintExpr p_expr2);
45
46 static constraint inequalitySubstituteUnsound (/*@returned@*/ constraint p_c, constraintList p_p);
47 static constraint inequalitySubstituteStrong (/*@returned@*/ constraint p_c, constraintList p_p);
48
49 static constraint constraint_searchandreplace (/*@returned@*/ constraint p_c, constraintExpr p_old, constraintExpr p_newExpr);
50
51 static constraint constraint_addOr (/*@returned@*/ constraint p_orig, /*@observer@*/ constraint p_orConstr);
52
53 static bool resolveOr (/*@temp@*/constraint p_c, /*@observer@*/ /*@temp@*/ constraintList p_list);
54
55 static /*@only@*/ constraintList reflectChangesEnsuresFree1 (/*@only@*/ constraintList p_pre2, constraintList p_post1);
56
57
58 /*@only@*/ constraintList constraintList_mergeEnsuresFreeFirst (constraintList list1, constraintList list2)
59 {
60   constraintList ret;
61
62   ret = constraintList_mergeEnsures (list1, list2);
63
64   constraintList_free(list1);
65   return ret;
66 }
67                                             
68 /*@only@*/ constraintList constraintList_mergeEnsures (constraintList list1, constraintList list2)
69 {
70   constraintList ret;
71   constraintList temp;
72
73   llassert(constraintList_isDefined(list1) );
74   llassert(constraintList_isDefined(list2) );
75
76   DPRINTF(( message ("constraintList_mergeEnsures: list1 %s list2 %s",
77                      constraintList_unparse(list1), constraintList_unparse(list2)
78                      )));
79   
80   ret = constraintList_fixConflicts (list1, list2);
81   ret = reflectChangesEnsuresFree1 (ret, list2);
82   temp = constraintList_subsumeEnsures (ret, list2);
83   constraintList_free(ret);
84   ret = temp;
85
86   temp = constraintList_subsumeEnsures (list2, ret);
87
88   temp = constraintList_addList (temp, ret);
89   constraintList_free(ret);
90   
91   DPRINTF(( message ("constraintList_mergeEnsures: returning %s ",
92                      constraintList_unparse(temp) )
93                      ));
94   
95
96   return temp;
97 }
98
99
100 /*@only@*/ constraintList constraintList_mergeRequiresFreeFirst (/*@only@*/ constraintList list1, constraintList list2)
101 {
102   constraintList ret;
103
104   ret = constraintList_mergeRequires(list1, list2);
105
106   constraintList_free(list1);
107
108   return ret;
109 }
110
111 /*@only@*/ constraintList constraintList_mergeRequires (constraintList list1, constraintList list2)
112 {
113   constraintList ret;
114   constraintList temp;
115
116   DPRINTF((message ("constraintList_mergeRequires: merging  %s and %s ", constraintList_unparse (list1), constraintList_unparse(list2) ) ) );
117
118   if (context_getFlag (FLG_REDUNDANTCONSTRAINTS) )
119     {
120       ret = constraintList_copy(list1);
121       ret = constraintList_addList(ret, list2); 
122       return ret;
123     }
124     
125   /* get constraints in list1 not satified by list2 */
126   temp = constraintList_reflectChanges(list1, list2);
127   DPRINTF((message ("constraintList_mergeRequires: temp = %s", constraintList_unparse(temp) ) ) );
128
129 /*get constraints in list2 not satified by temp*/
130   ret = constraintList_reflectChanges(list2, temp);
131  
132   DPRINTF((message ("constraintList_mergeRequires: ret =  %s", constraintList_unparse(ret) ) ) );
133   
134   ret = constraintList_addListFree (ret, temp);
135   
136   DPRINTF((message ("constraintList_mergeRequires: returning  %s", constraintList_unparse(ret) ) ) );
137
138   return ret;
139 }
140
141 /* old name mergeResolve renamed for czech naming convention */
142 void exprNode_mergeResolve (exprNode parent, exprNode child1, exprNode child2)
143 {
144   constraintList temp, temp2;
145
146   DPRINTF((message ("magically merging constraint into parent:%s for", exprNode_unparse (parent) )) );
147
148   DPRINTF((message (" children:  %s and %s", exprNode_unparse (child1), exprNode_unparse(child2) ) ) );
149
150   
151   if (exprNode_isUndefined(parent) )
152     {
153       llassert (exprNode_isDefined(parent) );
154       return;
155     }
156   
157   
158   if (exprNode_isError (child1)  || exprNode_isError(child2) )
159     {
160       if (exprNode_isError (child1) && !exprNode_isError(child2) )
161          {
162            constraintList_free(parent->requiresConstraints);
163
164            parent->requiresConstraints = constraintList_copy (child2->requiresConstraints);
165            constraintList_free(parent->ensuresConstraints);
166
167            parent->ensuresConstraints = constraintList_copy (child2->ensuresConstraints);
168            DPRINTF((message ("Copied child constraints: pre: %s and post: %s",
169                              constraintList_unparse( child2->requiresConstraints),
170                              constraintList_unparse (child2->ensuresConstraints)
171                              )
172                     ));
173            return;
174          }
175        else
176          {
177            llassert(exprNode_isError(child2) );
178            return;
179          }
180      }
181
182    llassert(!exprNode_isError (child1)  && ! exprNode_isError(child2) );
183    
184    DPRINTF((message ("Child constraints are %s %s and %s %s",
185                      constraintList_unparse (child1->requiresConstraints),
186                      constraintList_unparse (child1->ensuresConstraints),
187                      constraintList_unparse (child2->requiresConstraints),
188                      constraintList_unparse (child2->ensuresConstraints)
189                      ) ) );
190  
191  
192    constraintList_free(parent->requiresConstraints);
193
194   parent->requiresConstraints = constraintList_copy (child1->requiresConstraints);
195
196   if ( context_getFlag (FLG_ORCONSTRAINT) )
197     temp = constraintList_reflectChangesOr (child2->requiresConstraints, child1->ensuresConstraints);
198   else
199     temp = constraintList_reflectChanges(child2->requiresConstraints, child1->ensuresConstraints);
200
201   temp2 = constraintList_mergeRequires (parent->requiresConstraints, temp);
202   constraintList_free(parent->requiresConstraints);
203   constraintList_free(temp);
204   
205   parent->requiresConstraints = temp2;
206
207   DPRINTF((message ("Parent requires constraints are %s  ",
208                      constraintList_unparse (parent->requiresConstraints)
209                      ) ) );
210
211    constraintList_free(parent->ensuresConstraints);
212
213   parent->ensuresConstraints = constraintList_mergeEnsures(child1->ensuresConstraints,
214                                                            child2->ensuresConstraints);
215
216   
217   DPRINTF((message ("Parent constraints are %s and %s ",
218                      constraintList_unparse (parent->requiresConstraints),
219                      constraintList_unparse (parent->ensuresConstraints)
220                      ) ) );
221  
222 }
223   
224 /*@only@*/ constraintList constraintList_subsumeEnsures (constraintList list1, constraintList list2)
225 {
226   constraintList ret;
227   ret = constraintList_makeNew();
228   constraintList_elements (list1, el)
229     {
230       
231       DPRINTF ((message ("Examining %s", constraint_unparse (el) ) ) );
232       if (!constraintList_resolve (el, list2) )
233         {
234           constraint temp;
235           temp = constraint_copy(el);
236           ret = constraintList_add (ret, temp);
237         }
238       else
239         {
240           DPRINTF ((message ("Subsuming %s", constraint_unparse (el) ) ) );
241         }
242     } end_constraintList_elements;
243
244     return ret;
245 }
246
247
248
249 /*used to be reflectChangesFreePre  renamed for Czech naming conventino*/
250 /* tries to resolve constraints in list pre2 using post1 */
251 /*@only@*/ constraintList constraintList_reflectChangesFreePre (/*@only@*/ constraintList pre2, /*@observer@*/ constraintList post1)
252 {
253   constraintList ret;
254   
255   ret = constraintList_reflectChanges(pre2, post1);
256
257   constraintList_free (pre2);
258   
259   return ret;
260 }
261
262 /* tries to resolve constraints in list pre2 using post1 */
263
264 static /*@only@*/ constraintList reflectChangesNoOr (/*@observer@*/ /*@temp@*/ constraintList pre2, /*@observer@*/ /*@temp@*/ constraintList post1)
265 {
266   
267   constraintList ret;
268   constraint temp;
269   constraint temp2;
270
271   llassert  (! context_getFlag (FLG_ORCONSTRAINT) );
272
273   ret = constraintList_makeNew();
274   DPRINTF((message ("reflectChanges: lists %s and %s", constraintList_unparse(pre2), constraintList_unparse(post1) )));
275   
276   constraintList_elements (pre2, el)
277     {
278       if (!constraintList_resolve (el, post1) )
279         {
280           temp = constraint_substitute (el, post1);
281           if (!constraintList_resolve (temp, post1) )
282             {
283               /* try inequality substitution
284                  the inequality substitution may cause us to lose information
285                  so we don't want to store the result but we do it anyway
286               */
287               temp2 = constraint_copy (temp);
288               temp2 = inequalitySubstitute (temp2, post1); 
289               if (!constraintList_resolve (temp2, post1) )
290                 {
291                   temp2 = inequalitySubstituteUnsound (temp2, post1); 
292                   if (!constraintList_resolve (temp2, post1) )
293                     ret = constraintList_add (ret, temp2);
294                   else
295                     constraint_free(temp2);
296                 }
297               else
298                 {
299                   constraint_free(temp2);
300                 }
301             }
302           constraint_free(temp);
303         }
304     } end_constraintList_elements;
305
306     DPRINTF((message ("reflectChanges: returning %s", constraintList_unparse(ret) ) ) );
307     return ret;
308 }
309
310 /* tries to resolve constraints in list pre2 using post1 */
311 /*@only@*/ constraintList constraintList_reflectChanges(/*@observer@*/ constraintList pre2, /*@observer@*/ constraintList post1)
312 {
313   constraintList temp;
314   
315   if ( context_getFlag (FLG_ORCONSTRAINT) )
316     
317     temp = constraintList_reflectChangesOr (pre2, post1);
318   else
319     temp = reflectChangesNoOr(pre2, post1);
320
321   return temp;                           
322 }
323
324 static constraint constraint_addOr (/*@returned@*/ constraint orig, /*@observer@*/ constraint orConstr)
325 {
326   constraint c;
327
328   llassertfatal(constraint_isDefined(orig) );
329   
330   c = orig;
331
332   DPRINTF((message("constraint_addor: oring %s onto %s", constraint_unparseOr(orConstr), constraint_unparseOr(orig) ) ));
333   
334   while (c->or != NULL)
335     {
336       c = c->or;
337     }
338   
339   c->or = constraint_copy(orConstr);
340
341   DPRINTF((message("constraint_addor: returning %s",constraint_unparseOr(orig) ) ));
342   
343   return orig;
344 }
345
346
347 static bool resolveOr ( /*@temp@*/ constraint c, /*@observer@*/ /*@temp@*/ constraintList list)
348 {
349   constraint temp;
350
351   int numberOr;
352
353   numberOr = 0;
354
355     llassertfatal(constraint_isDefined(c) );
356
357   DPRINTF(( message("resolveOr: constraint %s and list %s", constraint_unparseOr(c), constraintList_unparse(list) ) ));
358   
359   temp = c;
360
361   do
362     {
363       if (constraintList_resolve (temp, list) )
364         return TRUE;
365       temp = temp->or;
366       numberOr++;
367       llassert(numberOr <= 10);
368     }
369   while (constraint_isDefined(temp));
370
371   return FALSE;
372 }
373
374 /*This is a "helper" function for doResolveOr */
375
376 static /*@only@*/ constraint doResolve (/*@only@*/ constraint c, constraintList post1, bool * resolved)
377 {
378   constraint temp;
379
380   llassert(constraint_isDefined (c ) );
381
382   DPRINTF((message("doResolve:: call on constraint c = : %q and constraintList %q",
383                    constraint_unparseOr(c), constraintList_unparse(post1)
384                    )
385            ));
386   
387   if (!resolveOr (c, post1) )
388     {
389       
390       temp = constraint_substitute (c, post1);
391       
392       DPRINTF((message("doResolve:: after substitute temp is %q",
393                    constraint_unparseOr(temp)
394                        )
395                ));
396   
397       if (!resolveOr (temp, post1) )
398         {
399           /* try inequality substitution */
400           constraint temp2;
401           
402           /* the inequality substitution may cause us to lose information
403              so we don't want to store the result but we do  anyway
404           */
405           temp2 = constraint_copy (c);
406           temp2 = inequalitySubstitute (temp2, post1);
407
408           if (!resolveOr (temp2, post1) )
409             {
410               constraint temp3;
411               temp3 = constraint_copy(temp2);
412               
413               temp3 = inequalitySubstituteStrong (temp3, post1);
414               if (!resolveOr (temp3, post1) )
415                 {
416                   temp2 = inequalitySubstituteUnsound (temp2, post1); 
417                   if (!resolveOr (temp2, post1) )
418                     {
419                       if (!constraint_same (temp, temp2) )
420                         {
421                           /* drl added 8/28/2002*/
422                           /*make sure that the information from
423                             a post condition like i = i + 1 is transfered
424                           */
425                           constraint tempSub;
426                           tempSub = constraint_substitute (temp2, post1);
427
428                           DPRINTF((
429                                    message("doResolve: adding %s ",
430                                            constraint_unparseOr(tempSub)
431                                            )
432                                    ));
433                           
434                           DPRINTF((
435                                    message("doResolve: not adding %s ",
436                                            constraint_unparseOr(temp2)
437                                            )
438                                    ));
439                           
440                           temp = constraint_addOr (temp, tempSub);
441                           constraint_free(tempSub);
442                           
443                         }
444                       if (!constraint_same (temp, temp3) && !constraint_same (temp3, temp2) )
445                         {
446                          /* drl added 8/28/2002*/
447                           /*make sure that the information from
448                             a post condition like i = i + 1 is transfered
449                           */
450                           constraint tempSub;
451                           
452                           tempSub = constraint_substitute (temp3, post1);
453
454                           DPRINTF((
455                                    message("doResolve: adding %s ",
456                                            constraint_unparseOr(tempSub)
457                                            )
458                                    ));
459
460                           
461                           DPRINTF((
462                                    message("doResolve: not adding %s ",
463                                            constraint_unparseOr(temp3)
464                                            )
465                                    ));
466
467                           temp = constraint_addOr (temp, tempSub);
468
469                           constraint_free(tempSub);
470                         }
471                       *resolved = FALSE;
472                       
473                       constraint_free(temp2);
474                       constraint_free(temp3);
475                       constraint_free(c);
476                       
477                       return temp;
478                     }
479                   constraint_free(temp2);
480                   constraint_free(temp3);
481                 }
482               else
483                 {
484                   constraint_free(temp2);
485                   constraint_free(temp3);
486                 }
487             }
488           else
489             {
490               constraint_free(temp2);
491             }             
492           
493         }
494       constraint_free(temp);
495     }
496   constraint_free(c);
497   
498   *resolved = TRUE;
499   return NULL;
500 }
501
502 static /*@only@*/ constraint doResolveOr (/*@observer@*/ /*@temp@*/ constraint c, constraintList post1, /*@out@*/bool * resolved)
503 {
504   constraint ret;
505   constraint next;
506   constraint curr;
507   
508   DPRINTF(( message("doResolveOr: constraint %s and list %s", constraint_unparseOr(c), constraintList_unparse(post1) ) ));
509
510   *resolved = FALSE;
511   
512   llassertfatal(constraint_isDefined(c) );
513
514   ret = constraint_copy(c);
515
516   llassert(constraint_isDefined(ret) );
517
518   if (constraintList_isEmpty(post1) )
519     {
520       return ret;
521     }
522   
523   next = ret->or;
524   ret->or = NULL;
525
526   ret = doResolve (ret, post1, resolved);
527
528   if (*resolved)
529     {
530       if (next != NULL)
531         constraint_free(next);
532       
533       /*we don't need to free ret when resolved is false because ret is null*/
534       llassert(ret == NULL);
535       
536       return NULL;
537     }
538   
539   while (next != NULL)
540     {
541       curr = next;
542       next = curr->or;
543       curr->or = NULL;
544
545       curr = doResolve (curr, post1, resolved);
546       
547        if (*resolved)
548         {
549           /* curr is null so we don't try to free it*/
550           llassert(curr == NULL);
551           
552           if (next != NULL)
553             constraint_free(next);
554
555           constraint_free(ret);
556           return NULL;
557         }
558       ret = constraint_addOr (ret, curr);
559       constraint_free(curr);
560     }
561
562   DPRINTF(( message("doResolveOr: returning ret = %s", constraint_unparseOr(ret) ) ));
563   
564   return ret;
565 }
566
567 /* tries to resolve constraints in list pr2 using post1 */
568 /*@only@*/ constraintList constraintList_reflectChangesOr (constraintList pre2, constraintList post1)
569 {
570   bool resolved;
571   constraintList ret;
572   constraint temp;
573   ret = constraintList_makeNew();
574   DPRINTF((message ("constraintList_reflectChangesOr: lists %s and %s", constraintList_unparse(pre2), constraintList_unparse(post1) )));
575   
576   constraintList_elements (pre2, el)
577     {
578       temp = doResolveOr (el, post1, &resolved);
579
580       if (!resolved)
581         {
582           ret = constraintList_add(ret, temp);
583         }
584       else
585         {
586      /* we don't need to free temp when
587         resolved is false because temp is null */
588           llassert(temp == NULL);
589         }
590       
591     } end_constraintList_elements;
592
593   DPRINTF((message ("constraintList_reflectChangesOr: returning %s", constraintList_unparse(ret) ) ) );
594     return ret;
595 }
596
597 static /*@only@*/ constraintList reflectChangesEnsures (/*@observer@*/ constraintList pre2, constraintList post1)
598 {  
599   constraintList ret;
600   constraint temp;
601   ret = constraintList_makeNew();
602   constraintList_elements (pre2, el)
603     {
604       if (!constraintList_resolve (el, post1) )
605         {
606           temp = constraint_substitute (el, post1);
607           llassert (temp != NULL);
608
609           if (!constraintList_resolve (temp, post1) )
610             ret = constraintList_add (ret, temp);
611           else
612             constraint_free(temp);  
613         }
614       else
615         {
616           DPRINTF ((message ("Resolved away %s ", constraint_unparse(el) ) ) );
617         }
618     } end_constraintList_elements;
619
620     return ret;
621 }
622
623
624 static /*@only@*/ constraintList reflectChangesEnsuresFree1 (/*@only@*/ constraintList pre2, constraintList post1)
625 {
626   constraintList ret;
627
628   ret = reflectChangesEnsures (pre2, post1);
629   
630   constraintList_free(pre2);
631
632   return ret;
633 }
634
635
636 static bool constraint_conflict (constraint c1, constraint c2)
637 {
638   if (!constraint_isDefined(c1) || !constraint_isDefined(c2))
639     {
640       return FALSE;
641     }
642
643   if (constraintExpr_similar (c1->lexpr, c2->lexpr))
644     {
645       if (c1->ar == EQ)
646         if (c1->ar == c2->ar)
647           {
648             DPRINTF (("%s conflicts with %s", constraint_unparse (c1), constraint_unparse (c2)));
649             return TRUE;
650           }
651     }  
652
653   /* This is a slight kludge to prevent circular constraints like
654      strlen(str) == maxRead(s) + strlen(str);
655   */
656
657   /*this code is functional but it may be worth cleaning up at some point. */
658   
659   if (c1->ar == EQ)
660     if (c1->ar == c2->ar)
661       {
662         if (constraintExpr_search (c1->lexpr, c2->expr) )
663           if (constraintExpr_isTerm(c1->lexpr) )
664             {
665               constraintTerm term;
666               
667               term = constraintExpr_getTerm(c1->lexpr);
668
669               if (constraintTerm_isExprNode(term) )
670                 {
671                   DPRINTF ((message ("%s conflicts with %s ", constraint_unparse (c1), constraint_unparse(c2) ) ) );
672                   return TRUE;
673                 }
674             }
675       }
676
677   if (constraint_tooDeep(c1) || constraint_tooDeep(c2) )
678         {
679           DPRINTF ((message ("%s conflicts with %s (constraint is too deep", constraint_unparse (c1), constraint_unparse(c2) ) ) );
680           return TRUE;
681         }
682   
683   DPRINTF ((message ("%s doesn't conflict with %s ", constraint_unparse (c1), constraint_unparse(c2) ) ) );
684
685   return FALSE; 
686
687 }
688
689 static void constraint_fixConflict (/*@temp@*/ constraint good, /*@temp@*/ /*@observer@*/ constraint conflicting) /*@modifies good@*/
690 {
691   llassertfatal(constraint_isDefined(conflicting) );
692   
693   if (conflicting->ar == EQ)
694     {
695       llassertfatal (constraint_isDefined(good));
696       DPRINTF (("Replacing here!"));
697       good->expr = constraintExpr_searchandreplace (good->expr, conflicting->lexpr, conflicting->expr);
698       good = constraint_simplify (good);
699     }
700
701
702 }
703
704 static bool conflict (constraint c, constraintList list)
705 {
706
707   constraintList_elements (list, el)
708     {
709       if ( constraint_conflict(el, c) )
710         {
711           constraint_fixConflict (el, c);
712           return TRUE;
713         }
714     } end_constraintList_elements;
715
716     return FALSE;
717
718 }
719
720 /*
721   check if constraint in list1 conflicts with constraints in List2.  If so we
722   remove form list1 and change list2.
723 */
724
725 constraintList constraintList_fixConflicts (constraintList list1, constraintList list2)
726 {
727   constraintList ret;
728   ret = constraintList_makeNew();
729   llassert(constraintList_isDefined(list1) );
730   constraintList_elements (list1, el)
731     {
732       if (! conflict (el, list2) )
733         {
734           constraint temp;
735           temp = constraint_copy(el);
736           ret = constraintList_add (ret, temp);
737         }
738     } end_constraintList_elements;
739
740     return ret;
741 }
742
743 /*returns true if constraint post satisfies cosntriant pre */
744
745 static bool constraintResolve_satisfies (constraint pre, constraint post)
746 {
747   if (!constraint_isDefined (pre))
748     {
749       return TRUE;
750     }
751
752   if (!constraint_isDefined(post)) 
753     {
754       return FALSE;
755     }
756
757   if (constraint_isAlwaysTrue (pre))
758     return TRUE;
759   
760   if (!constraintExpr_similar (pre->lexpr, post->lexpr) )
761     {
762       return FALSE;
763     }
764   
765   if (constraintExpr_isUndefined(post->expr))
766     {
767       llassert(FALSE);
768       return FALSE;
769     }
770   
771   return rangeCheck (pre->ar, pre->expr, post->ar, post->expr);
772 }
773
774
775 bool constraintList_resolve (/*@temp@*/ /*@observer@*/ constraint c,
776                              /*@temp@*/ /*@observer@*/ constraintList p)
777 {
778   DPRINTF (("[resolve] Trying to resolve constraint: %s using %s",
779             constraint_unparse (c),
780             constraintList_unparse (p)));
781
782   constraintList_elements (p, el)
783     {
784       if (constraintResolve_satisfies (c, el))
785         {
786           DPRINTF (("constraintList_resolve: %s satifies %s", 
787                     constraint_unparse (el), constraint_unparse (c)));
788           return TRUE;
789         }
790       
791       DPRINTF (("constraintList_resolve: %s does not satify %s\n ", 
792                 constraint_unparse (el), constraint_unparse (c)));
793     }
794   end_constraintList_elements;
795
796   DPRINTF (("No constraints satify: %s", constraint_unparse (c)));
797   return FALSE;
798 }
799
800 static bool arithType_canResolve (arithType ar1, arithType ar2)
801 {
802   switch (ar1)
803     {
804     case GTE:
805     case GT:
806       if ((ar2 == GT) || (ar2 == GTE) || (ar2 == EQ))
807         {
808           return TRUE;
809         }
810       break;
811
812     case EQ:
813       if (ar2 == EQ)
814         return TRUE;
815       break;
816
817     case LT:
818     case LTE:
819       if ((ar2 == LT) || (ar2 == LTE) || (ar2 == EQ))
820         return TRUE;
821       break;
822     default:
823       return FALSE;
824     }
825   return FALSE;   
826 }
827
828 /*checks for the case expr2 == sizeof buf1  and buf1 is a fixed array*/
829 static bool sizeofBufComp(constraintExpr buf1, constraintExpr expr2)
830 {
831   constraintTerm ct;
832   exprNode e, t;
833   sRef s1, s2;
834
835   llassertfatal(constraintExpr_isDefined(buf1) &&
836                 constraintExpr_isDefined(expr2) );
837
838   /*@access constraintExpr@*/
839   
840   if ((expr2->kind != term) && (buf1->kind != term) )
841     return FALSE;
842
843   
844   ct = constraintExprData_termGetTerm(expr2->data);
845
846   if (!constraintTerm_isExprNode(ct) )
847     return FALSE;
848
849   e = constraintTerm_getExprNode(ct);
850
851   llassert (exprNode_isDefined(e));
852
853   if (! (exprNode_isDefined(e)))
854     return FALSE;
855   
856   if (e->kind != XPR_SIZEOF)
857     return FALSE;
858   
859   t = exprData_getSingle (e->edata);
860   s1 = exprNode_getSref (t);
861
862   s2 = constraintTerm_getsRef(constraintExprData_termGetTerm(buf1->data) );
863
864   /*drl this may be the wronge thing to test for but this
865     seems to work correctly*/
866   if (sRef_similarRelaxed(s1, s2)   || sRef_sameName (s1, s2) )
867     {
868       /* origly checked that ctype_isFixedArray(sRef_getType(s2)) but
869          removed that test */
870         return TRUE;
871     }
872   return FALSE;
873 }
874
875 /* look for the special case of
876    maxSet(buf) >= sizeof(buf) - 1
877 */
878
879 /*drl eventually it would be good to check that
880   buf is of type char.*/
881
882 static bool sizeOfMaxSet( /*@observer@*/ /*@temp@*/ constraint c)
883 {
884   constraintExpr l, r, buf1, buf2, con;
885
886   DPRINTF(( message("sizeOfMaxSet: checking %s ", constraint_unparse(c) )
887             ));
888
889   llassertfatal (constraint_isDefined(c) );
890     
891   l = c->lexpr;
892   r = c->expr;
893
894   if (!((c->ar == EQ) || (c->ar == GTE) || (c->ar == LTE) ) )
895     return FALSE;
896
897   llassert (constraintExpr_isDefined(l)  );
898   llassert (constraintExpr_isDefined(r)  );
899
900   /*check if the constraintExpr is MaxSet(buf) */
901   if (l->kind == unaryExpr)
902     {
903       if (constraintExprData_unaryExprGetOp(l->data) == MAXSET)
904         {
905           buf1 = constraintExprData_unaryExprGetExpr(l->data);
906         }
907       else
908         return FALSE;
909     }
910   else
911     return FALSE;
912
913   
914   if (r->kind != binaryexpr)
915     return FALSE;
916   
917   buf2 = constraintExprData_binaryExprGetExpr1(r->data);
918   con = constraintExprData_binaryExprGetExpr2(r->data);
919   
920   if (constraintExprData_binaryExprGetOp(r->data) == BINARYOP_MINUS)
921     {
922       if (constraintExpr_canGetValue(con) )
923         {
924           long i;
925           
926           i = constraintExpr_getValue(con);
927           if (i != 1)
928             {
929               return FALSE;
930             }
931         }
932       else
933         return FALSE;
934     }
935
936   if (constraintExprData_binaryExprGetOp(r->data) == BINARYOP_PLUS)
937     {
938       if (constraintExpr_canGetValue(con) )
939         {
940           long i;
941           
942           i = constraintExpr_getValue(con);
943           if (i != -1)
944             {
945               return FALSE;
946             }
947         }
948       else
949         return FALSE;
950     }
951
952   if (sizeofBufComp(buf1, buf2))
953     {
954       return TRUE;
955     }
956   else
957     {
958      return FALSE;
959     } 
960 }
961 /*@noaccess constraintExpr@*/
962
963 /* We look for constraint which are tautologies */
964
965 bool constraint_isAlwaysTrue (/*@observer@*/ /*@temp@*/ constraint c)
966 {
967   constraintExpr l, r;
968   bool rHasConstant;
969   int rConstant;
970
971   
972   llassert (constraint_isDefined(c) );  
973   
974   l = c->lexpr;
975   r = c->expr;
976
977   DPRINTF(( message("constraint_IsAlwaysTrue:examining %s", constraint_unparse(c) ) ));
978
979   if (sizeOfMaxSet(c) )
980     return TRUE;
981   
982   if (constraintExpr_canGetValue(l) && constraintExpr_canGetValue(r) )
983     {
984       int cmp;
985       cmp = constraintExpr_compare (l, r);
986       switch (c->ar)
987         {
988         case EQ:
989           return (cmp == 0);
990         case GT:
991           return (cmp > 0);
992         case GTE:
993           return (cmp >= 0);
994         case LTE:
995           return (cmp <= 0);
996         case LT:
997           return (cmp < 0);
998
999         default:
1000           BADEXIT;
1001           /*@notreached@*/
1002           break;
1003         }
1004     }
1005
1006   if (constraintExpr_similar (l,r))
1007     {
1008       switch (c->ar)
1009         {
1010         case EQ:
1011         case GTE:
1012         case LTE:
1013           return TRUE;
1014           
1015         case GT:
1016         case LT:
1017           break;
1018         default:
1019           BADEXIT;
1020           /*@notreached@*/
1021           break;
1022         }
1023     }
1024
1025   l = constraintExpr_copy (c->lexpr);
1026   r = constraintExpr_copy (c->expr);
1027
1028   r = constraintExpr_propagateConstants (r, &rHasConstant, &rConstant);
1029
1030   if (constraintExpr_similar (l,r) && (rHasConstant ) )
1031     {
1032       DPRINTF(( message("constraint_IsAlwaysTrue: after removing constants %s and %s are similar", constraintExpr_unparse(l), constraintExpr_unparse(r) ) ));
1033       DPRINTF(( message("constraint_IsAlwaysTrue: rconstant is %d", rConstant ) ));
1034       
1035       constraintExpr_free(l);
1036       constraintExpr_free(r);
1037       
1038       switch (c->ar)
1039         {
1040         case EQ:
1041           return (rConstant == 0);
1042         case LT:
1043           return (rConstant > 0);
1044         case LTE:
1045           return (rConstant >= 0);
1046         case GTE:
1047           return (rConstant <= 0);
1048         case GT:
1049           return (rConstant < 0);
1050           
1051         default:
1052           BADEXIT;
1053           /*@notreached@*/
1054           break;
1055         }
1056     }  
1057       else
1058       {
1059         constraintExpr_free(l);
1060         constraintExpr_free(r);
1061         DPRINTF(( message("Constraint %s is not always true", constraint_unparse(c) ) ));
1062         return FALSE;
1063       }
1064   
1065   BADEXIT;
1066 }
1067
1068 static bool rangeCheck (arithType ar1, /*@observer@*/ constraintExpr expr1, arithType ar2, /*@observer@*/ constraintExpr expr2)
1069
1070 {
1071   DPRINTF (("Doing range check %s and %s",
1072             constraintExpr_unparse (expr1), constraintExpr_unparse (expr2)));
1073
1074   if (!arithType_canResolve (ar1, ar2))
1075     return FALSE;
1076   
1077   switch (ar1)
1078     {
1079     case GTE:
1080       if (constraintExpr_similar (expr1, expr2) )
1081         return TRUE;
1082       /*@fallthrough@*/
1083     case GT:
1084       if (!  (constraintExpr_canGetValue (expr1) &&
1085               constraintExpr_canGetValue (expr2) ) )
1086         {
1087           constraintExpr e1, e2;
1088           bool p1, p2;
1089           int const1, const2;
1090           
1091           e1 = constraintExpr_copy(expr1);
1092           e2 = constraintExpr_copy(expr2);
1093           
1094           e1 = constraintExpr_propagateConstants (e1, &p1, &const1);
1095           e2 = constraintExpr_propagateConstants (e2, &p2, &const2);
1096           
1097           if (p1 || p2)
1098             {
1099               if (!p1)
1100                 const1 = 0;
1101               
1102               if (!p2)
1103                 const2 = 0;
1104               
1105               if (const1 <= const2)
1106                 if (constraintExpr_similar (e1, e2) )
1107                   {
1108                     constraintExpr_free(e1);
1109                     constraintExpr_free(e2);
1110                     return TRUE;
1111                   }
1112             }
1113           DPRINTF(("Can't Get value"));
1114           
1115           constraintExpr_free(e1);
1116           constraintExpr_free(e2);
1117           return FALSE;
1118         }
1119       
1120       if (constraintExpr_compare (expr2, expr1) >= 0)
1121         return TRUE;
1122       
1123       return FALSE;
1124     case EQ:
1125       if (constraintExpr_similar (expr1, expr2) )
1126         return TRUE;
1127       
1128       return FALSE;
1129     case LTE:
1130       if (constraintExpr_similar (expr1, expr2) )
1131         return TRUE;
1132       /*@fallthrough@*/
1133     case LT:
1134       if (!  (constraintExpr_canGetValue (expr1) &&
1135               constraintExpr_canGetValue (expr2) ) )
1136         {
1137           constraintExpr e1, e2;
1138           bool p1, p2;
1139           int const1, const2;
1140           
1141           e1 = constraintExpr_copy(expr1);
1142           e2 = constraintExpr_copy(expr2);
1143           
1144           e1 = constraintExpr_propagateConstants (e1, &p1, &const1);
1145           
1146           e2 = constraintExpr_propagateConstants (e2, &p2, &const2);
1147           
1148           if (p1 || p2)
1149             {
1150               if (!p1)
1151                 const1 = 0;
1152               
1153               if (!p2)
1154                 const2 = 0;
1155               
1156               if (const1 >= const2)
1157                 if (constraintExpr_similar (e1, e2) )
1158                   {
1159                     constraintExpr_free(e1);
1160                     constraintExpr_free(e2);
1161                     return TRUE;
1162                   }
1163             }
1164           constraintExpr_free(e1);
1165           constraintExpr_free(e2);
1166           
1167           DPRINTF(("Can't Get value"));
1168           return FALSE;
1169         }
1170       
1171       if (constraintExpr_compare (expr2, expr1) <= 0)
1172         return TRUE;
1173       
1174       return FALSE;
1175       
1176     default:
1177       llcontbug((message("Unhandled case in switch: %q", arithType_print(ar1) ) ) );
1178     }
1179   BADEXIT;
1180 }
1181
1182 static constraint constraint_searchandreplace (/*@returned@*/ constraint c, constraintExpr old, constraintExpr newExpr)
1183 {
1184   llassertfatal (constraint_isDefined(c));
1185   
1186   DPRINTF (("Starting replace lexpr [%p]: %s < %s ==> %s > in %s", c, 
1187             constraintExpr_unparse (c->lexpr), 
1188             constraintExpr_unparse (old), constraintExpr_unparse (newExpr),
1189             constraint_unparse (c)));
1190   c->lexpr = constraintExpr_searchandreplace (c->lexpr, old, newExpr);
1191   DPRINTF (("Finished replace lexpr [%p]: %s", c, constraintExpr_unparse (c->lexpr)));
1192   c->expr = constraintExpr_searchandreplace (c->expr, old, newExpr);
1193   return c;
1194 }
1195
1196 bool constraint_search (constraint c, constraintExpr old) /*@*/
1197 {
1198   bool ret;
1199   ret = FALSE;
1200   
1201   llassert (constraint_isDefined (c));
1202   
1203   ret  = constraintExpr_search (c->lexpr, old);
1204   ret = ret || constraintExpr_search (c->expr, old);
1205   return ret;
1206 }
1207
1208 /* adjust file locs and stuff */
1209 static constraint constraint_adjust (/*@returned@*/ constraint substitute, /*@observer@*/ constraint old)
1210 {
1211   fileloc loc1, loc2, loc3;
1212
1213   DPRINTF ((message("Start adjust on %s and %s", constraint_unparse(substitute),
1214                      constraint_unparse(old))
1215                    ));
1216
1217   llassert(constraint_isDefined(substitute));
1218   llassert(constraint_isDefined(old));
1219            
1220   loc1 = constraint_getFileloc (old);
1221   loc2 = constraintExpr_loc (substitute->lexpr);
1222   loc3 = constraintExpr_loc (substitute->expr);
1223   
1224   /* special case of an equality that "contains itself" */
1225   if (constraintExpr_search (substitute->expr, substitute->lexpr) )
1226       if (fileloc_closer (loc1, loc3, loc2))
1227       {
1228         constraintExpr temp;
1229         DPRINTF ((message("Doing adjust on %s", constraint_unparse(substitute) )
1230                    ));
1231         temp = substitute->lexpr;
1232         substitute->lexpr = substitute->expr;
1233         substitute->expr  = temp;
1234         substitute = constraint_simplify(substitute);
1235       }
1236
1237   fileloc_free (loc1);
1238   fileloc_free (loc2);
1239   fileloc_free (loc3);
1240
1241   return substitute;
1242   
1243 }
1244
1245 /* If function preforms substitutes based on inequality
1246
1247    It uses the rule x >= y && b < y  ===> x >= b + 1
1248
1249    Warning this is sound but throws out information
1250  */
1251
1252 constraint  inequalitySubstitute  (/*@returned@*/ constraint c, constraintList p)
1253 {
1254   llassert(constraint_isDefined(c) );
1255
1256   if (c->ar != GTE)
1257     return c;
1258   
1259   constraintList_elements (p, el)
1260     {
1261       
1262       llassert(constraint_isDefined(el) );
1263       
1264       if ((el->ar == LT )  )
1265            {
1266              constraintExpr  temp2;
1267              
1268              if (constraintExpr_same (el->expr, c->expr) )
1269                {
1270                  DPRINTF((message ("inequalitySubstitute Replacing %q in %q with  %q",
1271                                    constraintExpr_print (c->expr),
1272                                    constraint_unparse (c),
1273                                    constraintExpr_print (el->expr) )
1274                           ));
1275                  temp2   = constraintExpr_copy (el->lexpr);
1276                  constraintExpr_free(c->expr);
1277                  c->expr =  constraintExpr_makeIncConstraintExpr (temp2);
1278
1279                }
1280              
1281            }
1282     }
1283   end_constraintList_elements;
1284
1285   c = constraint_simplify(c);
1286   return c;
1287 }
1288
1289
1290 /* drl7x 7/26/001
1291
1292    THis function is like inequalitySubstitute but it adds the rule
1293    added the rules x >= y &&  y <= b  ===> x >= b
1294     x >= y &&  y < b  ===> x >= b + 1
1295
1296    This is sound but sonce it throws out additional information it should only one used
1297    if we're oring constraints.
1298  */
1299
1300 static constraint  inequalitySubstituteStrong  (/*@returned@*/ constraint c, constraintList p)
1301 {
1302   DPRINTF (( message ("inequalitySubstituteStrong examining substituting for %q", constraint_unparse(c) ) ));      
1303
1304   llassert(constraint_isDefined(c) );
1305
1306   if (! (constraint_isDefined(c) ) )
1307   {
1308     return c;
1309   }
1310   
1311   if (c->ar != GTE)
1312     return c;
1313   
1314   DPRINTF (( message ("inequalitySubstituteStrong examining substituting for %q with %q",
1315                       constraint_unparse(c), constraintList_unparse(p) ) ));      
1316   constraintList_elements (p, el)
1317     {
1318       
1319       DPRINTF (( message ("inequalitySubstituteStrong examining substituting %s on %s", constraint_unparse(el), constraint_unparse(c) ) ));      
1320
1321       llassert(constraint_isDefined(el) );
1322       if ((el->ar == LT ) ||  (el->ar == LTE )  )
1323            {
1324              constraintExpr  temp2;
1325              
1326              if (constraintExpr_same (el->lexpr, c->expr) )
1327                {
1328                  DPRINTF((message ("inequalitySubstitute Replacing %s in %s with  %s",
1329                                    constraintExpr_print (c->expr),
1330                                    constraint_unparse (c),
1331                                    constraintExpr_print (el->expr) )
1332                           ));
1333                  temp2   = constraintExpr_copy (el->expr);
1334                  constraintExpr_free(c->expr);
1335                  if ((el->ar == LTE ) )
1336                    {
1337                      c->expr = temp2;
1338                    }
1339                  else
1340                    {
1341                      c->expr =  constraintExpr_makeIncConstraintExpr (temp2);
1342                    }
1343                }
1344              
1345            }
1346     }
1347   end_constraintList_elements;
1348
1349   c = constraint_simplify(c);
1350   return c;
1351 }
1352
1353
1354 /* This function performs substitutions based on the rule:
1355    for a constraint of the form expr1 >= expr2;   a < b =>
1356    a = b -1 for all a in expr1.  This will work in most cases.
1357
1358    Like inequalitySubstitute we're throwing away some information
1359 */
1360
1361 static constraint  inequalitySubstituteUnsound  (/*@returned@*/ constraint c, constraintList p)
1362 {
1363   DPRINTF (( message ("Doing inequalitySubstituteUnsound " ) ));
1364
1365     llassert(constraint_isDefined(c) );
1366   
1367   if (c->ar != GTE)
1368     return c;
1369   
1370   constraintList_elements (p, el)
1371     {
1372
1373       llassert(constraint_isDefined(el) );
1374
1375       DPRINTF (( message ("inequalitySubstituteUnsound examining substituting %s on %s", constraint_unparse(el), constraint_unparse(c) ) ));      
1376        if (( el->ar == LTE) || (el->ar == LT) )
1377            {
1378              constraintExpr  temp2;
1379
1380              temp2   = constraintExpr_copy (el->expr);
1381              
1382              if (el->ar == LT)
1383                temp2  =  constraintExpr_makeDecConstraintExpr (temp2);
1384              
1385              DPRINTF((message ("Replacing %s in %s with  %s",
1386                                constraintExpr_print (el->lexpr),
1387                                constraintExpr_print (c->lexpr),
1388                                constraintExpr_print (temp2) ) ));
1389              
1390              c->lexpr = constraintExpr_searchandreplace (c->lexpr, el->lexpr, temp2);
1391              constraintExpr_free(temp2);
1392            }
1393     }
1394   end_constraintList_elements;
1395
1396   c = constraint_simplify(c);
1397   return c;
1398 }
1399
1400 /*@only@*/ constraint constraint_substitute (/*@observer@*/ /*@temp@*/ constraint c, constraintList p)
1401 {
1402   constraint ret = constraint_copy (c);
1403
1404   constraintList_elements (p, el)
1405     {
1406       if (constraint_isDefined (el))
1407         {
1408           if ( el->ar == EQ)
1409             if (!constraint_conflict (ret, el))
1410               {
1411                 constraint temp = constraint_copy(el);
1412                 temp = constraint_adjust(temp, ret);
1413                 
1414                 llassert(constraint_isDefined(temp) );
1415                 
1416                 
1417                 DPRINTF (("constraint_substitute :: Substituting in %s using %s",
1418                           constraint_unparse (ret), constraint_unparse (temp)));
1419           
1420                 ret = constraint_searchandreplace (ret, temp->lexpr, temp->expr);
1421                 DPRINTF (("constraint_substitute :: The new constraint is %s", constraint_unparse (ret)));;
1422                 constraint_free(temp);
1423               }
1424         }
1425     }
1426   end_constraintList_elements;
1427
1428   ret = constraint_simplify (ret);
1429   DPRINTF(( message (" constraint_substitute :: The final new constraint is %s", constraint_unparse (ret) ) ));
1430   return ret;
1431 }
1432
1433
1434 /*@only@*/ constraintList constraintList_substituteFreeTarget (/*@only@*/ constraintList target, /*@observer@*/ constraintList subList)
1435 {
1436 constraintList ret;
1437
1438 ret = constraintList_substitute (target, subList);
1439
1440 constraintList_free(target);
1441
1442 return ret;
1443 }
1444
1445 /* we try to do substitutions on each constraint in target using the constraint in sublist*/
1446
1447 /*@only@*/ constraintList constraintList_substitute (constraintList target,/*2observer@*/  constraintList subList)
1448 {
1449
1450   constraintList ret;
1451
1452   ret = constraintList_makeNew();
1453   
1454   constraintList_elements(target, el)
1455   { 
1456     constraint temp;
1457     /* drl possible problem : warning make sure that a side effect is not expected */
1458
1459     temp = constraint_substitute(el, subList);
1460     ret = constraintList_add (ret, temp);
1461   }
1462   end_constraintList_elements;
1463
1464   return ret;
1465 }
1466
1467 static constraint constraint_solve (/*@returned@*/ constraint c)
1468 {
1469
1470   llassert(constraint_isDefined(c) );
1471
1472   DPRINTF((message ("Solving %s\n", constraint_unparse(c) ) ) );
1473   c->expr = constraintExpr_solveBinaryExpr (c->lexpr, c->expr);
1474   DPRINTF((message ("Solved and got %s\n", constraint_unparse(c) ) ) );
1475
1476   return c;
1477 }
1478
1479 static arithType flipAr (arithType ar)
1480 {
1481   switch (ar)
1482     {
1483     case LT:
1484       return GT;
1485     case LTE:
1486       return GTE;
1487     case EQ:
1488       return EQ;
1489     case GT:
1490       return LT;
1491     case GTE:
1492       return LTE;
1493     default:
1494       llcontbug (message("unexpected value: case not handled"));
1495     }
1496   BADEXIT;
1497 }
1498
1499 static constraint  constraint_swapLeftRight (/*@returned@*/ constraint c)
1500 {
1501   constraintExpr temp;
1502
1503   llassert(constraint_isDefined(c) );
1504
1505   c->ar = flipAr (c->ar);
1506   temp = c->lexpr;
1507   c->lexpr = c->expr;
1508   c->expr = temp;
1509   DPRINTF(("Swaped left and right sides of constraint"));
1510   return c;
1511 }
1512
1513
1514
1515 constraint constraint_simplify ( /*@returned@*/ constraint c)
1516 {
1517   
1518   llassert(constraint_isDefined(c) );
1519         
1520   DPRINTF(( message("constraint_simplify on %q ", constraint_unparse(c) ) ));
1521
1522   if (constraint_tooDeep(c))
1523     {
1524         DPRINTF(( message("constraint_simplify: constraint to complex aborting %q ", constraint_unparse(c) ) ));
1525       return c;
1526
1527     }
1528   
1529   c->lexpr = constraintExpr_simplify (c->lexpr);
1530   c->expr  = constraintExpr_simplify (c->expr);
1531
1532   if (constraintExpr_isBinaryExpr (c->lexpr) )
1533     {
1534       c = constraint_solve (c);
1535       
1536       c->lexpr = constraintExpr_simplify (c->lexpr);
1537       c->expr  = constraintExpr_simplify (c->expr);
1538     }
1539   
1540   if (constraintExpr_isLit(c->lexpr) && (!constraintExpr_isLit(c->expr) ) )
1541     {
1542       c = constraint_swapLeftRight(c);
1543       /*I don't think this will be an infinate loop*/
1544       c = constraint_simplify(c);
1545     }
1546
1547   DPRINTF(( message("constraint_simplify returning  %q ", constraint_unparse(c) ) ));
1548
1549   return c;
1550 }
1551
1552
1553
1554
1555 /* returns true  if fileloc for term1 is closer to file for term2 than term3*/
1556
1557 bool fileloc_closer (fileloc  loc1, fileloc  loc2, fileloc  loc3)
1558 {
1559
1560   if  (!fileloc_isDefined (loc1) )
1561     return FALSE;
1562
1563   if  (!fileloc_isDefined (loc2) )
1564     return FALSE;
1565
1566   if  (!fileloc_isDefined (loc3) )
1567     return TRUE;
1568
1569   
1570   
1571   
1572   if (fileloc_equal (loc2, loc3) )
1573     return FALSE;
1574
1575   if (fileloc_equal (loc1, loc2) )
1576     return TRUE;
1577
1578     if (fileloc_equal (loc1, loc3) )
1579     return FALSE;
1580
1581    if ( fileloc_lessthan (loc1, loc2) )
1582      {
1583        if (fileloc_lessthan (loc2, loc3) )
1584          {
1585            llassert (fileloc_lessthan (loc1, loc3) );
1586            return TRUE;
1587          }
1588        else
1589          {
1590            return FALSE;
1591          }
1592      }
1593
1594    if ( !fileloc_lessthan (loc1, loc2) )
1595      {
1596        if (!fileloc_lessthan (loc2, loc3) )
1597          {
1598            llassert (!fileloc_lessthan (loc1, loc3) );
1599            return TRUE;
1600          }
1601        else
1602          {
1603            return FALSE;
1604          }
1605      }
1606
1607    llassert(FALSE);
1608    return FALSE;
1609 }
1610
1611
This page took 0.410337 seconds and 5 git commands to generate.