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