1 19 20 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 34 class ConstraintCollector extends AbstractStmtSwitch 35 { 36 private TypeResolver resolver; 37 private boolean uses; 39 private JimpleBody stmtBody; 40 41 public ConstraintCollector(TypeResolver resolver, boolean uses) 42 { 43 this.resolver = resolver; 44 this.uses = uses; 45 } 46 47 public void collect(Stmt stmt, JimpleBody stmtBody) 48 { 49 this.stmtBody = stmtBody; 50 stmt.apply(this); 51 } 52 private void handleInvokeExpr(InvokeExpr ie) 53 { 54 if(!uses) 55 return; 56 57 if(ie instanceof InterfaceInvokeExpr) 58 { 59 InterfaceInvokeExpr invoke = (InterfaceInvokeExpr) ie; 60 SootMethodRef method = invoke.getMethodRef(); 61 int count = invoke.getArgCount(); 62 63 for(int i = 0; i < count; i++) 64 { 65 if(invoke.getArg(i) instanceof Local) 66 { 67 Local local = (Local) invoke.getArg(i); 68 69 if(local.getType() instanceof IntegerType) 70 { 71 TypeVariable localType = resolver.typeVariable(local); 72 73 localType.addParent(resolver.typeVariable(method.parameterType(i))); 74 } 75 } 76 } 77 } 78 else if(ie instanceof SpecialInvokeExpr) 79 { 80 SpecialInvokeExpr invoke = (SpecialInvokeExpr) ie; 81 SootMethodRef method = invoke.getMethodRef(); 82 int count = invoke.getArgCount(); 83 84 for(int i = 0; i < count; i++) 85 { 86 if(invoke.getArg(i) instanceof Local) 87 { 88 Local local = (Local) invoke.getArg(i); 89 90 if(local.getType() instanceof IntegerType) 91 { 92 TypeVariable localType = resolver.typeVariable(local); 93 94 localType.addParent(resolver.typeVariable(method.parameterType(i))); 95 } 96 } 97 } 98 } 99 else if(ie instanceof VirtualInvokeExpr) 100 { 101 VirtualInvokeExpr invoke = (VirtualInvokeExpr) ie; 102 SootMethodRef method = invoke.getMethodRef(); 103 int count = invoke.getArgCount(); 104 105 for(int i = 0; i < count; i++) 106 { 107 if(invoke.getArg(i) instanceof Local) 108 { 109 Local local = (Local) invoke.getArg(i); 110 111 if(local.getType() instanceof IntegerType) 112 { 113 TypeVariable localType = resolver.typeVariable(local); 114 115 localType.addParent(resolver.typeVariable(method.parameterType(i))); 116 } 117 } 118 } 119 } 120 else if(ie instanceof StaticInvokeExpr) 121 { 122 StaticInvokeExpr invoke = (StaticInvokeExpr) ie; 123 SootMethodRef method = invoke.getMethodRef(); 124 int count = invoke.getArgCount(); 125 126 for(int i = 0; i < count; i++) 127 { 128 if(invoke.getArg(i) instanceof Local) 129 { 130 Local local = (Local) invoke.getArg(i); 131 132 if(local.getType() instanceof IntegerType) 133 { 134 TypeVariable localType = resolver.typeVariable(local); 135 136 localType.addParent(resolver.typeVariable(method.parameterType(i))); 137 } 138 } 139 } 140 } 141 else 142 { 143 throw new RuntimeException ("Unhandled invoke expression type: " + ie.getClass()); 144 } 145 } 146 147 public void caseBreakpointStmt(BreakpointStmt stmt) 148 { 149 } 151 152 public void caseInvokeStmt(InvokeStmt stmt) 153 { 154 handleInvokeExpr((InvokeExpr) stmt.getInvokeExpr()); 155 } 156 157 public void caseAssignStmt(AssignStmt stmt) 158 { 159 Value l = stmt.getLeftOp(); 160 Value r = stmt.getRightOp(); 161 162 TypeVariable left = null; 163 TypeVariable right = null; 164 165 167 if(l instanceof ArrayRef) 168 { 169 ArrayRef ref = (ArrayRef) l; 170 Type baset = ((Local) ref.getBase()).getType(); 171 if(!(baset instanceof NullType)) 172 { 173 ArrayType base = (ArrayType) baset; 174 Value index = ref.getIndex(); 175 176 if(uses) 177 { 178 if((base.numDimensions == 1) && 179 (base.baseType instanceof IntegerType)) 180 { 181 left = resolver.typeVariable(base.baseType); 182 } 183 184 if(index instanceof Local) 185 { 186 resolver.typeVariable((Local) index).addParent(resolver.INT); 187 } 188 } 189 } 190 } 191 else if(l instanceof Local) 192 { 193 if(((Local) l).getType() instanceof IntegerType) 194 { 195 left = resolver.typeVariable((Local) l); 196 } 197 } 198 else if(l instanceof InstanceFieldRef) 199 { 200 if(uses) 201 { 202 InstanceFieldRef ref = (InstanceFieldRef) l; 203 204 Type fieldType = ref.getField().getType(); 205 206 if(fieldType instanceof IntegerType) 207 { 208 left = resolver.typeVariable(ref.getField().getType()); 209 } 210 } 211 } 212 else if(l instanceof StaticFieldRef) 213 { 214 if(uses) 215 { 216 StaticFieldRef ref = (StaticFieldRef) l; 217 218 Type fieldType = ref.getField().getType(); 219 220 if(fieldType instanceof IntegerType) 221 { 222 left = resolver.typeVariable(ref.getField().getType()); 223 } 224 } 225 } 226 else 227 { 228 throw new RuntimeException ("Unhandled assignment left hand side type: " + l.getClass()); 229 } 230 231 233 if(r instanceof ArrayRef) 234 { 235 ArrayRef ref = (ArrayRef) r; 236 Type baset = ((Local) ref.getBase()).getType(); 237 if(!(baset instanceof NullType)) 238 { 239 ArrayType base = (ArrayType) baset; 240 Value index = ref.getIndex(); 241 242 if((base.numDimensions == 1) && 243 (base.baseType instanceof IntegerType)) 244 { 245 right = resolver.typeVariable(base.baseType); 246 } 247 248 if(uses) 249 { 250 if(index instanceof Local) 251 { 252 resolver.typeVariable((Local) index).addParent(resolver.INT); 253 } 254 } 255 } 256 } 257 else if(r instanceof DoubleConstant) 258 { 259 } 260 else if(r instanceof FloatConstant) 261 { 262 } 263 else if(r instanceof IntConstant) 264 { 265 int value = ((IntConstant) r).value; 266 267 if(value < -32768) 268 { 269 right = resolver.INT; 270 } 271 else if(value < -128) 272 { 273 right = resolver.SHORT; 274 } 275 else if(value < 0) 276 { 277 right = resolver.BYTE; 278 } 279 else if(value < 2) 280 { 281 right = resolver.R0_1; 282 } 283 else if(value < 128) 284 { 285 right = resolver.R0_127; 286 } 287 else if(value < 32768) 288 { 289 right = resolver.R0_32767; 290 } 291 else if(value < 65536) 292 { 293 right = resolver.CHAR; 294 } 295 else 296 { 297 right = resolver.INT; 298 } 299 } 300 else if(r instanceof LongConstant) 301 { 302 } 303 else if(r instanceof NullConstant) 304 { 305 } 306 else if(r instanceof StringConstant) 307 { 308 } 309 else if(r instanceof ClassConstant) 310 { 311 } 312 else if(r instanceof BinopExpr) 313 { 314 316 BinopExpr be = (BinopExpr) r; 317 318 Value lv = be.getOp1(); 319 Value rv = be.getOp2(); 320 321 TypeVariable lop = null; 322 TypeVariable rop = null; 323 324 if(lv instanceof Local) 326 { 327 if(((Local) lv).getType() instanceof IntegerType) 328 { 329 lop = resolver.typeVariable((Local) lv); 330 } 331 } 332 else if(lv instanceof DoubleConstant) 333 { 334 } 335 else if(lv instanceof FloatConstant) 336 { 337 } 338 else if(lv instanceof IntConstant) 339 { 340 int value = ((IntConstant) lv).value; 341 342 if(value < -32768) 343 { 344 lop = resolver.INT; 345 } 346 else if(value < -128) 347 { 348 lop = resolver.SHORT; 349 } 350 else if(value < 0) 351 { 352 lop = resolver.BYTE; 353 } 354 else if(value < 2) 355 { 356 lop = resolver.R0_1; 357 } 358 else if(value < 128) 359 { 360 lop = resolver.R0_127; 361 } 362 else if(value < 32768) 363 { 364 lop = resolver.R0_32767; 365 } 366 else if(value < 65536) 367 { 368 lop = resolver.CHAR; 369 } 370 else 371 { 372 lop = resolver.INT; 373 } 374 } 375 else if(lv instanceof LongConstant) 376 { 377 } 378 else if(lv instanceof NullConstant) 379 { 380 } 381 else if(lv instanceof StringConstant) 382 { 383 } 384 else if(lv instanceof ClassConstant) 385 { 386 } 387 else 388 { 389 throw new RuntimeException ("Unhandled binary expression left operand type: " + lv.getClass()); 390 } 391 392 if(rv instanceof Local) 394 { 395 if(((Local) rv).getType() instanceof IntegerType) 396 { 397 rop = resolver.typeVariable((Local) rv); 398 } 399 } 400 else if(rv instanceof DoubleConstant) 401 { 402 } 403 else if(rv instanceof FloatConstant) 404 { 405 } 406 else if(rv instanceof IntConstant) 407 { 408 int value = ((IntConstant) rv).value; 409 410 if(value < -32768) 411 { 412 rop = resolver.INT; 413 } 414 else if(value < -128) 415 { 416 rop = resolver.SHORT; 417 } 418 else if(value < 0) 419 { 420 rop = resolver.BYTE; 421 } 422 else if(value < 2) 423 { 424 rop = resolver.R0_1; 425 } 426 else if(value < 128) 427 { 428 rop = resolver.R0_127; 429 } 430 else if(value < 32768) 431 { 432 rop = resolver.R0_32767; 433 } 434 else if(value < 65536) 435 { 436 rop = resolver.CHAR; 437 } 438 else 439 { 440 rop = resolver.INT; 441 } 442 } 443 else if(rv instanceof LongConstant) 444 { 445 } 446 else if(rv instanceof NullConstant) 447 { 448 } 449 else if(rv instanceof StringConstant) 450 { 451 } 452 else if(rv instanceof ClassConstant) 453 { 454 } 455 else 456 { 457 throw new RuntimeException ("Unhandled binary expression right operand type: " + rv.getClass()); 458 } 459 460 if((be instanceof AddExpr) || 461 (be instanceof SubExpr) || 462 (be instanceof DivExpr) || 463 (be instanceof RemExpr) || 464 (be instanceof MulExpr)) 465 { 466 if(lop != null && rop != null) 467 { 468 if(uses) 469 { 470 if(lop.type() == null) 471 { 472 lop.addParent(resolver.INT); 473 } 474 475 if(rop.type() == null) 476 { 477 rop.addParent(resolver.INT); 478 } 479 } 480 481 right = resolver.INT; 482 } 483 } 484 else if((be instanceof AndExpr) || 485 (be instanceof OrExpr) || 486 (be instanceof XorExpr)) 487 { 488 if(lop != null && rop != null) 489 { 490 TypeVariable common = resolver.typeVariable(); 491 rop.addParent(common); 492 lop.addParent(common); 493 494 right = common; 495 } 496 } 497 else if(be instanceof ShlExpr) 498 { 499 if(uses) 500 { 501 if(lop != null && lop.type() == null) 502 { 503 lop.addParent(resolver.INT); 504 } 505 506 if(rop.type() == null) 507 { 508 rop.addParent(resolver.INT); 509 } 510 } 511 512 right = (lop == null) ? null : resolver.INT; 513 } 514 else if((be instanceof ShrExpr) || 515 (be instanceof UshrExpr)) 516 { 517 if(uses) 518 { 519 if(lop != null && lop.type() == null) 520 { 521 lop.addParent(resolver.INT); 522 } 523 524 if(rop.type() == null) 525 { 526 rop.addParent(resolver.INT); 527 } 528 } 529 530 right = lop; 531 } 532 else if((be instanceof CmpExpr) || 533 (be instanceof CmpgExpr) || 534 (be instanceof CmplExpr)) 535 { 536 right = resolver.BYTE; 537 } 538 else if((be instanceof EqExpr) || 539 (be instanceof GeExpr) || 540 (be instanceof GtExpr) || 541 (be instanceof LeExpr) || 542 (be instanceof LtExpr) || 543 (be instanceof NeExpr)) 544 { 545 if(uses) 546 { 547 TypeVariable common = resolver.typeVariable(); 548 rop.addParent(common); 549 lop.addParent(common); 550 } 551 552 right = resolver.BOOLEAN; 553 } 554 else 555 { 556 throw new RuntimeException ("Unhandled binary expression type: " + be.getClass()); 557 } 558 } 559 else if(r instanceof CastExpr) 560 { 561 CastExpr ce = (CastExpr) r; 562 563 if(ce.getCastType() instanceof IntegerType) 564 { 565 right = resolver.typeVariable(ce.getCastType()); 566 } 567 } 568 else if(r instanceof InstanceOfExpr) 569 { 570 InstanceOfExpr ioe = (InstanceOfExpr) r; 571 572 right = resolver.BOOLEAN; 573 } 574 else if(r instanceof InvokeExpr) 575 { 576 InvokeExpr ie = (InvokeExpr) r; 577 578 handleInvokeExpr(ie); 579 580 if(ie.getMethodRef().returnType() instanceof IntegerType) 581 { 582 right = resolver.typeVariable(ie.getMethodRef().returnType()); 583 } 584 } 585 else if(r instanceof NewArrayExpr) 586 { 587 NewArrayExpr nae = (NewArrayExpr) r; 588 589 if(uses) 590 { 591 Value size = nae.getSize(); 592 if(size instanceof Local) 593 { 594 TypeVariable var = resolver.typeVariable((Local) size); 595 var.addParent(resolver.INT); 596 } 597 } 598 } 599 else if(r instanceof NewExpr) 600 { 601 } 602 else if(r instanceof NewMultiArrayExpr) 603 { 604 NewMultiArrayExpr nmae = (NewMultiArrayExpr) r; 605 606 if(uses) 607 { 608 for(int i = 0; i < nmae.getSizeCount(); i++) 609 { 610 Value size = nmae.getSize(i); 611 if(size instanceof Local) 612 { 613 TypeVariable var = resolver.typeVariable((Local) size); 614 var.addParent(resolver.INT); 615 } 616 } 617 } 618 } 619 else if(r instanceof LengthExpr) 620 { 621 LengthExpr le = (LengthExpr) r; 622 623 right = resolver.INT; 624 } 625 else if(r instanceof NegExpr) 626 { 627 NegExpr ne = (NegExpr) r; 628 629 if(ne.getOp() instanceof Local) 630 { 631 Local local = (Local) ne.getOp(); 632 633 if(local.getType() instanceof IntegerType) 634 { 635 if(uses) 636 { 637 resolver.typeVariable(local).addParent(resolver.INT); 638 } 639 640 TypeVariable v = resolver.typeVariable(); 641 v.addChild(resolver.BYTE); 642 v.addChild(resolver.typeVariable(local)); 643 right = v; 644 } 645 } 646 else if(ne.getOp() instanceof DoubleConstant) 647 { 648 } 649 else if(ne.getOp() instanceof FloatConstant) 650 { 651 } 652 else if(ne.getOp() instanceof IntConstant) 653 { 654 int value = ((IntConstant) ne.getOp()).value; 655 656 if(value < -32768) 657 { 658 right = resolver.INT; 659 } 660 else if(value < -128) 661 { 662 right = resolver.SHORT; 663 } 664 else if(value < 0) 665 { 666 right = resolver.BYTE; 667 } 668 else if(value < 2) 669 { 670 right = resolver.BYTE; 671 } 672 else if(value < 128) 673 { 674 right = resolver.BYTE; 675 } 676 else if(value < 32768) 677 { 678 right = resolver.SHORT; 679 } 680 else if(value < 65536) 681 { 682 right = resolver.INT; 683 } 684 else 685 { 686 right = resolver.INT; 687 } 688 } 689 else if(ne.getOp() instanceof LongConstant) 690 { 691 } 692 else 693 { 694 throw new RuntimeException ("Unhandled neg expression operand type: " + ne.getOp().getClass()); 695 } 696 } 697 else if(r instanceof Local) 698 { 699 Local local = (Local) r; 700 701 if(local.getType() instanceof IntegerType) 702 { 703 right = resolver.typeVariable(local); 704 } 705 } 706 else if(r instanceof InstanceFieldRef) 707 { 708 InstanceFieldRef ref = (InstanceFieldRef) r; 709 710 if(ref.getField().getType() instanceof IntegerType) 711 { 712 right = resolver.typeVariable(ref.getField().getType()); 713 } 714 } 715 else if(r instanceof StaticFieldRef) 716 { 717 StaticFieldRef ref = (StaticFieldRef) r; 718 719 if(ref.getField().getType() instanceof IntegerType) 720 { 721 right = resolver.typeVariable(ref.getField().getType()); 722 } 723 } 724 else 725 { 726 throw new RuntimeException ("Unhandled assignment right hand side type: " + r.getClass()); 727 } 728 729 if(left != null && right != null && 730 (left.type() == null || right.type() == null)) 731 { 732 right.addParent(left); 733 } 734 } 735 736 public void caseIdentityStmt(IdentityStmt stmt) 737 { 738 Value l = stmt.getLeftOp(); 739 Value r = stmt.getRightOp(); 740 741 if(l instanceof Local) 742 { 743 if(((Local) l).getType() instanceof IntegerType) 744 { 745 TypeVariable left = resolver.typeVariable((Local) l); 746 747 TypeVariable right = resolver.typeVariable(r.getType()); 748 right.addParent(left); 749 } 750 } 751 } 752 753 public void caseEnterMonitorStmt(EnterMonitorStmt stmt) 754 { 755 } 756 757 public void caseExitMonitorStmt(ExitMonitorStmt stmt) 758 { 759 } 760 761 public void caseGotoStmt(GotoStmt stmt) 762 { 763 } 764 765 public void caseIfStmt(IfStmt stmt) 766 { 767 if(uses) 768 { 769 ConditionExpr cond = (ConditionExpr) stmt.getCondition(); 770 771 BinopExpr expr = (BinopExpr) cond; 772 Value lv = expr.getOp1(); 773 Value rv = expr.getOp2(); 774 775 TypeVariable lop = null; 776 TypeVariable rop = null; 777 778 if(lv instanceof Local) 780 { 781 if(((Local) lv).getType() instanceof IntegerType) 782 { 783 lop = resolver.typeVariable((Local) lv); 784 } 785 } 786 else if(lv instanceof DoubleConstant) 787 { 788 } 789 else if(lv instanceof FloatConstant) 790 { 791 } 792 else if(lv instanceof IntConstant) 793 { 794 int value = ((IntConstant) lv).value; 795 796 if(value < -32768) 797 { 798 lop = resolver.INT; 799 } 800 else if(value < -128) 801 { 802 lop = resolver.SHORT; 803 } 804 else if(value < 0) 805 { 806 lop = resolver.BYTE; 807 } 808 else if(value < 2) 809 { 810 lop = resolver.R0_1; 811 } 812 else if(value < 128) 813 { 814 lop = resolver.R0_127; 815 } 816 else if(value < 32768) 817 { 818 lop = resolver.R0_32767; 819 } 820 else if(value < 65536) 821 { 822 lop = resolver.CHAR; 823 } 824 else 825 { 826 lop = resolver.INT; 827 } 828 } 829 else if(lv instanceof LongConstant) 830 { 831 } 832 else if(lv instanceof NullConstant) 833 { 834 } 835 else if(lv instanceof StringConstant) 836 { 837 } 838 else if(lv instanceof ClassConstant) 839 { 840 } 841 else 842 { 843 throw new RuntimeException ("Unhandled binary expression left operand type: " + lv.getClass()); 844 } 845 846 if(rv instanceof Local) 848 { 849 if(((Local) rv).getType() instanceof IntegerType) 850 { 851 rop = resolver.typeVariable((Local) rv); 852 } 853 } 854 else if(rv instanceof DoubleConstant) 855 { 856 } 857 else if(rv instanceof FloatConstant) 858 { 859 } 860 else if(rv instanceof IntConstant) 861 { 862 int value = ((IntConstant) rv).value; 863 864 if(value < -32768) 865 { 866 rop = resolver.INT; 867 } 868 else if(value < -128) 869 { 870 rop = resolver.SHORT; 871 } 872 else if(value < 0) 873 { 874 rop = resolver.BYTE; 875 } 876 else if(value < 2) 877 { 878 rop = resolver.R0_1; 879 } 880 else if(value < 128) 881 { 882 rop = resolver.R0_127; 883 } 884 else if(value < 32768) 885 { 886 rop = resolver.R0_32767; 887 } 888 else if(value < 65536) 889 { 890 rop = resolver.CHAR; 891 } 892 else 893 { 894 rop = resolver.INT; 895 } 896 } 897 else if(rv instanceof LongConstant) 898 { 899 } 900 else if(rv instanceof NullConstant) 901 { 902 } 903 else if(rv instanceof StringConstant) 904 { 905 } 906 else if(rv instanceof ClassConstant) 907 { 908 } 909 else 910 { 911 throw new RuntimeException ("Unhandled binary expression right operand type: " + rv.getClass()); 912 } 913 914 if(rop != null && lop != null) 915 { 916 TypeVariable common = resolver.typeVariable(); 917 rop.addParent(common); 918 lop.addParent(common); 919 } 920 } 921 } 922 923 public void caseLookupSwitchStmt(LookupSwitchStmt stmt) 924 { 925 if(uses) 926 { 927 Value key = stmt.getKey(); 928 929 if(key instanceof Local) 930 { 931 resolver.typeVariable((Local) key).addParent(resolver.INT); 932 } 933 } 934 } 935 936 public void caseNopStmt(NopStmt stmt) 937 { 938 } 939 940 public void caseReturnStmt(ReturnStmt stmt) 941 { 942 if(uses) 943 { 944 if(stmt.getOp() instanceof Local) 945 { 946 if(((Local) stmt.getOp()).getType() instanceof IntegerType) 947 { 948 resolver.typeVariable((Local) stmt.getOp()). 949 addParent(resolver.typeVariable(stmtBody.getMethod().getReturnType())); 950 } 951 } 952 } 953 } 954 955 public void caseReturnVoidStmt(ReturnVoidStmt stmt) 956 { 957 } 958 959 public void caseTableSwitchStmt(TableSwitchStmt stmt) 960 { 961 if(uses) 962 { 963 Value key = stmt.getKey(); 964 965 if(key instanceof Local) 966 { 967 resolver.typeVariable((Local) key).addParent(resolver.INT); 968 } 969 } 970 } 971 972 public void caseThrowStmt(ThrowStmt stmt) 973 { 974 } 975 976 public void defaultCase(Stmt stmt) 977 { 978 throw new RuntimeException ("Unhandled statement type: " + stmt.getClass()); 979 } 980 } 981 | Popular Tags |