1 19 20 package soot.toolkits.exceptions; 21 22 import java.util.Iterator ; 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 46 public class UnitThrowAnalysis extends AbstractThrowAnalysis { 47 48 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 61 public UnitThrowAnalysis(Singletons.Global g) {} 62 63 66 protected UnitThrowAnalysis() {} 67 68 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 110 ThrowableSet mightThrow(SootMethod m) { 111 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 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); 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 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 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 } 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 obj) { 455 } 456 } 457 458 459 protected class ValueSwitch implements GrimpValueSwitch, ShimpleValueSwitch { 460 461 private ThrowableSet.Manager mgr = 462 ThrowableSet.Manager.v(); 463 464 private ThrowableSet result = mgr.VM_ERRORS; 466 467 ThrowableSet getResult() { 468 return result; 469 } 470 471 472 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 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 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 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 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 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 obj) { 707 } 708 709 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 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 |