KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > toolkits > typing > ConstraintCheckerBV


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 1997-2000 Etienne Gagnon. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

19
20 /*
21  * Modified by the Sable Research Group and others 1997-1999.
22  * See the 'credits' file distributed with Soot for the complete list of
23  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
24  */

25
26
27 package soot.jimple.toolkits.typing;
28
29 import soot.*;
30 import soot.jimple.*;
31 import soot.util.*;
32 import java.util.*;
33 import java.io.*;
34
35 class ConstraintCheckerBV extends AbstractStmtSwitch
36 {
37   private final TypeResolverBV resolver;
38   private final ClassHierarchy hierarchy;
39   private final boolean fix; // if true, fix constraint violations
40

41   private JimpleBody stmtBody;
42
43   public ConstraintCheckerBV(TypeResolverBV resolver, boolean fix)
44   {
45     this.resolver = resolver;
46     this.fix = fix;
47
48     hierarchy = resolver.hierarchy();
49   }
50
51   public void check(Stmt stmt, JimpleBody stmtBody) throws TypeException
52   {
53     try
54       {
55     this.stmtBody = stmtBody;
56     stmt.apply(this);
57       }
58     catch(RuntimeTypeException e)
59       {
60         StringWriter st = new StringWriter();
61         PrintWriter pw = new PrintWriter(st);
62     e.printStackTrace(pw);
63     pw.close();
64     throw new TypeException(st.toString());
65       }
66   }
67
68   private static class RuntimeTypeException extends RuntimeException JavaDoc
69   {
70     RuntimeTypeException(String JavaDoc message)
71     {
72       super(message);
73     }
74   }
75
76   static void error(String JavaDoc message)
77   {
78     throw new RuntimeTypeException(message);
79   }
80
81   private void handleInvokeExpr(InvokeExpr ie, Stmt invokestmt)
82   {
83     if(ie instanceof InterfaceInvokeExpr)
84       {
85     InterfaceInvokeExpr invoke = (InterfaceInvokeExpr) ie;
86     
87     SootMethodRef method = invoke.getMethodRef();
88     Value base = invoke.getBase();
89     
90     if(base instanceof Local)
91       {
92         Local local = (Local) base;
93         
94         if(!hierarchy.typeNode(local.getType()).hasAncestorOrSelf(hierarchy.typeNode(method.declaringClass().getType())))
95           {
96         if(fix)
97           {
98             invoke.setBase(insertCast(local, method.declaringClass().getType(), invokestmt));
99           }
100         else
101           {
102             error("Type Error(7): local " + local + " is of incompatible type " + local.getType());
103           }
104           }
105       }
106     
107     int count = invoke.getArgCount();
108     
109     for(int i = 0; i < count; i++)
110       {
111         if(invoke.getArg(i) instanceof Local)
112           {
113         Local local = (Local) invoke.getArg(i);
114
115         if(!hierarchy.typeNode(local.getType()).hasAncestorOrSelf(hierarchy.typeNode(method.parameterType(i))))
116           {
117             if(fix)
118               {
119             invoke.setArg(i, insertCast(local, method.parameterType(i), invokestmt));
120               }
121             else
122               {
123             error("Type Error(8)");
124               }
125           }
126           }
127       }
128       }
129     else if(ie instanceof SpecialInvokeExpr)
130       {
131     SpecialInvokeExpr invoke = (SpecialInvokeExpr) ie;
132
133     SootMethodRef method = invoke.getMethodRef();
134     Value base = invoke.getBase();
135
136     if(base instanceof Local)
137       {
138         Local local = (Local) base;
139
140         if(!hierarchy.typeNode(local.getType()).hasAncestorOrSelf(hierarchy.typeNode(method.declaringClass().getType())))
141           {
142         if(fix)
143           {
144             invoke.setBase(insertCast(local, method.declaringClass().getType(), invokestmt));
145           }
146         else
147           {
148             error("Type Error(9)");
149           }
150           }
151       }
152
153     int count = invoke.getArgCount();
154
155     for(int i = 0; i < count; i++)
156       {
157         if(invoke.getArg(i) instanceof Local)
158           {
159         Local local = (Local) invoke.getArg(i);
160
161         if(!hierarchy.typeNode(local.getType()).hasAncestorOrSelf(hierarchy.typeNode(method.parameterType(i))))
162           {
163             if(fix)
164               {
165             invoke.setArg(i, insertCast(local, method.parameterType(i), invokestmt));
166               }
167             else
168               {
169             error("Type Error(10)");
170               }
171           }
172           }
173       }
174       }
175     else if(ie instanceof VirtualInvokeExpr)
176       {
177     VirtualInvokeExpr invoke = (VirtualInvokeExpr) ie;
178
179     SootMethodRef method = invoke.getMethodRef();
180     Value base = invoke.getBase();
181
182     if(base instanceof Local)
183       {
184         Local local = (Local) base;
185
186         if(!hierarchy.typeNode(local.getType()).hasAncestorOrSelf(hierarchy.typeNode(method.declaringClass().getType())))
187           {
188         if(fix)
189           {
190             invoke.setBase(insertCast(local, method.declaringClass().getType(), invokestmt));
191           }
192         else
193           {
194             error("Type Error(13)");
195           }
196           }
197       }
198
199     int count = invoke.getArgCount();
200
201     for(int i = 0; i < count; i++)
202       {
203         if(invoke.getArg(i) instanceof Local)
204           {
205         Local local = (Local) invoke.getArg(i);
206
207         if(!hierarchy.typeNode(local.getType()).hasAncestorOrSelf(hierarchy.typeNode(method.parameterType(i))))
208           {
209             if(fix)
210               {
211             invoke.setArg(i, insertCast(local, method.parameterType(i), invokestmt));
212               }
213             else
214               {
215             error("Type Error(14)");
216               }
217           }
218           }
219       }
220       }
221     else if(ie instanceof StaticInvokeExpr)
222       {
223     StaticInvokeExpr invoke = (StaticInvokeExpr) ie;
224
225     SootMethodRef method = invoke.getMethodRef();
226
227     int count = invoke.getArgCount();
228
229     for(int i = 0; i < count; i++)
230       {
231         if(invoke.getArg(i) instanceof Local)
232           {
233         Local local = (Local) invoke.getArg(i);
234
235         if(!hierarchy.typeNode(local.getType()).hasAncestorOrSelf(hierarchy.typeNode(method.parameterType(i))))
236           {
237             if(fix)
238               {
239             invoke.setArg(i, insertCast(local, method.parameterType(i), invokestmt));
240               }
241             else
242               {
243             error("Type Error(15)");
244               }
245           }
246           }
247       }
248       }
249     else
250       {
251     throw new RuntimeException JavaDoc("Unhandled invoke expression type: " + ie.getClass());
252       }
253   }
254
255   public void caseBreakpointStmt(BreakpointStmt stmt)
256   {
257     // Do nothing
258
}
259
260   public void caseInvokeStmt(InvokeStmt stmt)
261   {
262     handleInvokeExpr((InvokeExpr) stmt.getInvokeExpr(), stmt);
263   }
264
265   public void caseAssignStmt(AssignStmt stmt)
266   {
267     Value l = stmt.getLeftOp();
268     Value r = stmt.getRightOp();
269
270     TypeNode left = null;
271
272     //******** LEFT ********
273

274     if(l instanceof ArrayRef)
275       {
276     ArrayRef ref = (ArrayRef) l;
277     TypeNode base = hierarchy.typeNode(((Local) ref.getBase()).getType());
278
279     if(!base.isArray())
280       {
281         error("Type Error(16)");
282       }
283
284     left = base.element();
285     
286     Value index = ref.getIndex();
287     
288     if(index instanceof Local)
289       {
290         if(!hierarchy.typeNode(((Local) index).getType()).hasAncestorOrSelf(hierarchy.typeNode(IntType.v())))
291           {
292         error("Type Error(17)");
293           }
294       }
295       }
296     else if(l instanceof Local)
297       {
298     try
299       {
300         left = hierarchy.typeNode(((Local) l).getType());
301       }
302     catch(InternalTypingException e)
303       {
304         G.v().out.println("untyped local: " + l);
305         throw e;
306       }
307       }
308     else if(l instanceof InstanceFieldRef)
309       {
310     InstanceFieldRef ref = (InstanceFieldRef) l;
311     
312     TypeNode base = hierarchy.typeNode(((Local) ref.getBase()).getType());
313     
314     if(!base.hasAncestorOrSelf(hierarchy.typeNode(ref.getField().getDeclaringClass().getType())))
315       {
316         if(fix)
317           {
318         ref.setBase(insertCast((Local) ref.getBase(), ref.getField().getDeclaringClass().getType(), stmt));
319           }
320         else
321           {
322         error("Type Error(18)");
323           }
324       }
325
326     left = hierarchy.typeNode(ref.getField().getType());
327       }
328     else if(l instanceof StaticFieldRef)
329       {
330     StaticFieldRef ref = (StaticFieldRef) l;
331     left = hierarchy.typeNode(ref.getField().getType());
332       }
333     else
334       {
335     throw new RuntimeException JavaDoc("Unhandled assignment left hand side type: " + l.getClass());
336       }
337
338     //******** RIGHT ********
339

340     if(r instanceof ArrayRef)
341       {
342     ArrayRef ref = (ArrayRef) r;
343     TypeNode base = hierarchy.typeNode(((Local) ref.getBase()).getType());
344
345     if(!base.isArray())
346       {
347         error("Type Error(19): " + base + " is not an array type");
348       }
349
350     if(base == hierarchy.NULL)
351       {
352         return;
353       }
354
355     if(!left.hasDescendantOrSelf(base.element()))
356       {
357         if(fix)
358           {
359         Type lefttype = left.type();
360         if(lefttype instanceof ArrayType)
361           {
362             ArrayType atype = (ArrayType) lefttype;
363             ref.setBase(insertCast((Local) ref.getBase(), ArrayType.v(atype.baseType, atype.numDimensions + 1), stmt));
364           }
365         else
366           {
367             ref.setBase(insertCast((Local) ref.getBase(), ArrayType.v(lefttype, 1), stmt));
368           }
369           }
370         else
371           {
372         error("Type Error(20)");
373           }
374       }
375
376     Value index = ref.getIndex();
377     
378     if(index instanceof Local)
379     {
380       if(!hierarchy.typeNode(((Local) index).getType()).hasAncestorOrSelf(hierarchy.typeNode(IntType.v())))
381         {
382           error("Type Error(21)");
383         }
384     }
385       }
386     else if(r instanceof DoubleConstant)
387       {
388     if(!left.hasDescendantOrSelf(hierarchy.typeNode(DoubleType.v())))
389       {
390         error("Type Error(22)");
391       }
392       }
393     else if(r instanceof FloatConstant)
394       {
395     if(!left.hasDescendantOrSelf(hierarchy.typeNode(FloatType.v())))
396       {
397         error("Type Error(45)");
398       }
399       }
400     else if(r instanceof IntConstant)
401       {
402     if(!left.hasDescendantOrSelf(hierarchy.typeNode(IntType.v())))
403       {
404         error("Type Error(23)");
405       }
406       }
407     else if(r instanceof LongConstant)
408       {
409     if(!left.hasDescendantOrSelf(hierarchy.typeNode(LongType.v())))
410       {
411         error("Type Error(24)");
412       }
413       }
414     else if(r instanceof NullConstant)
415       {
416     if(!left.hasDescendantOrSelf(hierarchy.typeNode(NullType.v())))
417       {
418         error("Type Error(25)");
419       }
420       }
421     else if(r instanceof StringConstant)
422       {
423     if(!left.hasDescendantOrSelf(hierarchy.typeNode(RefType.v("java.lang.String"))))
424       {
425         error("Type Error(26)");
426       }
427       }
428     else if(r instanceof ClassConstant)
429       {
430     if(!left.hasDescendantOrSelf(hierarchy.typeNode(RefType.v("java.lang.Class"))))
431       {
432         error("Type Error(27)");
433       }
434       }
435     else if(r instanceof BinopExpr)
436       {
437     //******** BINOP EXPR ********
438

439     BinopExpr be = (BinopExpr) r;
440
441     Value lv = be.getOp1();
442     Value rv = be.getOp2();
443     
444     TypeNode lop;
445     TypeNode rop;
446
447     //******** LEFT ********
448
if(lv instanceof Local)
449       {
450         lop = hierarchy.typeNode(((Local) lv).getType());
451       }
452     else if(lv instanceof DoubleConstant)
453       {
454         lop = hierarchy.typeNode(DoubleType.v());
455       }
456     else if(lv instanceof FloatConstant)
457       {
458         lop = hierarchy.typeNode(FloatType.v());
459       }
460     else if(lv instanceof IntConstant)
461       {
462         lop = hierarchy.typeNode(IntType.v());
463       }
464     else if(lv instanceof LongConstant)
465       {
466         lop = hierarchy.typeNode(LongType.v());
467       }
468     else if(lv instanceof NullConstant)
469       {
470         lop = hierarchy.typeNode(NullType.v());
471       }
472     else if(lv instanceof StringConstant)
473       {
474         lop = hierarchy.typeNode(RefType.v("java.lang.String"));
475       }
476     else if(lv instanceof ClassConstant)
477       {
478         lop = hierarchy.typeNode(RefType.v("java.lang.Class"));
479       }
480     else
481       {
482         throw new RuntimeException JavaDoc("Unhandled binary expression left operand type: " + lv.getClass());
483       }
484     
485     //******** RIGHT ********
486
if(rv instanceof Local)
487       {
488         rop = hierarchy.typeNode(((Local) rv).getType());
489       }
490     else if(rv instanceof DoubleConstant)
491       {
492         rop = hierarchy.typeNode(DoubleType.v());
493       }
494     else if(rv instanceof FloatConstant)
495       {
496         rop = hierarchy.typeNode(FloatType.v());
497       }
498     else if(rv instanceof IntConstant)
499       {
500         rop = hierarchy.typeNode(IntType.v());
501       }
502     else if(rv instanceof LongConstant)
503       {
504         rop = hierarchy.typeNode(LongType.v());
505       }
506     else if(rv instanceof NullConstant)
507       {
508         rop = hierarchy.typeNode(NullType.v());
509       }
510     else if(rv instanceof StringConstant)
511       {
512         rop = hierarchy.typeNode(RefType.v("java.lang.String"));
513       }
514     else if(rv instanceof ClassConstant)
515       {
516         rop = hierarchy.typeNode(RefType.v("java.lang.Class"));
517       }
518     else
519       {
520         throw new RuntimeException JavaDoc("Unhandled binary expression right operand type: " + rv.getClass());
521       }
522     
523     if((be instanceof AddExpr) ||
524        (be instanceof SubExpr) ||
525        (be instanceof MulExpr) ||
526        (be instanceof DivExpr) ||
527        (be instanceof RemExpr) ||
528        (be instanceof AndExpr) ||
529        (be instanceof OrExpr) ||
530        (be instanceof XorExpr))
531       {
532         if(!(left.hasDescendantOrSelf(lop) &&
533          left.hasDescendantOrSelf(rop)))
534           {
535         error("Type Error(27)");
536           }
537       }
538     else if((be instanceof ShlExpr) ||
539         (be instanceof ShrExpr) ||
540         (be instanceof UshrExpr))
541       {
542         if(!(left.hasDescendantOrSelf(lop) &&
543          hierarchy.typeNode(IntType.v()).hasAncestorOrSelf(rop)))
544           {
545         error("Type Error(28)");
546           }
547       }
548     else if((be instanceof CmpExpr) ||
549         (be instanceof CmpgExpr) ||
550         (be instanceof CmplExpr) ||
551         (be instanceof EqExpr) ||
552         (be instanceof GeExpr) ||
553         (be instanceof GtExpr) ||
554         (be instanceof LeExpr) ||
555         (be instanceof LtExpr) ||
556         (be instanceof NeExpr))
557       {
558         try
559           {
560         lop.lca(rop);
561           }
562         catch(TypeException e)
563           {
564         error(e.getMessage());
565           }
566
567         if(!left.hasDescendantOrSelf(hierarchy.typeNode(IntType.v())))
568           {
569         error("Type Error(29)");
570           }
571       }
572     else
573       {
574         throw new RuntimeException JavaDoc("Unhandled binary expression type: " + be.getClass());
575       }
576       }
577     else if(r instanceof CastExpr)
578       {
579     CastExpr ce = (CastExpr) r;
580     TypeNode cast = hierarchy.typeNode(ce.getCastType());
581     if(ce.getOp() instanceof Local)
582     {
583       TypeNode op = hierarchy.typeNode(((Local) ce.getOp()).getType());
584
585       try
586         {
587           // we must be careful not to reject primitive type casts (e.g. int to long)
588
if(cast.isClassOrInterface() || op.isClassOrInterface())
589             {
590           cast.lca(op);
591             }
592         }
593       catch(TypeException e)
594         {
595           G.v().out.println(r + "[" + op + "<->" + cast + "]");
596           error(e.getMessage());
597         }
598     }
599
600     if(!left.hasDescendantOrSelf(cast))
601       {
602         error("Type Error(30)");
603       }
604       }
605     else if(r instanceof InstanceOfExpr)
606       {
607     InstanceOfExpr ioe = (InstanceOfExpr) r;
608     TypeNode type = hierarchy.typeNode(ioe.getCheckType());
609     TypeNode op = hierarchy.typeNode(ioe.getOp().getType());
610     
611     try
612       {
613         op.lca(type);
614       }
615     catch(TypeException e)
616       {
617         G.v().out.println(r + "[" + op + "<->" + type + "]");
618         error(e.getMessage());
619       }
620     
621     if(!left.hasDescendantOrSelf(hierarchy.typeNode(IntType.v())))
622       {
623         error("Type Error(31)");
624       }
625       }
626     else if(r instanceof InvokeExpr)
627       {
628     InvokeExpr ie = (InvokeExpr) r;
629
630     handleInvokeExpr(ie, stmt);
631
632     if(!left.hasDescendantOrSelf(hierarchy.typeNode(ie.getMethodRef().returnType())))
633       {
634         error("Type Error(32)");
635       }
636       }
637     else if(r instanceof NewArrayExpr)
638       {
639     NewArrayExpr nae = (NewArrayExpr) r;
640
641     Type baseType = nae.getBaseType();
642     TypeNode right;
643
644     if(baseType instanceof ArrayType)
645       {
646         right = hierarchy.typeNode(ArrayType.v(((ArrayType) baseType).baseType,
647                               ((ArrayType) baseType).numDimensions + 1));
648       }
649     else
650       {
651         right = hierarchy.typeNode(ArrayType.v(baseType, 1));
652       }
653
654     if(!left.hasDescendantOrSelf(right))
655       {
656         error("Type Error(33)");
657       }
658
659
660     Value size = nae.getSize();
661     if(size instanceof Local)
662       {
663         TypeNode var = hierarchy.typeNode(((Local) size).getType());
664
665         if(!var.hasAncestorOrSelf(hierarchy.typeNode(IntType.v())))
666           {
667         error("Type Error(34)");
668           }
669       }
670       }
671     else if(r instanceof NewExpr)
672       {
673     NewExpr ne = (NewExpr) r;
674
675     if(!left.hasDescendantOrSelf(hierarchy.typeNode(ne.getBaseType())))
676       {
677         error("Type Error(35)");
678       }
679       }
680     else if(r instanceof NewMultiArrayExpr)
681       {
682     NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
683
684     if(!left.hasDescendantOrSelf(hierarchy.typeNode(nmae.getBaseType())))
685       {
686         error("Type Error(36)");
687       }
688
689     for(int i = 0; i < nmae.getSizeCount(); i++)
690       {
691         Value size = nmae.getSize(i);
692         if(size instanceof Local)
693           {
694         TypeNode var = hierarchy.typeNode(((Local) size).getType());
695
696         if(!var.hasAncestorOrSelf(hierarchy.typeNode(IntType.v())))
697           {
698             error("Type Error(37)");
699           }
700           }
701       }
702       }
703     else if(r instanceof LengthExpr)
704       {
705     LengthExpr le = (LengthExpr) r;
706
707     if(!left.hasDescendantOrSelf(hierarchy.typeNode(IntType.v())))
708       {
709         error("Type Error(38)");
710       }
711
712     if(le.getOp() instanceof Local)
713       {
714         if(!hierarchy.typeNode(((Local) le.getOp()).getType()).isArray())
715           {
716         error("Type Error(39)");
717           }
718       }
719       }
720     else if(r instanceof NegExpr)
721       {
722     NegExpr ne = (NegExpr) r;
723     TypeNode right;
724
725     if(ne.getOp() instanceof Local)
726       {
727         right = hierarchy.typeNode(((Local) ne.getOp()).getType());
728       }
729     else if(ne.getOp() instanceof DoubleConstant)
730       {
731         right = hierarchy.typeNode(DoubleType.v());
732       }
733     else if(ne.getOp() instanceof FloatConstant)
734       {
735         right = hierarchy.typeNode(FloatType.v());
736       }
737     else if(ne.getOp() instanceof IntConstant)
738       {
739         right = hierarchy.typeNode(IntType.v());
740       }
741     else if(ne.getOp() instanceof LongConstant)
742       {
743         right = hierarchy.typeNode(LongType.v());
744       }
745     else
746       {
747         throw new RuntimeException JavaDoc("Unhandled neg expression operand type: " + ne.getOp().getClass());
748       }
749     
750     if(!left.hasDescendantOrSelf(right))
751       {
752         error("Type Error(40)");
753       }
754       }
755     else if(r instanceof Local)
756       {
757     if(!left.hasDescendantOrSelf(hierarchy.typeNode(((Local) r).getType())))
758       {
759         if(fix)
760           {
761         stmt.setRightOp(insertCast((Local) r, left.type(), stmt));
762           }
763         else
764           {
765         error("Type Error(41)");
766           }
767       }
768       }
769     else if(r instanceof InstanceFieldRef)
770       {
771     InstanceFieldRef ref = (InstanceFieldRef) r;
772
773     TypeNode baseType = hierarchy.typeNode(((Local) ref.getBase()).getType());
774     if(!baseType.hasAncestorOrSelf(hierarchy.typeNode(ref.getField().getDeclaringClass().getType())))
775       {
776         if(fix)
777           {
778         ref.setBase(insertCast((Local) ref.getBase(), ref.getField().getDeclaringClass().getType(), stmt));
779           }
780         else
781           {
782         error("Type Error(42)");
783           }
784       }
785     
786     if(!left.hasDescendantOrSelf(hierarchy.typeNode(ref.getField().getType())))
787       {
788         error("Type Error(43)");
789       }
790       }
791     else if(r instanceof StaticFieldRef)
792       {
793     StaticFieldRef ref = (StaticFieldRef) r;
794
795     if(!left.hasDescendantOrSelf(hierarchy.typeNode(ref.getField().getType())))
796       {
797         error("Type Error(44)");
798       }
799       }
800     else
801       {
802     throw new RuntimeException JavaDoc("Unhandled assignment right hand side type: " + r.getClass());
803       }
804   }
805
806   public void caseIdentityStmt(IdentityStmt stmt)
807   {
808     TypeNode left = hierarchy.typeNode(((Local) stmt.getLeftOp()).getType());
809
810     Value r = stmt.getRightOp();
811
812     if(!(r instanceof CaughtExceptionRef))
813       {
814     TypeNode right = hierarchy.typeNode(r.getType());
815     if(!left.hasDescendantOrSelf(right))
816       {
817         error("Type Error(46) [" + left + " <- " + right + "]");
818       }
819       }
820     else
821       {
822     List exceptionTypes = TrapManager.getExceptionTypesOf(stmt, stmtBody);
823     Iterator typeIt = exceptionTypes.iterator();
824     
825     while(typeIt.hasNext())
826       {
827         Type t = (Type) typeIt.next();
828         
829         if(!left.hasDescendantOrSelf(hierarchy.typeNode(t)))
830           {
831         error("Type Error(47)");
832           }
833       }
834     
835     if(!left.hasAncestorOrSelf(hierarchy.typeNode(RefType.v("java.lang.Throwable"))))
836       {
837         error("Type Error(48)");
838       }
839       }
840   }
841
842   public void caseEnterMonitorStmt(EnterMonitorStmt stmt)
843   {
844     if(stmt.getOp() instanceof Local)
845       {
846     TypeNode op = hierarchy.typeNode(((Local) stmt.getOp()).getType());
847     
848     if(!op.hasAncestorOrSelf(hierarchy.typeNode(RefType.v("java.lang.Object"))))
849       {
850         error("Type Error(49)");
851       }
852       }
853   }
854
855   public void caseExitMonitorStmt(ExitMonitorStmt stmt)
856   {
857     if(stmt.getOp() instanceof Local)
858       {
859     TypeNode op = hierarchy.typeNode(((Local) stmt.getOp()).getType());
860     
861     if(!op.hasAncestorOrSelf(hierarchy.typeNode(RefType.v("java.lang.Object"))))
862       {
863         error("Type Error(49)");
864       }
865       }
866   }
867
868   public void caseGotoStmt(GotoStmt stmt)
869   {
870   }
871
872   public void caseIfStmt(IfStmt stmt)
873   {
874     ConditionExpr cond = (ConditionExpr) stmt.getCondition();
875     
876     BinopExpr expr = (BinopExpr) cond;
877     Value lv = expr.getOp1();
878     Value rv = expr.getOp2();
879     
880     TypeNode lop;
881     TypeNode rop;
882     
883     //******** LEFT ********
884
if(lv instanceof Local)
885       {
886     lop = hierarchy.typeNode(((Local) lv).getType());
887       }
888     else if(lv instanceof DoubleConstant)
889       {
890     lop = hierarchy.typeNode(DoubleType.v());
891       }
892     else if(lv instanceof FloatConstant)
893       {
894     lop = hierarchy.typeNode(FloatType.v());
895       }
896     else if(lv instanceof IntConstant)
897       {
898     lop = hierarchy.typeNode(IntType.v());
899       }
900     else if(lv instanceof LongConstant)
901       {
902     lop = hierarchy.typeNode(LongType.v());
903       }
904     else if(lv instanceof NullConstant)
905       {
906     lop = hierarchy.typeNode(NullType.v());
907       }
908     else if(lv instanceof StringConstant)
909       {
910     lop = hierarchy.typeNode(RefType.v("java.lang.String"));
911       }
912     else if(lv instanceof ClassConstant)
913       {
914     lop = hierarchy.typeNode(RefType.v("java.lang.Class"));
915       }
916     else
917       {
918     throw new RuntimeException JavaDoc("Unhandled binary expression left operand type: " + lv.getClass());
919       }
920     
921     //******** RIGHT ********
922
if(rv instanceof Local)
923       {
924     rop = hierarchy.typeNode(((Local) rv).getType());
925       }
926     else if(rv instanceof DoubleConstant)
927       {
928     rop = hierarchy.typeNode(DoubleType.v());
929       }
930     else if(rv instanceof FloatConstant)
931       {
932     rop = hierarchy.typeNode(FloatType.v());
933       }
934     else if(rv instanceof IntConstant)
935       {
936     rop = hierarchy.typeNode(IntType.v());
937       }
938     else if(rv instanceof LongConstant)
939       {
940     rop = hierarchy.typeNode(LongType.v());
941       }
942     else if(rv instanceof NullConstant)
943       {
944     rop = hierarchy.typeNode(NullType.v());
945       }
946     else if(rv instanceof StringConstant)
947       {
948     rop = hierarchy.typeNode(RefType.v("java.lang.String"));
949       }
950     else if(rv instanceof ClassConstant)
951       {
952     rop = hierarchy.typeNode(RefType.v("java.lang.Class"));
953       }
954     else
955       {
956     throw new RuntimeException JavaDoc("Unhandled binary expression right operand type: " + rv.getClass());
957       }
958     
959     try
960       {
961     lop.lca(rop);
962       }
963     catch(TypeException e)
964       {
965     error(e.getMessage());
966       }
967   }
968
969   public void caseLookupSwitchStmt(LookupSwitchStmt stmt)
970   {
971     Value key = stmt.getKey();
972
973     if(key instanceof Local)
974       {
975     if(!hierarchy.typeNode(((Local) key).getType()).hasAncestorOrSelf(hierarchy.typeNode(IntType.v())))
976       {
977         error("Type Error(50)");
978       }
979       }
980   }
981
982   public void caseNopStmt(NopStmt stmt)
983   {
984   }
985
986   public void caseReturnStmt(ReturnStmt stmt)
987   {
988     if(stmt.getOp() instanceof Local)
989       {
990     if(!hierarchy.typeNode(((Local) stmt.getOp()).getType()).
991        hasAncestorOrSelf(hierarchy.typeNode(stmtBody.getMethod().getReturnType())))
992       {
993         if(fix)
994           {
995         stmt.setOp(insertCast((Local) stmt.getOp(), stmtBody.getMethod().getReturnType(), stmt));
996           }
997         else
998           {
999         error("Type Error(51)");
1000          }
1001      }
1002      }
1003  }
1004
1005  public void caseReturnVoidStmt(ReturnVoidStmt stmt)
1006  {
1007  }
1008
1009  public void caseTableSwitchStmt(TableSwitchStmt stmt)
1010  {
1011    Value key = stmt.getKey();
1012
1013    if(key instanceof Local)
1014      {
1015    if(!hierarchy.typeNode(((Local) key).getType()).hasAncestorOrSelf(hierarchy.typeNode(IntType.v())))
1016      {
1017        error("Type Error(52)");
1018      }
1019      }
1020  }
1021
1022  public void caseThrowStmt(ThrowStmt stmt)
1023  {
1024    if(stmt.getOp() instanceof Local)
1025      {
1026    TypeNode op = hierarchy.typeNode(((Local) stmt.getOp()).getType());
1027        
1028    if(!op.hasAncestorOrSelf(hierarchy.typeNode(RefType.v("java.lang.Throwable"))))
1029      {
1030        if(fix)
1031          {
1032        stmt.setOp(insertCast((Local) stmt.getOp(), RefType.v("java.lang.Throwable"), stmt));
1033          }
1034        else
1035          {
1036        error("Type Error(53)");
1037          }
1038      }
1039      }
1040  }
1041
1042  public void defaultCase(Stmt stmt)
1043  {
1044    throw new RuntimeException JavaDoc("Unhandled statement type: " + stmt.getClass());
1045  }
1046
1047  private Local insertCast(Local oldlocal, Type type, Stmt stmt)
1048  {
1049    Local newlocal = Jimple.v().newLocal("tmp", type);
1050    stmtBody.getLocals().add(newlocal);
1051    
1052    stmtBody.getUnits().insertBefore(Jimple.v().newAssignStmt(newlocal, Jimple.v().newCastExpr(oldlocal, type)), stmt);
1053    return newlocal;
1054  }
1055}
1056
Popular Tags