KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > toolkits > exceptions > UnitThrowAnalysis


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2003 John Jorgensen
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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 package soot.toolkits.exceptions;
21
22 import java.util.Iterator JavaDoc;
23 import soot.*;
24 import soot.baf.*;
25 import soot.jimple.*;
26 import soot.grimp.*;
27 import soot.shimple.ShimpleValueSwitch;
28 import soot.shimple.PhiExpr;
29 import soot.toolkits.exceptions.*;
30
31 /**
32  * A {@link ThrowAnalysis} which returns the set of runtime exceptions
33  * and errors that might be thrown by the bytecode instructions
34  * represented by a unit, as indicated by the Java Virtual Machine
35  * specification. I.e. this analysis is based entirely on the
36  * “opcode” of the unit, the types of its arguments, and
37  * the values of constant arguments.
38  *
39  * <p>The <code>mightThrow</code> methods could be declared static.
40  * They are left virtual to facilitate testing. For example,
41  * to verify that the expressions in a method call are actually being
42  * examined, a test case can override the mightThrow(SootMethod)
43  * with an implementation which returns the empty set instead of
44  * all possible exceptions.
45  */

46 public class UnitThrowAnalysis extends AbstractThrowAnalysis {
47
48     // Cache the response to mightThrowImplicitly():
49
private final ThrowableSet implicitThrowExceptions
50     = ThrowableSet.Manager.v().VM_ERRORS
51     .add(ThrowableSet.Manager.v().NULL_POINTER_EXCEPTION)
52     .add(ThrowableSet.Manager.v().ILLEGAL_MONITOR_STATE_EXCEPTION);
53
54     /**
55      * Constructs a <code>UnitThrowAnalysis</code> for inclusion in
56      * Soot's global variable manager, {@link G}.
57      *
58      * @param g guarantees that the constructor may only be called
59      * from {@link Singletons}.
60      */

61     public UnitThrowAnalysis(Singletons.Global g) {}
62
63     /**
64      * A protected constructor for use by unit tests.
65      */

66     protected UnitThrowAnalysis() {}
67
68     /**
69      * Returns the single instance of <code>UnitThrowAnalysis</code>.
70      *
71      * @return Soot's <code>UnitThrowAnalysis</code>.
72      */

73     public static UnitThrowAnalysis v() { return G.v().soot_toolkits_exceptions_UnitThrowAnalysis(); }
74
75
76     public ThrowableSet mightThrow(Unit u) {
77     UnitSwitch sw = new UnitSwitch();
78     u.apply(sw);
79     return sw.getResult();
80     }
81
82
83     public ThrowableSet mightThrowImplicitly(ThrowInst t) {
84     return implicitThrowExceptions;
85     }
86     
87     
88     public ThrowableSet mightThrowImplicitly(ThrowStmt t) {
89     return implicitThrowExceptions;
90     }
91     
92     
93     ThrowableSet mightThrow(Value v) {
94     ValueSwitch sw = new ValueSwitch();
95     v.apply(sw);
96     return sw.getResult();
97     }
98
99
100     /**
101      * Returns the set of types that might be thrown as a result of
102      * calling the specified method.
103      *
104      * @param m method whose exceptions are to be returned.
105      *
106      * @return a representation of the set of {@link
107      * java.lang.Throwable Throwable} types that <code>m</code> might
108      * throw.
109      */

110     ThrowableSet mightThrow(SootMethod m) {
111     // In the absence of an interprocedural analysis,
112
// m could throw anything.
113
return ThrowableSet.Manager.v().ALL_THROWABLES;
114     }
115
116
117     private static final IntConstant INT_CONSTANT_ZERO = IntConstant.v(0);
118     private static final LongConstant LONG_CONSTANT_ZERO = LongConstant.v(0);
119
120
121     protected class UnitSwitch implements InstSwitch, StmtSwitch {
122
123     private ThrowableSet.Manager mgr = ThrowableSet.Manager.v();
124
125     // Asynchronous errors are always possible:
126
private ThrowableSet result = mgr.VM_ERRORS;
127     
128     ThrowableSet getResult() {
129         return result;
130     }
131
132     public void caseReturnVoidInst(ReturnVoidInst i) {
133         result = result.add(mgr.ILLEGAL_MONITOR_STATE_EXCEPTION);
134     }
135         
136     public void caseReturnInst(ReturnInst i) {
137         result = result.add(mgr.ILLEGAL_MONITOR_STATE_EXCEPTION);
138     }
139
140     public void caseNopInst(NopInst i) {
141     }
142
143     public void caseGotoInst(GotoInst i) {
144     }
145
146     public void casePushInst(PushInst i) {
147     }
148
149     public void casePopInst(PopInst i) {
150     }
151
152     public void caseIdentityInst(IdentityInst i) {
153     }
154
155     public void caseStoreInst(StoreInst i) {
156     }
157
158     public void caseLoadInst(LoadInst i) {
159     }
160
161     public void caseArrayWriteInst(ArrayWriteInst i) {
162         result = result.add(mgr.NULL_POINTER_EXCEPTION);
163         result = result.add(mgr.ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION);
164         if (i.getOpType() instanceof RefType) {
165         result = result.add(mgr.ARRAY_STORE_EXCEPTION);
166         }
167     }
168
169     public void caseArrayReadInst(ArrayReadInst i) {
170         result = result.add(mgr.NULL_POINTER_EXCEPTION);
171         result = result.add(mgr.ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION);
172     }
173
174     public void caseIfNullInst(IfNullInst i) {
175     }
176
177     public void caseIfNonNullInst(IfNonNullInst i) {
178     }
179
180     public void caseIfEqInst(IfEqInst i) {
181     }
182
183     public void caseIfNeInst(IfNeInst i) {
184     }
185
186     public void caseIfGtInst(IfGtInst i) {
187     }
188
189     public void caseIfGeInst(IfGeInst i) {
190     }
191
192     public void caseIfLtInst(IfLtInst i) {
193     }
194
195     public void caseIfLeInst(IfLeInst i) {
196     }
197
198     public void caseIfCmpEqInst(IfCmpEqInst i) {
199     }
200
201     public void caseIfCmpNeInst(IfCmpNeInst i) {
202     }
203
204     public void caseIfCmpGtInst(IfCmpGtInst i) {
205     }
206
207     public void caseIfCmpGeInst(IfCmpGeInst i) {
208     }
209
210     public void caseIfCmpLtInst(IfCmpLtInst i) {
211     }
212
213     public void caseIfCmpLeInst(IfCmpLeInst i) {
214     }
215
216     public void caseStaticGetInst(StaticGetInst i) {
217         result = result.add(mgr.INITIALIZATION_ERRORS);
218     }
219
220     public void caseStaticPutInst(StaticPutInst i) {
221         result = result.add(mgr.INITIALIZATION_ERRORS);
222     }
223
224     public void caseFieldGetInst(FieldGetInst i) {
225         result = result.add(mgr.RESOLVE_FIELD_ERRORS);
226         result = result.add(mgr.NULL_POINTER_EXCEPTION);
227     }
228
229     public void caseFieldPutInst(FieldPutInst i) {
230         result = result.add(mgr.RESOLVE_FIELD_ERRORS);
231         result = result.add(mgr.NULL_POINTER_EXCEPTION);
232     }
233
234     public void caseInstanceCastInst(InstanceCastInst i) {
235         result = result.add(mgr.RESOLVE_CLASS_ERRORS);
236         result = result.add(mgr.CLASS_CAST_EXCEPTION);
237     }
238
239     public void caseInstanceOfInst(InstanceOfInst i) {
240         result = result.add(mgr.RESOLVE_CLASS_ERRORS);
241     }
242
243     public void casePrimitiveCastInst(PrimitiveCastInst i) {
244     }
245
246     public void caseStaticInvokeInst(StaticInvokeInst i) {
247         result = result.add(mgr.INITIALIZATION_ERRORS);
248         result = result.add(mightThrow(i.getMethod()));
249     }
250
251     public void caseVirtualInvokeInst(VirtualInvokeInst i) {
252         result = result.add(mgr.RESOLVE_METHOD_ERRORS);
253         result = result.add(mgr.NULL_POINTER_EXCEPTION);
254         result = result.add(mightThrow(i.getMethod()));
255     }
256
257     public void caseInterfaceInvokeInst(InterfaceInvokeInst i) {
258         result = result.add(mgr.RESOLVE_METHOD_ERRORS);
259         result = result.add(mgr.NULL_POINTER_EXCEPTION);
260         result = result.add(mightThrow(i.getMethod()));
261     }
262
263     public void caseSpecialInvokeInst(SpecialInvokeInst i) {
264         result = result.add(mgr.RESOLVE_METHOD_ERRORS);
265         result = result.add(mgr.NULL_POINTER_EXCEPTION);
266         result = result.add(mightThrow(i.getMethod()));
267     }
268
269     public void caseThrowInst(ThrowInst i) {
270         result = mightThrowImplicitly(i);
271         result = result.add(mightThrowExplicitly(i));
272     }
273
274     public void caseAddInst(AddInst i) {
275     }
276
277     public void caseAndInst(AndInst i) {
278     }
279
280     public void caseOrInst(OrInst i) {
281     }
282
283     public void caseXorInst(XorInst i) {
284     }
285
286     public void caseArrayLengthInst(ArrayLengthInst i) {
287         result = result.add(mgr.NULL_POINTER_EXCEPTION);
288     }
289
290     public void caseCmpInst(CmpInst i) {
291     }
292
293     public void caseCmpgInst(CmpgInst i) {
294     }
295
296     public void caseCmplInst(CmplInst i) {
297     }
298
299     public void caseDivInst(DivInst i) {
300         if (i.getOpType() instanceof IntegerType ||
301         i.getOpType() == LongType.v()) {
302         result = result.add(mgr.ARITHMETIC_EXCEPTION);
303         }
304     }
305
306     public void caseIncInst(IncInst i) {
307     }
308
309     public void caseMulInst(MulInst i) {
310     }
311
312     public void caseRemInst(RemInst i) {
313         if (i.getOpType() instanceof IntegerType ||
314         i.getOpType() == LongType.v()) {
315         result = result.add(mgr.ARITHMETIC_EXCEPTION);
316         }
317     }
318
319     public void caseSubInst(SubInst i) {
320     }
321
322     public void caseShlInst(ShlInst i) {
323     }
324
325     public void caseShrInst(ShrInst i) {
326     }
327
328     public void caseUshrInst(UshrInst i) {
329     }
330
331     public void caseNewInst(NewInst i) {
332         result = result.add(mgr.INITIALIZATION_ERRORS);
333     }
334         
335     public void caseNegInst(NegInst i) {
336     }
337
338     public void caseSwapInst(SwapInst i) {
339     }
340    
341     public void caseDup1Inst(Dup1Inst i) {
342     }
343
344     public void caseDup2Inst(Dup2Inst i) {
345     }
346
347     public void caseDup1_x1Inst(Dup1_x1Inst i) {
348     }
349     
350     public void caseDup1_x2Inst(Dup1_x2Inst i) {
351     }
352
353     public void caseDup2_x1Inst(Dup2_x1Inst i) {
354     }
355
356     public void caseDup2_x2Inst(Dup2_x2Inst i) {
357     }
358
359     public void caseNewArrayInst(NewArrayInst i) {
360         result = result.add(mgr.RESOLVE_CLASS_ERRORS); // Could be omitted for primitive arrays.
361
result = result.add(mgr.NEGATIVE_ARRAY_SIZE_EXCEPTION);
362     }
363
364     public void caseNewMultiArrayInst(NewMultiArrayInst i) {
365         result = result.add(mgr.RESOLVE_CLASS_ERRORS);
366         result = result.add(mgr.NEGATIVE_ARRAY_SIZE_EXCEPTION);
367     }
368
369     public void caseLookupSwitchInst(LookupSwitchInst i) {
370     }
371
372     public void caseTableSwitchInst(TableSwitchInst i) {
373     }
374
375     public void caseEnterMonitorInst(EnterMonitorInst i) {
376         result = result.add(mgr.NULL_POINTER_EXCEPTION);
377     }
378
379     public void caseExitMonitorInst(ExitMonitorInst i) {
380         result = result.add(mgr.ILLEGAL_MONITOR_STATE_EXCEPTION);
381         result = result.add(mgr.NULL_POINTER_EXCEPTION);
382     }
383
384     public void caseAssignStmt(AssignStmt s) {
385         Value lhs = s.getLeftOp();
386         if (lhs instanceof ArrayRef &&
387         (lhs.getType() instanceof UnknownType ||
388          lhs.getType() instanceof RefType)) {
389         // This corresponds to an aastore byte code.
390
result = result.add(mgr.ARRAY_STORE_EXCEPTION);
391         }
392         result = result.add(mightThrow(s.getLeftOp()));
393         result = result.add(mightThrow(s.getRightOp()));
394     }
395
396     public void caseBreakpointStmt(BreakpointStmt s) {}
397
398     public void caseEnterMonitorStmt(EnterMonitorStmt s) {
399         result = result.add(mgr.NULL_POINTER_EXCEPTION);
400         result = result.add(mightThrow(s.getOp()));
401     }
402
403     public void caseExitMonitorStmt(ExitMonitorStmt s) {
404         result = result.add(mgr.ILLEGAL_MONITOR_STATE_EXCEPTION);
405         result = result.add(mgr.NULL_POINTER_EXCEPTION);
406         result = result.add(mightThrow(s.getOp()));
407     }
408
409     public void caseGotoStmt(GotoStmt s) {
410     }
411
412     public void caseIdentityStmt(IdentityStmt s) {}
413     // Perhaps IdentityStmt shouldn't even return VM_ERRORS,
414
// since it corresponds to no bytecode instructions whatsoever.
415

416     public void caseIfStmt(IfStmt s) {
417         result = result.add(mightThrow(s.getCondition()));
418     }
419
420     public void caseInvokeStmt(InvokeStmt s) {
421         result = result.add(mightThrow(s.getInvokeExpr()));
422     }
423
424     public void caseLookupSwitchStmt(LookupSwitchStmt s) {
425         result = result.add(mightThrow(s.getKey()));
426     }
427         
428     public void caseNopStmt(NopStmt s) {
429     }
430
431     public void caseRetStmt(RetStmt s) {
432         // Soot should never produce any RetStmt, since
433
// it implements jsr with gotos.
434
}
435
436     public void caseReturnStmt(ReturnStmt s) {
437         result = result.add(mgr.ILLEGAL_MONITOR_STATE_EXCEPTION);
438         result = result.add(mightThrow(s.getOp()));
439     }
440
441     public void caseReturnVoidStmt(ReturnVoidStmt s) {
442         result = result.add(mgr.ILLEGAL_MONITOR_STATE_EXCEPTION);
443     }
444
445     public void caseTableSwitchStmt(TableSwitchStmt s) {
446         result = result.add(mightThrow(s.getKey()));
447     }
448
449     public void caseThrowStmt(ThrowStmt s) {
450         result = mightThrowImplicitly(s);
451         result = result.add(mightThrowExplicitly(s));
452     }
453
454     public void defaultCase(Object JavaDoc obj) {
455     }
456     }
457
458
459     protected class ValueSwitch implements GrimpValueSwitch, ShimpleValueSwitch {
460
461     private ThrowableSet.Manager mgr =
462         ThrowableSet.Manager.v();
463
464     // Asynchronous errors are always possible:
465
private ThrowableSet result = mgr.VM_ERRORS;
466     
467     ThrowableSet getResult() {
468         return result;
469     }
470
471
472     // Declared by ConstantSwitch interface:
473

474     public void caseDoubleConstant(DoubleConstant c) {
475     }
476
477     public void caseFloatConstant(FloatConstant c) {
478     }
479
480     public void caseIntConstant(IntConstant c) {
481     }
482
483     public void caseLongConstant(LongConstant c) {
484     }
485
486     public void caseNullConstant(NullConstant c) {
487     }
488
489     public void caseStringConstant(StringConstant c) {
490     }
491
492     public void caseClassConstant(ClassConstant c) {
493     }
494
495
496     // Declared by ExprSwitch interface:
497

498     public void caseAddExpr(AddExpr expr) {
499         caseBinopExpr(expr);
500     }
501
502     public void caseAndExpr(AndExpr expr) {
503         caseBinopExpr(expr);
504     }
505
506     public void caseCmpExpr(CmpExpr expr) {
507         caseBinopExpr(expr);
508     }
509
510     public void caseCmpgExpr(CmpgExpr expr) {
511         caseBinopExpr(expr);
512     }
513
514     public void caseCmplExpr(CmplExpr expr) {
515         caseBinopExpr(expr);
516     }
517
518     public void caseDivExpr(DivExpr expr) {
519         caseBinopDivExpr(expr);
520     }
521
522     public void caseEqExpr(EqExpr expr) {
523         caseBinopExpr(expr);
524     }
525
526     public void caseNeExpr(NeExpr expr) {
527         caseBinopExpr(expr);
528     }
529
530     public void caseGeExpr(GeExpr expr) {
531         caseBinopExpr(expr);
532     }
533
534     public void caseGtExpr(GtExpr expr) {
535         caseBinopExpr(expr);
536     }
537
538     public void caseLeExpr(LeExpr expr) {
539         caseBinopExpr(expr);
540     }
541
542     public void caseLtExpr(LtExpr expr) {
543         caseBinopExpr(expr);
544     }
545
546     public void caseMulExpr(MulExpr expr) {
547         caseBinopExpr(expr);
548     }
549
550     public void caseOrExpr(OrExpr expr) {
551         caseBinopExpr(expr);
552     }
553
554     public void caseRemExpr(RemExpr expr) {
555         caseBinopDivExpr(expr);
556     }
557
558     public void caseShlExpr(ShlExpr expr) {
559         caseBinopExpr(expr);
560     }
561
562     public void caseShrExpr(ShrExpr expr) {
563         caseBinopExpr(expr);
564     }
565
566     public void caseUshrExpr(UshrExpr expr) {
567         caseBinopExpr(expr);
568     }
569
570     public void caseSubExpr(SubExpr expr) {
571         caseBinopExpr(expr);
572     }
573
574     public void caseXorExpr(XorExpr expr) {
575         caseBinopExpr(expr);
576     }
577
578     public void caseInterfaceInvokeExpr(InterfaceInvokeExpr expr) {
579         caseInstanceInvokeExpr(expr);
580     }
581
582     public void caseSpecialInvokeExpr(SpecialInvokeExpr expr) {
583         caseInstanceInvokeExpr(expr);
584     }
585
586     public void caseStaticInvokeExpr(StaticInvokeExpr expr) {
587         result = result.add(mgr.INITIALIZATION_ERRORS);
588         for (int i = 0; i < expr.getArgCount(); i++) {
589         result = result.add(mightThrow(expr.getArg(i)));
590         }
591         result = result.add(mightThrow(expr.getMethod()));
592     }
593
594     public void caseVirtualInvokeExpr(VirtualInvokeExpr expr) {
595         caseInstanceInvokeExpr(expr);
596     }
597
598     public void caseCastExpr(CastExpr expr) {
599         result = result.add(mgr.RESOLVE_CLASS_ERRORS);
600         Type fromType = expr.getOp().getType();
601         Type toType = expr.getCastType();
602         if (toType instanceof RefLikeType) {
603         // fromType might still be unknown when we are called,
604
// but toType will have a value.
605
FastHierarchy h = Scene.v().getOrMakeFastHierarchy();
606         if (fromType == null || fromType instanceof UnknownType ||
607             ((! (fromType instanceof NullType)) &&
608              (! h.canStoreType(fromType, toType)))) {
609             result = result.add(mgr.CLASS_CAST_EXCEPTION);
610         }
611         }
612         result = result.add(mightThrow(expr.getOp()));
613     }
614         
615     public void caseInstanceOfExpr(InstanceOfExpr expr) {
616         result = result.add(mgr.RESOLVE_CLASS_ERRORS);
617         result = result.add(mightThrow(expr.getOp()));
618     }
619
620     public void caseNewArrayExpr(NewArrayExpr expr) {
621         if (expr.getBaseType() instanceof RefLikeType) {
622         result = result.add(mgr.RESOLVE_CLASS_ERRORS);
623         }
624         Value count = expr.getSize();
625         if ((! (count instanceof IntConstant)) ||
626         (((IntConstant) count).lessThan(INT_CONSTANT_ZERO)
627                               .equals(INT_CONSTANT_ZERO))) {
628         result = result.add(mgr.NEGATIVE_ARRAY_SIZE_EXCEPTION);
629         }
630         result = result.add(mightThrow(count));
631     }
632
633     public void caseNewMultiArrayExpr(NewMultiArrayExpr expr) {
634         result = result.add(mgr.RESOLVE_CLASS_ERRORS);
635         for (int i = 0; i < expr.getSizeCount(); i++) {
636         Value count = expr.getSize(i);
637         if ((! (count instanceof IntConstant)) ||
638             (((IntConstant) count).lessThan(INT_CONSTANT_ZERO)
639                                   .equals(INT_CONSTANT_ZERO))) {
640             result = result.add(mgr.NEGATIVE_ARRAY_SIZE_EXCEPTION);
641         }
642         result = result.add(mightThrow(count));
643         }
644     }
645
646     public void caseNewExpr(NewExpr expr) {
647         result = result.add(mgr.INITIALIZATION_ERRORS);
648         for (Iterator JavaDoc i = expr.getUseBoxes().iterator(); i.hasNext(); ) {
649         ValueBox box = (ValueBox) i.next();
650         result = result.add(mightThrow(box.getValue()));
651         }
652     }
653
654     public void caseLengthExpr(LengthExpr expr) {
655         result = result.add(mgr.NULL_POINTER_EXCEPTION);
656         result = result.add(mightThrow(expr.getOp()));
657     }
658
659     public void caseNegExpr(NegExpr expr) {
660         result = result.add(mightThrow(expr.getOp()));
661     }
662
663
664     // Declared by RefSwitch interface:
665

666     public void caseArrayRef(ArrayRef ref) {
667         result = result.add(mgr.NULL_POINTER_EXCEPTION);
668         result = result.add(mgr.ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION);
669         result = result.add(mightThrow(ref.getBase()));
670         result = result.add(mightThrow(ref.getIndex()));
671     }
672
673     public void caseStaticFieldRef(StaticFieldRef ref) {
674         result = result.add(mgr.INITIALIZATION_ERRORS);
675     }
676
677     public void caseInstanceFieldRef(InstanceFieldRef ref) {
678         result = result.add(mgr.RESOLVE_FIELD_ERRORS);
679         result = result.add(mgr.NULL_POINTER_EXCEPTION);
680         result = result.add(mightThrow(ref.getBase()));
681     }
682
683     public void caseParameterRef(ParameterRef v) {
684     }
685
686     public void caseCaughtExceptionRef(CaughtExceptionRef v) {
687     }
688
689     public void caseThisRef(ThisRef v) {
690     }
691
692     public void caseLocal(Local l) {
693     }
694
695     public void caseNewInvokeExpr(NewInvokeExpr e) {
696         caseStaticInvokeExpr(e);
697     }
698
699     public void casePhiExpr(PhiExpr e) {
700         for (Iterator JavaDoc i = e.getUseBoxes().iterator(); i.hasNext(); ) {
701         ValueBox box = (ValueBox) i.next();
702         result = result.add(mightThrow(box.getValue()));
703         }
704     }
705
706     public void defaultCase(Object JavaDoc obj) {
707     }
708
709     // The remaining cases are not declared by GrimpValueSwitch,
710
// but are used to factor out code common to several cases.
711

712     private void caseBinopExpr(BinopExpr expr) {
713         result = result.add(mightThrow(expr.getOp1()));
714         result = result.add(mightThrow(expr.getOp2()));
715     }
716
717     private void caseBinopDivExpr(BinopExpr expr) {
718         // Factors out code common to caseDivExpr and caseRemExpr.
719
// The checks against constant divisors would perhaps be
720
// better performed in a later pass, post-constant-propagation.
721
Value divisor = expr.getOp2();
722         Type divisorType = divisor.getType();
723         if (divisorType instanceof UnknownType) {
724         result = result.add(mgr.ARITHMETIC_EXCEPTION);
725         } else if ((divisorType instanceof IntegerType) &&
726         ((! (divisor instanceof IntConstant)) ||
727          (((IntConstant) divisor).equals(INT_CONSTANT_ZERO)))) {
728         result = result.add(mgr.ARITHMETIC_EXCEPTION);
729         } else if ((divisorType == LongType.v()) &&
730                ((! (divisor instanceof LongConstant)) ||
731             (((LongConstant) divisor).equals(LONG_CONSTANT_ZERO)))) {
732         result = result.add(mgr.ARITHMETIC_EXCEPTION);
733         }
734         caseBinopExpr(expr);
735     }
736
737     private void caseInstanceInvokeExpr(InstanceInvokeExpr expr) {
738         result = result.add(mgr.RESOLVE_METHOD_ERRORS);
739         result = result.add(mgr.NULL_POINTER_EXCEPTION);
740         for (int i = 0; i < expr.getArgCount(); i++) {
741         result = result.add(mightThrow(expr.getArg(i)));
742         }
743         result = result.add(mightThrow(expr.getBase()));
744         result = result.add(mightThrow(expr.getMethod()));
745     }
746     }
747 }
748
Popular Tags