KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > toolkits > typing > integer > ConstraintChecker


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.integer;
28
29 import soot.*;
30 import soot.jimple.*;
31 import soot.util.*;
32 import java.util.*;
33 import java.io.*;
34
35 class ConstraintChecker extends AbstractStmtSwitch
36 {
37   private final TypeResolver resolver;
38   private final boolean fix; // if true, fix constraint violations
39

40   private JimpleBody stmtBody;
41
42   public ConstraintChecker(TypeResolver resolver, boolean fix)
43   {
44     this.resolver = resolver;
45     this.fix = fix;
46   }
47
48   public void check(Stmt stmt, JimpleBody stmtBody) throws TypeException
49   {
50     try
51       {
52     this.stmtBody = stmtBody;
53     stmt.apply(this);
54       }
55     catch(RuntimeTypeException e)
56       {
57          StringWriter st = new StringWriter();
58          PrintWriter pw = new PrintWriter(st);
59      e.printStackTrace(pw);
60      pw.close();
61          throw new TypeException(st.toString());
62       }
63   }
64
65   private static class RuntimeTypeException extends RuntimeException JavaDoc
66   {
67     RuntimeTypeException(String JavaDoc message)
68     {
69       super(message);
70     }
71   }
72
73   static void error(String JavaDoc message)
74   {
75     throw new RuntimeTypeException(message);
76   }
77
78   private void handleInvokeExpr(InvokeExpr ie, Stmt invokestmt)
79   {
80     if(ie instanceof InterfaceInvokeExpr)
81       {
82     InterfaceInvokeExpr invoke = (InterfaceInvokeExpr) ie;
83     SootMethodRef method = invoke.getMethodRef();
84     int count = invoke.getArgCount();
85     
86     for(int i = 0; i < count; i++)
87       {
88         if(invoke.getArg(i) instanceof Local)
89           {
90         Local local = (Local) invoke.getArg(i);
91         
92         if(local.getType() instanceof IntegerType)
93           {
94             if(!ClassHierarchy.v().typeNode(local.getType()).
95                hasAncestor_1(ClassHierarchy.v().typeNode(method.parameterType(i))))
96               {
97             if(fix)
98               {
99                 invoke.setArg(i, insertCast(local, method.parameterType(i), invokestmt));
100               }
101             else
102               {
103                 error("Type Error(1)");
104               }
105               }
106           }
107           }
108       }
109       }
110     else if(ie instanceof SpecialInvokeExpr)
111       {
112     SpecialInvokeExpr invoke = (SpecialInvokeExpr) ie;
113     SootMethodRef method = invoke.getMethodRef();
114     int count = invoke.getArgCount();
115     
116     for(int i = 0; i < count; i++)
117       {
118         if(invoke.getArg(i) instanceof Local)
119           {
120         Local local = (Local) invoke.getArg(i);
121         
122         if(local.getType() instanceof IntegerType)
123           {
124             if(!ClassHierarchy.v().typeNode(local.getType()).
125                hasAncestor_1(ClassHierarchy.v().typeNode(method.parameterType(i))))
126               {
127             if(fix)
128               {
129                 invoke.setArg(i, insertCast(local, method.parameterType(i), invokestmt));
130               }
131             else
132               {
133                 error("Type Error(2)");
134               }
135               }
136           }
137           }
138       }
139       }
140     else if(ie instanceof VirtualInvokeExpr)
141       {
142     VirtualInvokeExpr invoke = (VirtualInvokeExpr) ie;
143     SootMethodRef method = invoke.getMethodRef();
144     int count = invoke.getArgCount();
145     
146     for(int i = 0; i < count; i++)
147       {
148         if(invoke.getArg(i) instanceof Local)
149           {
150         Local local = (Local) invoke.getArg(i);
151         
152         if(local.getType() instanceof IntegerType)
153           {
154             if(!ClassHierarchy.v().typeNode(local.getType()).
155                hasAncestor_1(ClassHierarchy.v().typeNode(method.parameterType(i))))
156               {
157             if(fix)
158               {
159                 invoke.setArg(i, insertCast(local, method.parameterType(i), invokestmt));
160               }
161             else
162               {
163                 error("Type Error(3)");
164               }
165               }
166           }
167           }
168       }
169       }
170     else if(ie instanceof StaticInvokeExpr)
171       {
172     StaticInvokeExpr invoke = (StaticInvokeExpr) ie;
173     SootMethodRef method = invoke.getMethodRef();
174     int count = invoke.getArgCount();
175     
176     for(int i = 0; i < count; i++)
177       {
178         if(invoke.getArg(i) instanceof Local)
179           {
180         Local local = (Local) invoke.getArg(i);
181         
182         if(local.getType() instanceof IntegerType)
183           {
184             if(!ClassHierarchy.v().typeNode(local.getType()).
185                hasAncestor_1(ClassHierarchy.v().typeNode(method.parameterType(i))))
186               {
187             if(fix)
188               {
189                 invoke.setArg(i, insertCast(local, method.parameterType(i), invokestmt));
190               }
191             else
192               {
193                 error("Type Error(4)");
194               }
195               }
196           }
197           }
198       }
199       }
200     else
201       {
202     throw new RuntimeException JavaDoc("Unhandled invoke expression type: " + ie.getClass());
203       }
204   }
205
206   public void caseBreakpointStmt(BreakpointStmt stmt)
207   {
208     // Do nothing
209
}
210
211   public void caseInvokeStmt(InvokeStmt stmt)
212   {
213     handleInvokeExpr((InvokeExpr) stmt.getInvokeExpr(), stmt);
214   }
215
216   public void caseAssignStmt(AssignStmt stmt)
217   {
218     Value l = stmt.getLeftOp();
219     Value r = stmt.getRightOp();
220
221     TypeNode left = null;
222     TypeNode right = null;
223
224     //******** LEFT ********
225

226     if(l instanceof ArrayRef)
227       {
228     ArrayRef ref = (ArrayRef) l;
229     Type baset = ((Local) ref.getBase()).getType();
230     if(!(baset instanceof NullType))
231     {
232       ArrayType base = (ArrayType) baset;
233       Value index = ref.getIndex();
234     
235       if((base.numDimensions == 1) &&
236          (base.baseType instanceof IntegerType))
237         {
238           left = ClassHierarchy.v().typeNode(base.baseType);
239         }
240     
241       if(index instanceof Local)
242         {
243           if(!ClassHierarchy.v().typeNode(((Local) index).getType()).hasAncestor_1(ClassHierarchy.v().INT))
244             {
245           if(fix)
246             {
247               ref.setIndex(insertCast((Local) index, IntType.v(), stmt));
248             }
249           else
250             {
251               error("Type Error(5)");
252             }
253             }
254         }
255         }
256       }
257     else if(l instanceof Local)
258       {
259     if(((Local) l).getType() instanceof IntegerType)
260       {
261         left = ClassHierarchy.v().typeNode(((Local) l).getType());
262       }
263       }
264     else if(l instanceof InstanceFieldRef)
265       {
266     InstanceFieldRef ref = (InstanceFieldRef) l;
267     
268     if(ref.getField().getType() instanceof IntegerType)
269       {
270         left = ClassHierarchy.v().typeNode( ref.getField().getType());
271       }
272       }
273     else if(l instanceof StaticFieldRef)
274       {
275     StaticFieldRef ref = (StaticFieldRef) l;
276
277     if(ref.getField().getType() instanceof IntegerType)
278       {
279         left = ClassHierarchy.v().typeNode(ref.getField().getType());
280       }
281       }
282     else
283       {
284     throw new RuntimeException JavaDoc("Unhandled assignment left hand side type: " + l.getClass());
285       }
286
287     //******** RIGHT ********
288

289     if(r instanceof ArrayRef)
290       {
291     ArrayRef ref = (ArrayRef) r;
292     Type baset = ((Local) ref.getBase()).getType();
293     if(!(baset instanceof NullType))
294     {
295       ArrayType base = (ArrayType) baset;
296       Value index = ref.getIndex();
297     
298       if((base.numDimensions == 1) &&
299          (base.baseType instanceof IntegerType))
300         {
301           right = ClassHierarchy.v().typeNode(base.baseType);
302         }
303     
304       if(index instanceof Local)
305         {
306           if(!ClassHierarchy.v().typeNode(((Local) index).getType()).hasAncestor_1(ClassHierarchy.v().INT))
307             {
308           if(fix)
309             {
310               ref.setIndex(insertCast((Local) index, IntType.v(), stmt));
311             }
312           else
313             {
314               error("Type Error(6)");
315             }
316             }
317         }
318     }
319       }
320     else if(r instanceof DoubleConstant)
321       {
322       }
323     else if(r instanceof FloatConstant)
324       {
325       }
326     else if(r instanceof IntConstant)
327       {
328     int value = ((IntConstant) r).value;
329     
330     if(value < -32768)
331       {
332         right = ClassHierarchy.v().INT;
333       }
334     else if(value < -128)
335       {
336         right = ClassHierarchy.v().SHORT;
337       }
338     else if(value < 0)
339       {
340         right = ClassHierarchy.v().BYTE;
341       }
342     else if(value < 2)
343       {
344         right = ClassHierarchy.v().R0_1;
345       }
346     else if(value < 128)
347       {
348         right = ClassHierarchy.v().R0_127;
349       }
350     else if(value < 32768)
351       {
352         right = ClassHierarchy.v().R0_32767;
353       }
354     else if(value < 65536)
355       {
356         right = ClassHierarchy.v().CHAR;
357       }
358     else
359       {
360         right = ClassHierarchy.v().INT;
361       }
362       }
363     else if(r instanceof LongConstant)
364       {
365       }
366     else if(r instanceof NullConstant)
367       {
368       }
369     else if(r instanceof StringConstant)
370       {
371       }
372     else if(r instanceof ClassConstant)
373       {
374       }
375     else if(r instanceof BinopExpr)
376       {
377     //******** BINOP EXPR ********
378

379     BinopExpr be = (BinopExpr) r;
380
381     Value lv = be.getOp1();
382     Value rv = be.getOp2();
383     
384     TypeNode lop = null;
385     TypeNode rop = null;
386
387     //******** LEFT ********
388
if(lv instanceof Local)
389       {
390         if(((Local) lv).getType() instanceof IntegerType)
391           {
392         lop = ClassHierarchy.v().typeNode(((Local) lv).getType());
393           }
394       }
395     else if(lv instanceof DoubleConstant)
396       {
397       }
398     else if(lv instanceof FloatConstant)
399       {
400       }
401     else if(lv instanceof IntConstant)
402       {
403         int value = ((IntConstant) lv).value;
404         
405         if(value < -32768)
406           {
407         lop = ClassHierarchy.v().INT;
408           }
409         else if(value < -128)
410           {
411         lop = ClassHierarchy.v().SHORT;
412           }
413         else if(value < 0)
414           {
415         lop = ClassHierarchy.v().BYTE;
416           }
417         else if(value < 2)
418           {
419         lop = ClassHierarchy.v().R0_1;
420           }
421         else if(value < 128)
422           {
423         lop = ClassHierarchy.v().R0_127;
424           }
425         else if(value < 32768)
426           {
427         lop = ClassHierarchy.v().R0_32767;
428           }
429         else if(value < 65536)
430           {
431         lop = ClassHierarchy.v().CHAR;
432           }
433         else
434           {
435         lop = ClassHierarchy.v().INT;
436           }
437       }
438     else if(lv instanceof LongConstant)
439       {
440       }
441     else if(lv instanceof NullConstant)
442       {
443       }
444     else if(lv instanceof StringConstant)
445       {
446       }
447     else if(lv instanceof ClassConstant)
448       {
449       }
450     else
451       {
452         throw new RuntimeException JavaDoc("Unhandled binary expression left operand type: " + lv.getClass());
453       }
454     
455     //******** RIGHT ********
456
if(rv instanceof Local)
457       {
458         if(((Local) rv).getType() instanceof IntegerType)
459           {
460         rop = ClassHierarchy.v().typeNode(((Local) rv).getType());
461           }
462       }
463     else if(rv instanceof DoubleConstant)
464       {
465       }
466     else if(rv instanceof FloatConstant)
467       {
468       }
469     else if(rv instanceof IntConstant)
470       {
471         int value = ((IntConstant) rv).value;
472         
473         if(value < -32768)
474           {
475         rop = ClassHierarchy.v().INT;
476           }
477         else if(value < -128)
478           {
479         rop = ClassHierarchy.v().SHORT;
480           }
481         else if(value < 0)
482           {
483         rop = ClassHierarchy.v().BYTE;
484           }
485         else if(value < 2)
486           {
487         rop = ClassHierarchy.v().R0_1;
488           }
489         else if(value < 128)
490           {
491         rop = ClassHierarchy.v().R0_127;
492           }
493         else if(value < 32768)
494           {
495         rop = ClassHierarchy.v().R0_32767;
496           }
497         else if(value < 65536)
498           {
499         rop = ClassHierarchy.v().CHAR;
500           }
501         else
502           {
503         rop = ClassHierarchy.v().INT;
504           }
505       }
506     else if(rv instanceof LongConstant)
507       {
508       }
509     else if(rv instanceof NullConstant)
510       {
511       }
512     else if(rv instanceof StringConstant)
513       {
514       }
515     else if(rv instanceof ClassConstant)
516       {
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       {
529         if(lop != null && rop != null)
530           {
531         if(!lop.hasAncestor_1(ClassHierarchy.v().INT))
532           {
533             if(fix)
534               {
535             be.setOp1(insertCast(be.getOp1(), lop.type(), IntType.v(), stmt));
536               }
537             else
538               {
539             error("Type Error(7)");
540               }
541           }
542
543         if(!rop.hasAncestor_1(ClassHierarchy.v().INT))
544           {
545             if(fix)
546               {
547             be.setOp2(insertCast(be.getOp2(), rop.type(), IntType.v(), stmt));
548               }
549             else
550               {
551             error("Type Error(8)");
552               }
553           }
554           }
555         
556         right = ClassHierarchy.v().INT;
557       }
558     else if((be instanceof AndExpr) ||
559         (be instanceof OrExpr) ||
560         (be instanceof XorExpr))
561       {
562         if(lop != null && rop != null)
563           {
564         TypeNode lca = lop.lca_1(rop);
565         
566         if(lca == ClassHierarchy.v().TOP)
567           {
568             if(fix)
569               {
570             if(!lop.hasAncestor_1(ClassHierarchy.v().INT))
571               {
572                 be.setOp1(insertCast(be.getOp1(), lop.type(), rop.type(), stmt));
573                 lca = rop;
574               }
575             
576             if(!rop.hasAncestor_1(ClassHierarchy.v().INT))
577               {
578                 be.setOp2(insertCast(be.getOp2(), rop.type(), lop.type(), stmt));
579                 lca = lop;
580               }
581               }
582             else
583               {
584             error("Type Error(11)");
585               }
586           }
587         
588         right = lca;
589           }
590       }
591     else if(be instanceof ShlExpr)
592       {
593         if(lop != null)
594           {
595         if(!lop.hasAncestor_1(ClassHierarchy.v().INT))
596           {
597             if(fix)
598               {
599             be.setOp1(insertCast(be.getOp1(), lop.type(), IntType.v(), stmt));
600               }
601             else
602               {
603             error("Type Error(9)");
604               }
605           }
606           }
607         
608         if(!rop.hasAncestor_1(ClassHierarchy.v().INT))
609           {
610         if(fix)
611           {
612             be.setOp2(insertCast(be.getOp2(), rop.type(), IntType.v(), stmt));
613           }
614         else
615           {
616             error("Type Error(10)");
617           }
618           }
619         
620         right = (lop == null) ? null : ClassHierarchy.v().INT;
621       }
622     else if((be instanceof ShrExpr) ||
623         (be instanceof UshrExpr))
624       {
625         if(lop != null)
626           {
627         if(!lop.hasAncestor_1(ClassHierarchy.v().INT))
628           {
629             if(fix)
630               {
631             be.setOp1(insertCast(be.getOp1(), lop.type(), ByteType.v(), stmt));
632             lop = ClassHierarchy.v().BYTE;
633               }
634             else
635               {
636             error("Type Error(9)");
637               }
638           }
639           }
640         
641         if(!rop.hasAncestor_1(ClassHierarchy.v().INT))
642           {
643         if(fix)
644           {
645             be.setOp2(insertCast(be.getOp2(), rop.type(), IntType.v(), stmt));
646           }
647         else
648           {
649             error("Type Error(10)");
650           }
651           }
652
653         right = lop;
654       }
655     else if((be instanceof CmpExpr) ||
656         (be instanceof CmpgExpr) ||
657         (be instanceof CmplExpr))
658       {
659         right = ClassHierarchy.v().BYTE;
660       }
661     else if((be instanceof EqExpr) ||
662         (be instanceof GeExpr) ||
663         (be instanceof GtExpr) ||
664         (be instanceof LeExpr) ||
665         (be instanceof LtExpr) ||
666         (be instanceof NeExpr))
667       {
668         TypeNode lca = lop.lca_1(rop);
669         
670         if(lca == ClassHierarchy.v().TOP)
671           {
672         if(fix)
673           {
674             if(!lop.hasAncestor_1(ClassHierarchy.v().INT))
675               {
676             be.setOp1(insertCast(be.getOp1(), lop.type(), rop.type(), stmt));
677               }
678             
679             if(!rop.hasAncestor_1(ClassHierarchy.v().INT))
680               {
681             be.setOp2(insertCast(be.getOp2(), rop.type(), lop.type(), stmt));
682               }
683           }
684         else
685           {
686             error("Type Error(11)");
687           }
688           }
689         
690         right = ClassHierarchy.v().BOOLEAN;
691       }
692     else
693       {
694         throw new RuntimeException JavaDoc("Unhandled binary expression type: " + be.getClass());
695       }
696       }
697     else if(r instanceof CastExpr)
698       {
699     CastExpr ce = (CastExpr) r;
700
701     if(ce.getCastType() instanceof IntegerType)
702       {
703         right = ClassHierarchy.v().typeNode(ce.getCastType());
704       }
705       }
706     else if(r instanceof InstanceOfExpr)
707       {
708     InstanceOfExpr ioe = (InstanceOfExpr) r;
709
710     right = ClassHierarchy.v().BOOLEAN;
711       }
712     else if(r instanceof InvokeExpr)
713       {
714     InvokeExpr ie = (InvokeExpr) r;
715
716     handleInvokeExpr(ie, stmt);
717     
718     if(ie.getMethodRef().returnType() instanceof IntegerType)
719       {
720         right = ClassHierarchy.v().typeNode(ie.getMethodRef().returnType());
721       }
722       }
723     else if(r instanceof NewArrayExpr)
724       {
725     NewArrayExpr nae = (NewArrayExpr) r;
726     Value size = nae.getSize();
727
728     if(size instanceof Local)
729       {
730         if(!ClassHierarchy.v().typeNode(((Local) size).getType()).
731            hasAncestor_1(ClassHierarchy.v().INT))
732           {
733         if(fix)
734           {
735             nae.setSize(insertCast((Local) size, IntType.v(), stmt));
736           }
737         else
738           {
739             error("Type Error(12)");
740           }
741           }
742       }
743       }
744     else if(r instanceof NewExpr)
745       {
746       }
747     else if(r instanceof NewMultiArrayExpr)
748       {
749     NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
750
751     for(int i = 0; i < nmae.getSizeCount(); i++)
752       {
753         Value size = nmae.getSize(i);
754
755         if(size instanceof Local)
756           {
757         if(!ClassHierarchy.v().typeNode(((Local) size).getType()).
758            hasAncestor_1(ClassHierarchy.v().INT))
759           {
760             if(fix)
761               {
762             nmae.setSize(i, insertCast((Local) size, IntType.v(), stmt));
763               }
764             else
765               {
766             error("Type Error(13)");
767               }
768           }
769           }
770       }
771       }
772     else if(r instanceof LengthExpr)
773       {
774     LengthExpr le = (LengthExpr) r;
775
776     right = ClassHierarchy.v().INT;
777       }
778     else if(r instanceof NegExpr)
779       {
780     NegExpr ne = (NegExpr) r;
781
782     if(ne.getOp() instanceof Local)
783       {
784         Local local = (Local) ne.getOp();
785
786         if(local.getType() instanceof IntegerType)
787           {
788         TypeNode ltype = ClassHierarchy.v().typeNode(local.getType());
789         if(!ltype.hasAncestor_1(ClassHierarchy.v().INT))
790           {
791             if(fix)
792               {
793             ne.setOp(insertCast(local, IntType.v(), stmt));
794             ltype = ClassHierarchy.v().BYTE;
795               }
796             else
797               {
798             error("Type Error(14)");
799               }
800           }
801
802         right = (ltype == ClassHierarchy.v().CHAR) ? ClassHierarchy.v().INT : ltype;
803           }
804       }
805     else if(ne.getOp() instanceof DoubleConstant)
806       {
807       }
808     else if(ne.getOp() instanceof FloatConstant)
809       {
810       }
811     else if(ne.getOp() instanceof IntConstant)
812       {
813         right = ClassHierarchy.v().INT;
814       }
815     else if(ne.getOp() instanceof LongConstant)
816       {
817       }
818     else
819       {
820         throw new RuntimeException JavaDoc("Unhandled neg expression operand type: " + ne.getOp().getClass());
821       }
822       }
823     else if(r instanceof Local)
824       {
825     Local local = (Local) r;
826     
827     if(local.getType() instanceof IntegerType)
828       {
829         right = ClassHierarchy.v().typeNode(local.getType());
830       }
831       }
832     else if(r instanceof InstanceFieldRef)
833       {
834     InstanceFieldRef ref = (InstanceFieldRef) r;
835
836     if(ref.getField().getType() instanceof IntegerType)
837       {
838         right = ClassHierarchy.v().typeNode(ref.getField().getType());
839       }
840       }
841     else if(r instanceof StaticFieldRef)
842       {
843     StaticFieldRef ref = (StaticFieldRef) r;
844
845     if(ref.getField().getType() instanceof IntegerType)
846       {
847         right = ClassHierarchy.v().typeNode(ref.getField().getType());
848       }
849       }
850     else
851       {
852     throw new RuntimeException JavaDoc("Unhandled assignment right hand side type: " + r.getClass());
853       }
854
855     if(left != null && right != null)
856       {
857     if(!right.hasAncestor_1(left))
858       {
859         if(fix)
860           {
861         stmt.setRightOp(insertCast(stmt.getRightOp(), getTypeForCast(right), getTypeForCast(left), stmt));
862           }
863         else
864           {
865         error("Type Error(15)");
866           }
867       }
868       }
869   }
870
871   static Type getTypeForCast(TypeNode node)
872       // This method is a local kludge, for avoiding NullPointerExceptions
873
// when a R0_1, R0_127, or R0_32767 node is used in a type
874
// cast. A more elegant solution would work with the TypeNode
875
// type definition itself, but that would require a more thorough
876
// knowledge of the typing system than the kludger posesses.
877
{
878     if (node.type() == null)
879       {
880     if (node == ClassHierarchy.v().R0_1)
881       {
882         return BooleanType.v();
883       }
884     else if (node == ClassHierarchy.v().R0_127)
885       {
886         return ByteType.v();
887       }
888     else if (node == ClassHierarchy.v().R0_32767)
889       {
890         return ShortType.v();
891       }
892     // Perhaps we should throw an exception here, since I don't think
893
// there should be any other cases where node.type() is null.
894
// In case that supposition is incorrect, though, we'll just
895
// go on to return the null, and let the callers worry about it.
896
}
897     return node.type();
898   }
899
900   public void caseIdentityStmt(IdentityStmt stmt)
901   {
902     Value l = stmt.getLeftOp();
903     Value r = stmt.getRightOp();
904
905     if(l instanceof Local)
906       {
907     if(((Local) l).getType() instanceof IntegerType)
908       {
909         TypeNode left = ClassHierarchy.v().typeNode((((Local) l).getType()));
910         TypeNode right = ClassHierarchy.v().typeNode(r.getType());
911
912         if(!right.hasAncestor_1(left))
913           {
914         if(fix)
915           {
916             ((soot.jimple.internal.JIdentityStmt) stmt).setLeftOp(insertCastAfter((Local) l, left.type(), right.type(), stmt));
917           }
918         else
919           {
920             error("Type Error(16)");
921           }
922           }
923       }
924       }
925   }
926
927   public void caseEnterMonitorStmt(EnterMonitorStmt stmt)
928   {
929   }
930
931   public void caseExitMonitorStmt(ExitMonitorStmt stmt)
932   {
933   }
934
935   public void caseGotoStmt(GotoStmt stmt)
936   {
937   }
938
939   public void caseIfStmt(IfStmt stmt)
940   {
941     ConditionExpr cond = (ConditionExpr) stmt.getCondition();
942     
943     BinopExpr expr = (BinopExpr) cond;
944     Value lv = expr.getOp1();
945     Value rv = expr.getOp2();
946     
947     TypeNode lop = null;
948     TypeNode rop = null;
949     
950     //******** LEFT ********
951
if(lv instanceof Local)
952       {
953     if(((Local) lv).getType() instanceof IntegerType)
954       {
955         lop = ClassHierarchy.v().typeNode(((Local) lv).getType());
956       }
957       }
958     else if(lv instanceof DoubleConstant)
959       {
960       }
961     else if(lv instanceof FloatConstant)
962       {
963       }
964     else if(lv instanceof IntConstant)
965       {
966     int value = ((IntConstant) lv).value;
967         
968     if(value < -32768)
969       {
970         lop = ClassHierarchy.v().INT;
971       }
972     else if(value < -128)
973       {
974         lop = ClassHierarchy.v().SHORT;
975       }
976     else if(value < 0)
977       {
978         lop = ClassHierarchy.v().BYTE;
979       }
980     else if(value < 2)
981       {
982         lop = ClassHierarchy.v().R0_1;
983       }
984     else if(value < 128)
985       {
986         lop = ClassHierarchy.v().R0_127;
987       }
988     else if(value < 32768)
989       {
990         lop = ClassHierarchy.v().R0_32767;
991       }
992     else if(value < 65536)
993       {
994         lop = ClassHierarchy.v().CHAR;
995       }
996     else
997       {
998         lop = ClassHierarchy.v().INT;
999       }
1000      }
1001    else if(lv instanceof LongConstant)
1002      {
1003      }
1004    else if(lv instanceof NullConstant)
1005      {
1006      }
1007    else if(lv instanceof StringConstant)
1008      {
1009      }
1010    else if(lv instanceof ClassConstant)
1011      {
1012      }
1013    else
1014      {
1015    throw new RuntimeException JavaDoc("Unhandled binary expression left operand type: " + lv.getClass());
1016      }
1017    
1018    //******** RIGHT ********
1019
if(rv instanceof Local)
1020      {
1021    if(((Local) rv).getType() instanceof IntegerType)
1022      {
1023        rop = ClassHierarchy.v().typeNode(((Local) rv).getType());
1024      }
1025      }
1026    else if(rv instanceof DoubleConstant)
1027      {
1028      }
1029    else if(rv instanceof FloatConstant)
1030      {
1031      }
1032    else if(rv instanceof IntConstant)
1033      {
1034    int value = ((IntConstant) rv).value;
1035    
1036    if(value < -32768)
1037      {
1038        rop = ClassHierarchy.v().INT;
1039      }
1040    else if(value < -128)
1041      {
1042        rop = ClassHierarchy.v().SHORT;
1043      }
1044    else if(value < 0)
1045      {
1046        rop = ClassHierarchy.v().BYTE;
1047      }
1048    else if(value < 2)
1049      {
1050        rop = ClassHierarchy.v().R0_1;
1051      }
1052    else if(value < 128)
1053      {
1054        rop = ClassHierarchy.v().R0_127;
1055      }
1056    else if(value < 32768)
1057      {
1058        rop = ClassHierarchy.v().R0_32767;
1059      }
1060    else if(value < 65536)
1061      {
1062        rop = ClassHierarchy.v().CHAR;
1063      }
1064    else
1065      {
1066        rop = ClassHierarchy.v().INT;
1067      }
1068      }
1069    else if(rv instanceof LongConstant)
1070      {
1071      }
1072    else if(rv instanceof NullConstant)
1073      {
1074      }
1075    else if(rv instanceof StringConstant)
1076      {
1077      }
1078    else if(rv instanceof ClassConstant)
1079      {
1080      }
1081    else
1082      {
1083    throw new RuntimeException JavaDoc("Unhandled binary expression right operand type: " + rv.getClass());
1084      }
1085    
1086    if(lop != null && rop != null)
1087      {
1088    if(lop.lca_1(rop) == ClassHierarchy.v().TOP)
1089      {
1090        if(fix)
1091          {
1092        if(!lop.hasAncestor_1(ClassHierarchy.v().INT))
1093          {
1094            expr.setOp1(insertCast(expr.getOp1(), getTypeForCast(lop), getTypeForCast(rop), stmt));
1095          }
1096        
1097        if(!rop.hasAncestor_1(ClassHierarchy.v().INT))
1098          {
1099            expr.setOp2(insertCast(expr.getOp2(), getTypeForCast(rop), getTypeForCast(lop), stmt));
1100          }
1101          }
1102        else
1103          {
1104        error("Type Error(17)");
1105          }
1106      }
1107      }
1108  }
1109
1110  public void caseLookupSwitchStmt(LookupSwitchStmt stmt)
1111  {
1112    Value key = stmt.getKey();
1113    
1114    if(key instanceof Local)
1115      {
1116    if(!ClassHierarchy.v().typeNode(((Local) key).getType()).
1117       hasAncestor_1(ClassHierarchy.v().INT))
1118      {
1119        if(fix)
1120          {
1121        stmt.setKey(insertCast((Local) key, IntType.v(), stmt));
1122          }
1123        else
1124          {
1125        error("Type Error(18)");
1126          }
1127      }
1128      }
1129  }
1130
1131  public void caseNopStmt(NopStmt stmt)
1132  {
1133  }
1134
1135  public void caseReturnStmt(ReturnStmt stmt)
1136  {
1137    if(stmt.getOp() instanceof Local)
1138      {
1139    if(((Local) stmt.getOp()).getType() instanceof IntegerType)
1140      {
1141        if(!ClassHierarchy.v().typeNode(((Local) stmt.getOp()).getType()).
1142           hasAncestor_1(ClassHierarchy.v().typeNode(stmtBody.getMethod().getReturnType())))
1143          {
1144        if(fix)
1145          {
1146            stmt.setOp(insertCast((Local) stmt.getOp(), stmtBody.getMethod().getReturnType(), stmt));
1147          }
1148        else
1149          {
1150            error("Type Error(19)");
1151          }
1152          }
1153      }
1154      }
1155  }
1156
1157  public void caseReturnVoidStmt(ReturnVoidStmt stmt)
1158  {
1159  }
1160
1161  public void caseTableSwitchStmt(TableSwitchStmt stmt)
1162  {
1163    Value key = stmt.getKey();
1164    
1165    if(key instanceof Local)
1166      {
1167    if(!ClassHierarchy.v().typeNode(((Local) key).getType()).
1168       hasAncestor_1(ClassHierarchy.v().INT))
1169      {
1170        if(fix)
1171          {
1172        stmt.setKey(insertCast((Local) key, IntType.v(), stmt));
1173          }
1174        else
1175          {
1176        error("Type Error(20)");
1177          }
1178      }
1179    resolver.typeVariable((Local) key).addParent(resolver.INT);
1180      }
1181  }
1182
1183  public void caseThrowStmt(ThrowStmt stmt)
1184  {
1185  }
1186
1187  public void defaultCase(Stmt stmt)
1188  {
1189    throw new RuntimeException JavaDoc("Unhandled statement type: " + stmt.getClass());
1190  }
1191
1192  private Local insertCast(Local oldlocal, Type type, Stmt stmt)
1193  {
1194    Local newlocal = Jimple.v().newLocal("tmp", type);
1195    stmtBody.getLocals().add(newlocal);
1196    
1197    stmtBody.getUnits().insertBefore(Jimple.v().newAssignStmt(newlocal, Jimple.v().newCastExpr(oldlocal, type)), stmt);
1198    return newlocal;
1199  }
1200
1201  private Local insertCastAfter(Local leftlocal, Type lefttype, Type righttype, Stmt stmt)
1202  {
1203    Local newlocal = Jimple.v().newLocal("tmp", righttype);
1204    stmtBody.getLocals().add(newlocal);
1205    
1206    stmtBody.getUnits().insertAfter(Jimple.v().newAssignStmt(leftlocal, Jimple.v().newCastExpr(newlocal, lefttype)), stmt);
1207    return newlocal;
1208  }
1209
1210  private Local insertCast(Value oldvalue, Type oldtype, Type type, Stmt stmt)
1211  {
1212    Local newlocal1 = Jimple.v().newLocal("tmp", oldtype);
1213    Local newlocal2 = Jimple.v().newLocal("tmp", type);
1214    stmtBody.getLocals().add(newlocal1);
1215    stmtBody.getLocals().add(newlocal2);
1216    
1217    stmtBody.getUnits().insertBefore(Jimple.v().newAssignStmt(newlocal1, oldvalue), stmt);
1218    stmtBody.getUnits().insertBefore(Jimple.v().newAssignStmt(newlocal2, Jimple.v().newCastExpr(newlocal1, type)), stmt);
1219    return newlocal2;
1220  }
1221}
1222
Popular Tags