1 19 20 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 34 class ConstraintCollectorBV extends AbstractStmtSwitch 35 { 36 private TypeResolverBV resolver; 37 private ClassHierarchy hierarchy; 38 private boolean uses; 40 private JimpleBody stmtBody; 41 42 public ConstraintCollectorBV(TypeResolverBV resolver, boolean uses) 43 { 44 this.resolver = resolver; 45 this.uses = uses; 46 47 hierarchy = resolver.hierarchy(); 48 } 49 50 public void collect(Stmt stmt, JimpleBody stmtBody) 51 { 52 this.stmtBody = stmtBody; 53 stmt.apply(this); 54 } 55 private void handleInvokeExpr(InvokeExpr ie) 56 { 57 if(!uses) 58 return; 59 60 if(ie instanceof InterfaceInvokeExpr) 61 { 62 InterfaceInvokeExpr invoke = (InterfaceInvokeExpr) ie; 63 64 SootMethodRef method = invoke.getMethodRef(); 65 Value base = invoke.getBase(); 66 67 if(base instanceof Local) 68 { 69 Local local = (Local) base; 70 71 TypeVariableBV localType = resolver.typeVariable(local); 72 73 localType.addParent(resolver.typeVariable(method.declaringClass())); 74 } 75 76 int count = invoke.getArgCount(); 77 78 for(int i = 0; i < count; i++) 79 { 80 if(invoke.getArg(i) instanceof Local) 81 { 82 Local local = (Local) invoke.getArg(i); 83 84 TypeVariableBV localType = resolver.typeVariable(local); 85 86 localType.addParent(resolver.typeVariable(method.parameterType(i))); 87 } 88 } 89 } 90 else if(ie instanceof SpecialInvokeExpr) 91 { 92 SpecialInvokeExpr invoke = (SpecialInvokeExpr) ie; 93 94 SootMethodRef method = invoke.getMethodRef(); 95 Value base = invoke.getBase(); 96 97 if(base instanceof Local) 98 { 99 Local local = (Local) base; 100 101 TypeVariableBV localType = resolver.typeVariable(local); 102 103 localType.addParent(resolver.typeVariable(method.declaringClass())); 104 } 105 106 int count = invoke.getArgCount(); 107 108 for(int i = 0; i < count; i++) 109 { 110 if(invoke.getArg(i) instanceof Local) 111 { 112 Local local = (Local) invoke.getArg(i); 113 114 TypeVariableBV localType = resolver.typeVariable(local); 115 116 localType.addParent(resolver.typeVariable(method.parameterType(i))); 117 } 118 } 119 } 120 else if(ie instanceof VirtualInvokeExpr) 121 { 122 VirtualInvokeExpr invoke = (VirtualInvokeExpr) ie; 123 124 SootMethodRef method = invoke.getMethodRef(); 125 Value base = invoke.getBase(); 126 127 if(base instanceof Local) 128 { 129 Local local = (Local) base; 130 131 TypeVariableBV localType = resolver.typeVariable(local); 132 133 localType.addParent(resolver.typeVariable(method.declaringClass())); 134 } 135 136 int count = invoke.getArgCount(); 137 138 for(int i = 0; i < count; i++) 139 { 140 if(invoke.getArg(i) instanceof Local) 141 { 142 Local local = (Local) invoke.getArg(i); 143 144 TypeVariableBV localType = resolver.typeVariable(local); 145 146 localType.addParent(resolver.typeVariable(method.parameterType(i))); 147 } 148 } 149 } 150 else if(ie instanceof StaticInvokeExpr) 151 { 152 StaticInvokeExpr invoke = (StaticInvokeExpr) ie; 153 154 SootMethodRef method = invoke.getMethodRef(); 155 156 int count = invoke.getArgCount(); 157 158 for(int i = 0; i < count; i++) 159 { 160 if(invoke.getArg(i) instanceof Local) 161 { 162 Local local = (Local) invoke.getArg(i); 163 164 TypeVariableBV localType = resolver.typeVariable(local); 165 166 localType.addParent(resolver.typeVariable(method.parameterType(i))); 167 } 168 } 169 } 170 else 171 { 172 throw new RuntimeException ("Unhandled invoke expression type: " + ie.getClass()); 173 } 174 } 175 176 public void caseBreakpointStmt(BreakpointStmt stmt) 177 { 178 } 180 181 public void caseInvokeStmt(InvokeStmt stmt) 182 { 183 handleInvokeExpr((InvokeExpr) stmt.getInvokeExpr()); 184 } 185 186 public void caseAssignStmt(AssignStmt stmt) 187 { 188 Value l = stmt.getLeftOp(); 189 Value r = stmt.getRightOp(); 190 191 TypeVariableBV left = null; 192 TypeVariableBV right = null; 193 194 196 if(l instanceof ArrayRef) 197 { 198 ArrayRef ref = (ArrayRef) l; 199 Value base = ref.getBase(); 200 Value index = ref.getIndex(); 201 202 TypeVariableBV baseType = resolver.typeVariable((Local) base); 203 baseType.makeElement(); 204 left = baseType.element(); 205 206 if(index instanceof Local) 207 { 208 if(uses) 209 { 210 resolver.typeVariable((Local) index).addParent(resolver.typeVariable(IntType.v())); 211 } 212 } 213 } 214 else if(l instanceof Local) 215 { 216 left = resolver.typeVariable((Local) l); 217 } 218 else if(l instanceof InstanceFieldRef) 219 { 220 InstanceFieldRef ref = (InstanceFieldRef) l; 221 222 if(uses) 223 { 224 TypeVariableBV baseType = resolver.typeVariable((Local) ref.getBase()); 225 baseType.addParent(resolver.typeVariable(ref.getField().getDeclaringClass())); 226 227 left = resolver.typeVariable(ref.getField().getType()); 228 } 229 } 230 else if(l instanceof StaticFieldRef) 231 { 232 if(uses) 233 { 234 StaticFieldRef ref = (StaticFieldRef) l; 235 236 left = resolver.typeVariable(ref.getField().getType()); 237 } 238 } 239 else 240 { 241 throw new RuntimeException ("Unhandled assignment left hand side type: " + l.getClass()); 242 } 243 244 246 if(r instanceof ArrayRef) 247 { 248 ArrayRef ref = (ArrayRef) r; 249 Value base = ref.getBase(); 250 Value index = ref.getIndex(); 251 252 TypeVariableBV baseType = resolver.typeVariable((Local) base); 253 baseType.makeElement(); 254 right = baseType.element(); 255 256 if(index instanceof Local) 257 { 258 if(uses) 259 { 260 resolver.typeVariable((Local) index).addParent(resolver.typeVariable(IntType.v())); 261 } 262 } 263 } 264 else if(r instanceof DoubleConstant) 265 { 266 right = resolver.typeVariable(DoubleType.v()); 267 } 268 else if(r instanceof FloatConstant) 269 { 270 right = resolver.typeVariable(FloatType.v()); 271 } 272 else if(r instanceof IntConstant) 273 { 274 right = resolver.typeVariable(IntType.v()); 275 } 276 else if(r instanceof LongConstant) 277 { 278 right = resolver.typeVariable(LongType.v()); 279 } 280 else if(r instanceof NullConstant) 281 { 282 right = resolver.typeVariable(NullType.v()); 283 } 284 else if(r instanceof StringConstant) 285 { 286 right = resolver.typeVariable(RefType.v("java.lang.String")); 287 } 288 else if(r instanceof ClassConstant) 289 { 290 right = resolver.typeVariable(RefType.v("java.lang.Class")); 291 } 292 else if(r instanceof BinopExpr) 293 { 294 296 BinopExpr be = (BinopExpr) r; 297 298 Value lv = be.getOp1(); 299 Value rv = be.getOp2(); 300 301 TypeVariableBV lop; 302 TypeVariableBV rop; 303 304 if(lv instanceof Local) 306 { 307 lop = resolver.typeVariable((Local) lv); 308 } 309 else if(lv instanceof DoubleConstant) 310 { 311 lop = resolver.typeVariable(DoubleType.v()); 312 } 313 else if(lv instanceof FloatConstant) 314 { 315 lop = resolver.typeVariable(FloatType.v()); 316 } 317 else if(lv instanceof IntConstant) 318 { 319 lop = resolver.typeVariable(IntType.v()); 320 } 321 else if(lv instanceof LongConstant) 322 { 323 lop = resolver.typeVariable(LongType.v()); 324 } 325 else if(lv instanceof NullConstant) 326 { 327 lop = resolver.typeVariable(NullType.v()); 328 } 329 else if(lv instanceof StringConstant) 330 { 331 lop = resolver.typeVariable(RefType.v("java.lang.String")); 332 } 333 else if(lv instanceof ClassConstant) 334 { 335 lop = resolver.typeVariable(RefType.v("java.lang.Class")); 336 } 337 else 338 { 339 throw new RuntimeException ("Unhandled binary expression left operand type: " + lv.getClass()); 340 } 341 342 if(rv instanceof Local) 344 { 345 rop = resolver.typeVariable((Local) rv); 346 } 347 else if(rv instanceof DoubleConstant) 348 { 349 rop = resolver.typeVariable(DoubleType.v()); 350 } 351 else if(rv instanceof FloatConstant) 352 { 353 rop = resolver.typeVariable(FloatType.v()); 354 } 355 else if(rv instanceof IntConstant) 356 { 357 rop = resolver.typeVariable(IntType.v()); 358 } 359 else if(rv instanceof LongConstant) 360 { 361 rop = resolver.typeVariable(LongType.v()); 362 } 363 else if(rv instanceof NullConstant) 364 { 365 rop = resolver.typeVariable(NullType.v()); 366 } 367 else if(rv instanceof StringConstant) 368 { 369 rop = resolver.typeVariable(RefType.v("java.lang.String")); 370 } 371 else if(rv instanceof ClassConstant) 372 { 373 rop = resolver.typeVariable(RefType.v("java.lang.Class")); 374 } 375 else 376 { 377 throw new RuntimeException ("Unhandled binary expression right operand type: " + rv.getClass()); 378 } 379 380 if((be instanceof AddExpr) || 381 (be instanceof SubExpr) || 382 (be instanceof MulExpr) || 383 (be instanceof DivExpr) || 384 (be instanceof RemExpr) || 385 (be instanceof AndExpr) || 386 (be instanceof OrExpr) || 387 (be instanceof XorExpr)) 388 { 389 if(uses) 390 { 391 TypeVariableBV common = resolver.typeVariable(); 392 rop.addParent(common); 393 lop.addParent(common); 394 } 395 396 if(left != null) 397 { 398 rop.addParent(left); 399 lop.addParent(left); 400 } 401 } 402 else if((be instanceof ShlExpr) || 403 (be instanceof ShrExpr) || 404 (be instanceof UshrExpr)) 405 { 406 if(uses) 407 { 408 rop.addParent(resolver.typeVariable(IntType.v())); 409 } 410 411 right = lop; 412 } 413 else if((be instanceof CmpExpr) || 414 (be instanceof CmpgExpr) || 415 (be instanceof CmplExpr) || 416 (be instanceof EqExpr) || 417 (be instanceof GeExpr) || 418 (be instanceof GtExpr) || 419 (be instanceof LeExpr) || 420 (be instanceof LtExpr) || 421 (be instanceof NeExpr)) 422 { 423 if(uses) 424 { 425 TypeVariableBV common = resolver.typeVariable(); 426 rop.addParent(common); 427 lop.addParent(common); 428 } 429 430 right = resolver.typeVariable(IntType.v()); 431 } 432 else 433 { 434 throw new RuntimeException ("Unhandled binary expression type: " + be.getClass()); 435 } 436 } 437 else if(r instanceof CastExpr) 438 { 439 CastExpr ce = (CastExpr) r; 440 441 right = resolver.typeVariable(ce.getCastType()); 442 } 443 else if(r instanceof InstanceOfExpr) 444 { 445 InstanceOfExpr ioe = (InstanceOfExpr) r; 446 447 right = resolver.typeVariable(IntType.v()); 448 } 449 else if(r instanceof InvokeExpr) 450 { 451 InvokeExpr ie = (InvokeExpr) r; 452 453 handleInvokeExpr(ie); 454 455 right = resolver.typeVariable(ie.getMethodRef().returnType()); 456 } 457 else if(r instanceof NewArrayExpr) 458 { 459 NewArrayExpr nae = (NewArrayExpr) r; 460 461 Type baseType = nae.getBaseType(); 462 463 if(baseType instanceof ArrayType) 464 { 465 right = resolver.typeVariable(ArrayType.v(((ArrayType) baseType).baseType, 466 ((ArrayType) baseType).numDimensions + 1)); 467 } 468 else 469 { 470 right = resolver.typeVariable(ArrayType.v(baseType, 1)); 471 } 472 473 if(uses) 474 { 475 Value size = nae.getSize(); 476 if(size instanceof Local) 477 { 478 TypeVariableBV var = resolver.typeVariable((Local) size); 479 var.addParent(resolver.typeVariable(IntType.v())); 480 } 481 } 482 } 483 else if(r instanceof NewExpr) 484 { 485 NewExpr na = (NewExpr) r; 486 487 right = resolver.typeVariable(na.getBaseType()); 488 } 489 else if(r instanceof NewMultiArrayExpr) 490 { 491 NewMultiArrayExpr nmae = (NewMultiArrayExpr) r; 492 493 right = resolver.typeVariable(nmae.getBaseType()); 494 495 if(uses) 496 { 497 for(int i = 0; i < nmae.getSizeCount(); i++) 498 { 499 Value size = nmae.getSize(i); 500 if(size instanceof Local) 501 { 502 TypeVariableBV var = resolver.typeVariable((Local) size); 503 var.addParent(resolver.typeVariable(IntType.v())); 504 } 505 } 506 } 507 } 508 else if(r instanceof LengthExpr) 509 { 510 LengthExpr le = (LengthExpr) r; 511 512 if(uses) 513 { 514 if(le.getOp() instanceof Local) 515 { 516 resolver.typeVariable((Local) le.getOp()).makeElement(); 517 } 518 } 519 520 right = resolver.typeVariable(IntType.v()); 521 } 522 else if(r instanceof NegExpr) 523 { 524 NegExpr ne = (NegExpr) r; 525 526 if(ne.getOp() instanceof Local) 527 { 528 right = resolver.typeVariable((Local) ne.getOp()); 529 } 530 else if(ne.getOp() instanceof DoubleConstant) 531 { 532 right = resolver.typeVariable(DoubleType.v()); 533 } 534 else if(ne.getOp() instanceof FloatConstant) 535 { 536 right = resolver.typeVariable(FloatType.v()); 537 } 538 else if(ne.getOp() instanceof IntConstant) 539 { 540 right = resolver.typeVariable(IntType.v()); 541 } 542 else if(ne.getOp() instanceof LongConstant) 543 { 544 right = resolver.typeVariable(LongType.v()); 545 } 546 else 547 { 548 throw new RuntimeException ("Unhandled neg expression operand type: " + ne.getOp().getClass()); 549 } 550 } 551 else if(r instanceof Local) 552 { 553 right = resolver.typeVariable((Local) r); 554 } 555 else if(r instanceof InstanceFieldRef) 556 { 557 InstanceFieldRef ref = (InstanceFieldRef) r; 558 559 if(uses) 560 { 561 TypeVariableBV baseType = resolver.typeVariable((Local) ref.getBase()); 562 baseType.addParent(resolver.typeVariable(ref.getField().getDeclaringClass())); 563 } 564 565 right = resolver.typeVariable(ref.getField().getType()); 566 } 567 else if(r instanceof StaticFieldRef) 568 { 569 StaticFieldRef ref = (StaticFieldRef) r; 570 571 right = resolver.typeVariable(ref.getField().getType()); 572 } 573 else 574 { 575 throw new RuntimeException ("Unhandled assignment right hand side type: " + r.getClass()); 576 } 577 578 if(left != null && right != null) 579 { 580 right.addParent(left); 581 } 582 } 583 584 public void caseIdentityStmt(IdentityStmt stmt) 585 { 586 Value l = stmt.getLeftOp(); 587 Value r = stmt.getRightOp(); 588 589 if(l instanceof Local) 590 { 591 TypeVariableBV left = resolver.typeVariable((Local) l); 592 593 if(!(r instanceof CaughtExceptionRef)) 594 { 595 TypeVariableBV right = resolver.typeVariable(r.getType()); 596 right.addParent(left); 597 } 598 else 599 { 600 List exceptionTypes = TrapManager.getExceptionTypesOf(stmt, stmtBody); 601 Iterator typeIt = exceptionTypes.iterator(); 602 603 while(typeIt.hasNext()) 604 { 605 Type t = (Type) typeIt.next(); 606 607 resolver.typeVariable(t).addParent(left); 608 } 609 610 if(uses) 611 { 612 left.addParent(resolver.typeVariable(RefType.v("java.lang.Throwable"))); 613 } 614 } 615 } 616 } 617 618 public void caseEnterMonitorStmt(EnterMonitorStmt stmt) 619 { 620 if(uses) 621 { 622 if(stmt.getOp() instanceof Local) 623 { 624 TypeVariableBV op = resolver.typeVariable((Local) stmt.getOp()); 625 626 op.addParent(resolver.typeVariable(RefType.v("java.lang.Object"))); 627 } 628 } 629 } 630 631 public void caseExitMonitorStmt(ExitMonitorStmt stmt) 632 { 633 if(uses) 634 { 635 if(stmt.getOp() instanceof Local) 636 { 637 TypeVariableBV op = resolver.typeVariable((Local) stmt.getOp()); 638 639 op.addParent(resolver.typeVariable(RefType.v("java.lang.Object"))); 640 } 641 } 642 } 643 644 public void caseGotoStmt(GotoStmt stmt) 645 { 646 } 647 648 public void caseIfStmt(IfStmt stmt) 649 { 650 if(uses) 651 { 652 ConditionExpr cond = (ConditionExpr) stmt.getCondition(); 653 654 BinopExpr expr = (BinopExpr) cond; 655 Value lv = expr.getOp1(); 656 Value rv = expr.getOp2(); 657 658 TypeVariableBV lop; 659 TypeVariableBV rop; 660 661 if(lv instanceof Local) 663 { 664 lop = resolver.typeVariable((Local) lv); 665 } 666 else if(lv instanceof DoubleConstant) 667 { 668 lop = resolver.typeVariable(DoubleType.v()); 669 } 670 else if(lv instanceof FloatConstant) 671 { 672 lop = resolver.typeVariable(FloatType.v()); 673 } 674 else if(lv instanceof IntConstant) 675 { 676 lop = resolver.typeVariable(IntType.v()); 677 } 678 else if(lv instanceof LongConstant) 679 { 680 lop = resolver.typeVariable(LongType.v()); 681 } 682 else if(lv instanceof NullConstant) 683 { 684 lop = resolver.typeVariable(NullType.v()); 685 } 686 else if(lv instanceof StringConstant) 687 { 688 lop = resolver.typeVariable(RefType.v("java.lang.String")); 689 } 690 else if(lv instanceof ClassConstant) 691 { 692 lop = resolver.typeVariable(RefType.v("java.lang.Class")); 693 } 694 else 695 { 696 throw new RuntimeException ("Unhandled binary expression left operand type: " + lv.getClass()); 697 } 698 699 if(rv instanceof Local) 701 { 702 rop = resolver.typeVariable((Local) rv); 703 } 704 else if(rv instanceof DoubleConstant) 705 { 706 rop = resolver.typeVariable(DoubleType.v()); 707 } 708 else if(rv instanceof FloatConstant) 709 { 710 rop = resolver.typeVariable(FloatType.v()); 711 } 712 else if(rv instanceof IntConstant) 713 { 714 rop = resolver.typeVariable(IntType.v()); 715 } 716 else if(rv instanceof LongConstant) 717 { 718 rop = resolver.typeVariable(LongType.v()); 719 } 720 else if(rv instanceof NullConstant) 721 { 722 rop = resolver.typeVariable(NullType.v()); 723 } 724 else if(rv instanceof StringConstant) 725 { 726 rop = resolver.typeVariable(RefType.v("java.lang.String")); 727 } 728 else if(rv instanceof ClassConstant) 729 { 730 rop = resolver.typeVariable(RefType.v("java.lang.Class")); 731 } 732 else 733 { 734 throw new RuntimeException ("Unhandled binary expression right operand type: " + rv.getClass()); 735 } 736 737 TypeVariableBV common = resolver.typeVariable(); 738 rop.addParent(common); 739 lop.addParent(common); 740 } 741 } 742 743 public void caseLookupSwitchStmt(LookupSwitchStmt stmt) 744 { 745 if(uses) 746 { 747 Value key = stmt.getKey(); 748 749 if(key instanceof Local) 750 { 751 resolver.typeVariable((Local) key).addParent(resolver.typeVariable(IntType.v())); 752 } 753 } 754 } 755 756 public void caseNopStmt(NopStmt stmt) 757 { 758 } 759 760 public void caseReturnStmt(ReturnStmt stmt) 761 { 762 if(uses) 763 { 764 if(stmt.getOp() instanceof Local) 765 { 766 resolver.typeVariable((Local) stmt.getOp()). 767 addParent(resolver.typeVariable(stmtBody.getMethod().getReturnType())); 768 } 769 } 770 } 771 772 public void caseReturnVoidStmt(ReturnVoidStmt stmt) 773 { 774 } 775 776 public void caseTableSwitchStmt(TableSwitchStmt stmt) 777 { 778 if(uses) 779 { 780 Value key = stmt.getKey(); 781 782 if(key instanceof Local) 783 { 784 resolver.typeVariable((Local) key).addParent(resolver.typeVariable(IntType.v())); 785 } 786 } 787 } 788 789 public void caseThrowStmt(ThrowStmt stmt) 790 { 791 if(uses) 792 { 793 if(stmt.getOp() instanceof Local) 794 { 795 TypeVariableBV op = resolver.typeVariable((Local) stmt.getOp()); 796 797 op.addParent(resolver.typeVariable(RefType.v("java.lang.Throwable"))); 798 } 799 } 800 } 801 802 public void defaultCase(Stmt stmt) 803 { 804 throw new RuntimeException ("Unhandled statement type: " + stmt.getClass()); 805 } 806 } 807 | Popular Tags |