1 19 20 package edu.umd.cs.findbugs.ba.npe; 21 22 import java.util.BitSet ; 23 import java.util.HashSet ; 24 import java.util.Iterator ; 25 import java.util.Set ; 26 27 import org.apache.bcel.Constants; 28 import org.apache.bcel.classfile.Method; 29 import org.apache.bcel.generic.CodeExceptionGen; 30 import org.apache.bcel.generic.Instruction; 31 import org.apache.bcel.generic.InstructionHandle; 32 import org.apache.bcel.generic.MethodGen; 33 import org.apache.bcel.generic.ObjectType; 34 35 import edu.umd.cs.findbugs.SystemProperties; 36 import edu.umd.cs.findbugs.annotations.CheckForNull; 37 import edu.umd.cs.findbugs.annotations.Nullable; 38 import edu.umd.cs.findbugs.ba.AnalysisContext; 39 import edu.umd.cs.findbugs.ba.AnalysisFeatures; 40 import edu.umd.cs.findbugs.ba.AssertionMethods; 41 import edu.umd.cs.findbugs.ba.BasicBlock; 42 import edu.umd.cs.findbugs.ba.CFG; 43 import edu.umd.cs.findbugs.ba.CFGBuilderException; 44 import edu.umd.cs.findbugs.ba.ClassContext; 45 import edu.umd.cs.findbugs.ba.Dataflow; 46 import edu.umd.cs.findbugs.ba.DataflowAnalysisException; 47 import edu.umd.cs.findbugs.ba.DataflowTestDriver; 48 import edu.umd.cs.findbugs.ba.DepthFirstSearch; 49 import edu.umd.cs.findbugs.ba.Edge; 50 import edu.umd.cs.findbugs.ba.EdgeTypes; 51 import edu.umd.cs.findbugs.ba.FrameDataflowAnalysis; 52 import edu.umd.cs.findbugs.ba.JavaClassAndMethod; 53 import edu.umd.cs.findbugs.ba.Location; 54 import edu.umd.cs.findbugs.ba.NullnessAnnotation; 55 import edu.umd.cs.findbugs.ba.NullnessAnnotationDatabase; 56 import edu.umd.cs.findbugs.ba.XFactory; 57 import edu.umd.cs.findbugs.ba.XMethod; 58 import edu.umd.cs.findbugs.ba.XMethodParameter; 59 import edu.umd.cs.findbugs.ba.vna.AvailableLoad; 60 import edu.umd.cs.findbugs.ba.vna.ValueNumber; 61 import edu.umd.cs.findbugs.ba.vna.ValueNumberDataflow; 62 import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame; 63 64 72 public class IsNullValueAnalysis 73 extends FrameDataflowAnalysis<IsNullValue, IsNullValueFrame> 74 implements EdgeTypes, IsNullValueAnalysisFeatures { 75 static final boolean DEBUG = SystemProperties.getBoolean("inva.debug"); 76 77 static { 78 if (DEBUG) System.out.println("inva.debug enabled"); 79 } 80 81 private MethodGen methodGen; 82 private IsNullValueFrameModelingVisitor visitor; 83 private ValueNumberDataflow vnaDataflow; 84 private int[] numNonExceptionSuccessorMap; 85 private Set <LocationWhereValueBecomesNull> locationWhereValueBecomesNullSet; 86 private final boolean trackValueNumbers; 87 88 private IsNullValueFrame lastFrame; 89 private IsNullValueFrame instanceOfFrame; 90 private IsNullValueFrame cachedEntryFact; 91 92 private JavaClassAndMethod classAndMethod; 93 94 public IsNullValueAnalysis(MethodGen methodGen, CFG cfg, ValueNumberDataflow vnaDataflow, DepthFirstSearch dfs, 95 AssertionMethods assertionMethods) { 96 super(dfs); 97 98 this.trackValueNumbers = AnalysisContext.currentAnalysisContext().getBoolProperty( 99 AnalysisFeatures.TRACK_VALUE_NUMBERS_IN_NULL_POINTER_ANALYSIS); 100 101 this.methodGen = methodGen; 102 this.visitor = new IsNullValueFrameModelingVisitor( 103 methodGen.getConstantPool(), 104 assertionMethods, 105 vnaDataflow, 106 trackValueNumbers); 107 this.vnaDataflow = vnaDataflow; 108 this.numNonExceptionSuccessorMap = new int[cfg.getNumBasicBlocks()]; 109 this.locationWhereValueBecomesNullSet = new HashSet <LocationWhereValueBecomesNull>(); 110 111 Iterator <Edge> i = cfg.edgeIterator(); 113 while (i.hasNext()) { 114 Edge edge = i.next(); 115 if (edge.isExceptionEdge()) 116 continue; 117 int srcBlockId = edge.getSource().getId(); 118 numNonExceptionSuccessorMap[srcBlockId]++; 119 } 120 if (DEBUG) { 121 System.out.println("IsNullValueAnalysis for " + methodGen.getClassName() + "." + methodGen.getName() + " : " + methodGen.getSignature()); 122 } 123 } 124 125 126 127 public void setClassAndMethod(JavaClassAndMethod classAndMethod) { 128 this.classAndMethod = classAndMethod; 129 } 130 public JavaClassAndMethod getClassAndMethod( ) { 131 return classAndMethod; 132 } 133 public IsNullValueFrame createFact() { 134 return new IsNullValueFrame(methodGen.getMaxLocals(), trackValueNumbers); 135 } 136 137 138 139 public void initEntryFact(IsNullValueFrame result) { 140 if (cachedEntryFact == null) { 141 142 cachedEntryFact = createFact(); 143 cachedEntryFact.setValid(); 144 145 int numLocals = methodGen.getMaxLocals(); 146 boolean instanceMethod = !methodGen.isStatic(); 147 XMethod xm = XFactory.createXMethod(methodGen.getClassName(), 148 methodGen.getName(), methodGen.getSignature(), methodGen.isStatic()); 149 NullnessAnnotationDatabase db = AnalysisContext.currentAnalysisContext().getNullnessAnnotationDatabase(); 150 int paramShift = instanceMethod ? 1 : 0; 151 for (int i = 0; i < numLocals; ++i) { 152 IsNullValue value; 153 154 int paramIndex = i - paramShift; 155 156 if (instanceMethod && i == 0) { 157 value = IsNullValue.nonNullValue(); 158 } else if (paramIndex >= methodGen.getArgumentTypes().length) { 159 value = IsNullValue.nonReportingNotNullValue(); 160 } else { 161 XMethodParameter methodParameter = new XMethodParameter(xm, paramIndex); 162 NullnessAnnotation n = db.getResolvedAnnotation(methodParameter, false); 163 if (n == NullnessAnnotation.CHECK_FOR_NULL) 164 value = IsNullValue.parameterMarkedAsMightBeNull(methodParameter); 166 else if (n == NullnessAnnotation.NONNULL) 167 value = IsNullValue.nonNullValue(); 170 else 171 value = IsNullValue.nonReportingNotNullValue(); 173 } 174 175 cachedEntryFact.setValue(i, value); 176 } 177 } 178 copy(cachedEntryFact, result); 179 } 180 181 182 @Override 183 public void transfer(BasicBlock basicBlock, @CheckForNull InstructionHandle end, IsNullValueFrame start, IsNullValueFrame result) 184 throws DataflowAnalysisException { 185 startTransfer(); 186 super.transfer(basicBlock, end, start, result); 187 endTransfer(basicBlock, end, result); 188 ValueNumberFrame vnaFrameAfter = vnaDataflow.getFactAfterLocation(Location.getLastLocation(basicBlock)); 189 if (!vnaFrameAfter.isTop()) 191 result.cleanStaleKnowledge(vnaFrameAfter); 192 } 193 194 public void startTransfer() throws DataflowAnalysisException { 195 lastFrame = null; 196 instanceOfFrame = null; 197 } 198 199 public void endTransfer(BasicBlock basicBlock, @CheckForNull InstructionHandle end, IsNullValueFrame result) 200 throws DataflowAnalysisException { 201 if (end == null) { 203 if (lastFrame == null) 204 result.setDecision(null); 205 else { 206 IsNullConditionDecision decision = getDecision(basicBlock, lastFrame); 207 result.setDecision(decision); 209 } 210 } 211 lastFrame = null; 212 instanceOfFrame = null; 213 } 214 215 @Override 216 public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, IsNullValueFrame fact) 217 throws DataflowAnalysisException { 218 219 if (handle == basicBlock.getLastInstruction()) { 222 lastFrame = createFact(); 223 lastFrame.copyFrom(fact); 224 } 225 226 if (handle.getInstruction().getOpcode() == Constants.INSTANCEOF) { 227 instanceOfFrame = createFact(); 228 instanceOfFrame.copyFrom(fact); 229 } 230 231 visitor.setFrameAndLocation(fact, new Location(handle, basicBlock)); 233 Instruction ins = handle.getInstruction(); 234 visitor.analyzeInstruction(ins); 235 236 243 int numProduced = ins.produceStack(methodGen.getConstantPool()); 244 if (numProduced == Constants.UNPREDICTABLE) 245 throw new DataflowAnalysisException("Unpredictable stack production", methodGen, handle); 246 247 int start = fact.getNumSlots() - numProduced; 248 Location location = new Location(handle, basicBlock); 249 ValueNumberFrame vnaFrameAfter = vnaDataflow.getFactAfterLocation(location); 250 251 for (int i = start; i < fact.getNumSlots(); ++i) { 252 ValueNumber value = vnaFrameAfter.getValue(i); 253 IsNullValue isNullValue = fact.getValue(i); 254 255 for (int j = 0; j < start; ++j) { 256 ValueNumber otherValue = vnaFrameAfter.getValue(j); 257 if (value.equals(otherValue)) { 258 fact.setValue(j, isNullValue); 262 } 263 } 264 } 265 266 if (visitor.getSlotContainingNewNullValue() >= 0) { 267 ValueNumber newNullValue = vnaFrameAfter.getValue(visitor.getSlotContainingNewNullValue()); 268 addLocationWhereValueBecomesNull(new LocationWhereValueBecomesNull( 269 location, 270 newNullValue )); 273 } 274 275 } 276 277 private static final BitSet nullComparisonInstructionSet = new BitSet (); 278 279 static { 280 nullComparisonInstructionSet.set(Constants.IFNULL); 281 282 nullComparisonInstructionSet.set(Constants.IFNONNULL); 283 nullComparisonInstructionSet.set(Constants.IF_ACMPEQ); 284 nullComparisonInstructionSet.set(Constants.IF_ACMPNE); 285 } 286 287 public void meetInto(IsNullValueFrame fact, Edge edge, IsNullValueFrame result) 288 throws DataflowAnalysisException { 289 290 if (fact.isValid()) { 291 IsNullValueFrame tmpFact = null; 292 293 final int numSlots = fact.getNumSlots(); 294 295 if (!NO_SPLIT_DOWNGRADE_NSP) { 296 if (!edge.isExceptionEdge() 298 && numNonExceptionSuccessorMap[edge.getSource().getId()] > 1) { 299 tmpFact = modifyFrame(fact, tmpFact); 300 tmpFact.downgradeOnControlSplit(); 301 } 302 } 303 304 if (!NO_SWITCH_DEFAULT_AS_EXCEPTION) { 305 if (edge.getType() == SWITCH_DEFAULT_EDGE) { 306 tmpFact = modifyFrame(fact, tmpFact); 307 tmpFact.toExceptionValues(); 308 } 309 } 310 311 final BasicBlock destBlock = edge.getTarget(); 312 313 if (destBlock.isExceptionHandler()) { 314 tmpFact = modifyFrame(fact, tmpFact); 317 tmpFact.clearStack(); 318 319 if (true) { 322 CodeExceptionGen handler = destBlock.getExceptionGen(); 323 ObjectType catchType = handler.getCatchType(); 324 if (catchType != null) { 325 String catchClass = catchType.getClassName(); 326 if (catchClass.equals("java.lang.CloneNotSupportedException") || 327 catchClass.equals("java.lang.InterruptedException")) { 328 for (int i = 0; i < tmpFact.getNumSlots(); ++i) { 329 IsNullValue value = tmpFact.getValue(i); 330 if (value.isDefinitelyNull() || value.isNullOnSomePath()) 331 tmpFact.setValue(i, IsNullValue.nullOnComplexPathValue()); 332 } 333 } 334 } 335 } 336 337 tmpFact.toExceptionValues(); 339 340 tmpFact.pushValue(IsNullValue.nonNullValue()); 342 } else { 343 final int edgeType = edge.getType(); 344 final BasicBlock sourceBlock = edge.getSource(); 345 final BasicBlock targetBlock = edge.getTarget(); 346 final ValueNumberFrame targetVnaFrame = vnaDataflow.getStartFact(destBlock); 347 final ValueNumberFrame sourceVnaFrame = vnaDataflow.getResultFact(sourceBlock); 348 349 350 assert targetVnaFrame != null; 351 352 if (edgeType == IFCMP_EDGE || edgeType == FALL_THROUGH_EDGE) { 355 IsNullConditionDecision decision = getResultFact(edge.getSource()).getDecision(); 356 if (decision != null) { 357 if (!decision.isEdgeFeasible(edgeType)) { 358 tmpFact = createFact(); 361 tmpFact.setTop(); 362 } else if (decision.getValue() != null) { 363 367 if (DEBUG) { 368 System.out.println("Updating edge information for " + decision.getValue()); 369 } 370 final Location atIf = new Location(sourceBlock.getLastInstruction(), sourceBlock); 371 final IsNullValueFrame prevIsNullValueFrame = getFactAtLocation(atIf); 373 final ValueNumberFrame prevVnaFrame = vnaDataflow.getFactAtLocation(atIf); 374 375 IsNullValue decisionValue = decision.getDecision(edgeType); 376 if (decisionValue != null) { 377 if (decisionValue.isDefinitelyNull()) { 378 addLocationWhereValueBecomesNull(new LocationWhereValueBecomesNull( 381 atIf, 382 decision.getValue() 383 )); 384 } 385 if (DEBUG) { 386 System.out.println("Set decision information"); 387 System.out.println(" " + decision.getValue() + " becomes " + decisionValue); 388 System.out.println(" prev available loads: " + prevVnaFrame.availableLoadMapAsString()); 389 System.out.println(" target available loads: " + targetVnaFrame.availableLoadMapAsString()); 390 } 391 tmpFact = replaceValues(fact, tmpFact, decision.getValue(), prevVnaFrame, 392 targetVnaFrame, decisionValue); 393 } 394 395 } 396 } 397 } 399 if (sourceBlock.isNullCheck() && edgeType == FALL_THROUGH_EDGE) { 402 ValueNumberFrame vnaFrame = vnaDataflow.getStartFact(destBlock); 403 if (vnaFrame == null) 404 throw new IllegalStateException ("no vna frame at block entry?"); 405 406 Instruction firstInDest = edge.getTarget().getFirstInstruction().getInstruction(); 407 408 409 IsNullValue instance = fact.getInstance(firstInDest, methodGen.getConstantPool()); 410 411 412 if (instance.isDefinitelyNull()) { 413 tmpFact = createFact(); 415 tmpFact.setTop(); 416 } 417 else if (!instance.isDefinitelyNotNull()) { 418 InstructionHandle kaBoomLocation = targetBlock.getFirstInstruction(); 421 ValueNumber replaceMe = vnaFrame.getInstance(firstInDest, methodGen.getConstantPool()); 422 IsNullValue noKaboomNonNullValue = IsNullValue.noKaboomNonNullValue( 423 new Location(kaBoomLocation, targetBlock) 424 ); 425 if (DEBUG) { 426 System.out.println("Start vna fact: " + vnaFrame); 427 System.out.println("inva fact: " + fact); 428 System.out.println("\nGenerated NoKaboom value for location " + kaBoomLocation); 429 System.out.println("Dereferenced " + instance); 430 System.out.println("On fall through from source block " + sourceBlock); 431 } 432 tmpFact = replaceValues(fact, tmpFact, replaceMe, vnaFrame, targetVnaFrame, noKaboomNonNullValue); 433 } 434 } 436 if (targetVnaFrame.phiNodeForLoads) { 437 if (DEBUG) 438 System.out.println("Is phi node for loads"); 439 for(ValueNumber v : fact.getKnownValues()) { 440 AvailableLoad loadForV = sourceVnaFrame.getLoad(v); 441 if (DEBUG) { 442 System.out.println(" " + v + " for " + loadForV); 443 } 444 if (loadForV != null) { 445 ValueNumber[] matchingValueNumbers = targetVnaFrame.getAvailableLoad(loadForV); 446 if (matchingValueNumbers != null) 447 for(ValueNumber v2 : matchingValueNumbers) { 448 tmpFact = modifyFrame(fact, tmpFact); 449 tmpFact.useNewValueNumberForLoad(v, v2); 450 if (DEBUG) System.out.println("For " + loadForV + " switch from " + v + " to " + v2); 451 } 452 } 453 454 } 455 } 456 } 457 if (tmpFact != null) 458 fact = tmpFact; 459 } 461 mergeInto(fact, result); 463 } 464 465 468 @Override 469 protected void mergeInto(IsNullValueFrame other, IsNullValueFrame result) throws DataflowAnalysisException { 470 if (other.isTop()) return; 471 if (result.isTop()) { 472 result.copyFrom(other); 473 return; 474 } 475 super.mergeInto(other, result); 476 if (trackValueNumbers) { 478 result.mergeKnownValuesWith(other); 479 } 480 481 } 482 483 486 @Override 487 public void startIteration() { 488 locationWhereValueBecomesNullSet.clear(); 492 } 493 494 public void addLocationWhereValueBecomesNull(LocationWhereValueBecomesNull locationWhereValueBecomesNull) { 495 locationWhereValueBecomesNullSet.add(locationWhereValueBecomesNull); 497 } 498 499 public Set <LocationWhereValueBecomesNull> getLocationWhereValueBecomesNullSet() { 500 return locationWhereValueBecomesNullSet; 501 } 502 503 @Override 504 protected void mergeValues(IsNullValueFrame otherFrame, IsNullValueFrame resultFrame, int slot) 505 throws DataflowAnalysisException { 506 IsNullValue value = IsNullValue.merge(resultFrame.getValue(slot), otherFrame.getValue(slot)); 507 resultFrame.setValue(slot, value); 508 } 509 510 521 private IsNullConditionDecision getDecision(BasicBlock basicBlock, IsNullValueFrame lastFrame) 522 throws DataflowAnalysisException { 523 524 assert lastFrame != null; 525 526 final InstructionHandle lastInSourceHandle = basicBlock.getLastInstruction(); 527 if (lastInSourceHandle == null) 528 return null; 530 final short lastInSourceOpcode = lastInSourceHandle.getInstruction().getOpcode(); 531 if (lastInSourceOpcode == Constants.IFEQ || lastInSourceOpcode == Constants.IFNE ) { 533 InstructionHandle prev = lastInSourceHandle.getPrev(); 534 if (prev == null) return null; 535 short secondToLastOpcode = prev.getInstruction().getOpcode(); 536 if (secondToLastOpcode != Constants.INSTANCEOF) return null; 538 IsNullValue tos = instanceOfFrame.getTopValue(); 539 boolean isNotInstanceOf = (lastInSourceOpcode != Constants.IFNE); 540 Location atInstanceOf = new Location(prev, basicBlock); 541 ValueNumberFrame instanceOfVnaFrame = vnaDataflow.getFactAtLocation(atInstanceOf); 542 543 IsNullValue ifcmpDecision = null; 545 IsNullValue fallThroughDecision = null; 546 547 if (tos.isDefinitelyNull()) { 548 if (isNotInstanceOf) 550 ifcmpDecision =tos; 551 else fallThroughDecision = tos; 553 } else if (tos.isDefinitelyNotNull()) { 554 return null; 555 } else { 556 ifcmpDecision = isNotInstanceOf ? tos : IsNullValue.pathSensitiveNonNullValue(); 558 fallThroughDecision = isNotInstanceOf ? IsNullValue.pathSensitiveNonNullValue() : tos; 559 } 560 if (DEBUG) System.out.println("Checking..." + tos + " -> " + ifcmpDecision + " or " + fallThroughDecision); 561 562 return new IsNullConditionDecision(instanceOfVnaFrame.getTopValue(), ifcmpDecision, fallThroughDecision); 563 564 } 565 if (!nullComparisonInstructionSet.get(lastInSourceOpcode)) 566 return null; 568 Location atIf = new Location(lastInSourceHandle, basicBlock); 569 ValueNumberFrame prevVnaFrame = vnaDataflow.getFactAtLocation(atIf); 570 571 switch (lastInSourceOpcode) { 572 573 case Constants.IFNULL: 574 case Constants.IFNONNULL: 575 { 576 IsNullValue tos = lastFrame.getTopValue(); 577 boolean ifnull = (lastInSourceOpcode == Constants.IFNULL); 578 579 IsNullValue ifcmpDecision = null; 581 IsNullValue fallThroughDecision = null; 582 583 if (tos.isDefinitelyNull()) { 584 if (ifnull) 586 ifcmpDecision = IsNullValue.pathSensitiveNullValue(); 587 else fallThroughDecision = IsNullValue.pathSensitiveNullValue(); 589 } else if (tos.isDefinitelyNotNull()) { 590 if (ifnull) 592 fallThroughDecision = IsNullValue.pathSensitiveNonNullValue(); 593 else ifcmpDecision = IsNullValue.pathSensitiveNonNullValue(); 595 } else { 596 ifcmpDecision = ifnull ? IsNullValue.pathSensitiveNullValue() : IsNullValue.pathSensitiveNonNullValue(); 598 fallThroughDecision = ifnull ? IsNullValue.pathSensitiveNonNullValue() : IsNullValue.pathSensitiveNullValue(); 599 } 600 return new IsNullConditionDecision(prevVnaFrame.getTopValue(), ifcmpDecision, fallThroughDecision); 601 } 602 case Constants.IF_ACMPEQ: 603 case Constants.IF_ACMPNE: 604 { 605 IsNullValue tos = lastFrame.getStackValue(0); 606 IsNullValue nextToTos = lastFrame.getStackValue(1); 607 608 boolean tosNull = tos.isDefinitelyNull(); 609 boolean nextToTosNull = nextToTos.isDefinitelyNull(); 610 611 boolean cmpeq = (lastInSourceOpcode == Constants.IF_ACMPEQ); 612 613 IsNullValue ifcmpDecision = null; 615 IsNullValue fallThroughDecision = null; 616 ValueNumber value; 617 618 if (tosNull && nextToTosNull) { 619 value = null; if (cmpeq) 622 ifcmpDecision = IsNullValue.pathSensitiveNullValue(); 623 else fallThroughDecision = IsNullValue.pathSensitiveNullValue(); 625 } else if (tosNull || nextToTosNull) { 626 value = prevVnaFrame.getStackValue(tosNull ? 1 : 0); 629 ifcmpDecision = cmpeq ? IsNullValue.pathSensitiveNullValue() : IsNullValue.pathSensitiveNonNullValue(); 630 fallThroughDecision = cmpeq ? IsNullValue.pathSensitiveNonNullValue() : IsNullValue.pathSensitiveNullValue(); 631 } else if (tos.isDefinitelyNotNull() && !nextToTos.isDefinitelyNotNull()) { 632 value = prevVnaFrame.getStackValue(1); 634 if (cmpeq) { 635 ifcmpDecision = tos; 636 fallThroughDecision = nextToTos; 637 } else { 638 fallThroughDecision = tos; 639 ifcmpDecision = nextToTos; 640 } 641 } else if (!tos.isDefinitelyNotNull() && nextToTos.isDefinitelyNotNull()) { 642 value = prevVnaFrame.getStackValue(0); 644 if (cmpeq) { 645 ifcmpDecision = nextToTos; 646 fallThroughDecision = tos; 647 } else { 648 fallThroughDecision = nextToTos; 649 ifcmpDecision = tos; 650 } 651 } else { 652 break; 654 } 655 656 return new IsNullConditionDecision(value, ifcmpDecision, fallThroughDecision); 657 } 658 default: 659 throw new IllegalStateException (); 660 } 661 662 return null; } 664 665 680 private IsNullValueFrame replaceValues(IsNullValueFrame origFrame, IsNullValueFrame frame, 681 ValueNumber replaceMe, ValueNumberFrame prevVnaFrame, ValueNumberFrame targetVnaFrame, 682 IsNullValue replacementValue) { 683 684 frame = modifyFrame(origFrame, frame); 686 687 assert frame.getNumSlots() == targetVnaFrame.getNumSlots(); 688 689 693 final int targetNumSlots = targetVnaFrame.getNumSlots(); 694 final int prefixNumSlots = Math.min(frame.getNumSlots(), prevVnaFrame.getNumSlots()); 695 696 if (trackValueNumbers) { 697 AvailableLoad loadForV = prevVnaFrame.getLoad(replaceMe); 698 if (DEBUG && loadForV != null) { 699 System.out.println("For " + replaceMe + " availableLoad is " + loadForV); 700 ValueNumber[] matchingValueNumbers = targetVnaFrame.getAvailableLoad(loadForV); 701 if (matchingValueNumbers != null) 702 for(ValueNumber v2 : matchingValueNumbers) System.out.println(" matches " + v2); 703 } 704 if (loadForV != null) { 705 ValueNumber[] matchingValueNumbers = targetVnaFrame.getAvailableLoad(loadForV); 706 if (matchingValueNumbers != null) 707 for(ValueNumber v2 : matchingValueNumbers) if (!replaceMe.equals(v2)) { 708 frame.setKnownValue(v2, replacementValue); 709 if (DEBUG) System.out.println("For " + loadForV + " switch from " + replaceMe + " to " + v2); 710 } 711 } 712 frame.setKnownValue(replaceMe, replacementValue); 713 } 714 724 for (int i = 0; i < prefixNumSlots; ++i) { 725 if (prevVnaFrame.getValue(i).equals(replaceMe)) { 726 ValueNumber corresponding = targetVnaFrame.getValue(i); 727 for (int j = 0; j < targetNumSlots; ++j) { 728 if (targetVnaFrame.getValue(j).equals(corresponding)) 729 frame.setValue(j, replacementValue); 730 } 731 } 732 } 733 734 return frame; 735 736 } 737 738 741 public static void main(String [] argv) throws Exception { 742 if (argv.length != 1) { 743 System.err.println("Usage: " + IsNullValueAnalysis.class.getName() + " <class file>"); 744 System.exit(1); 745 } 746 747 DataflowTestDriver<IsNullValueFrame, IsNullValueAnalysis> driver = new DataflowTestDriver<IsNullValueFrame, IsNullValueAnalysis>() { 748 @Override 749 public Dataflow<IsNullValueFrame, IsNullValueAnalysis> createDataflow(ClassContext classContext, Method method) 750 throws CFGBuilderException, DataflowAnalysisException { 751 752 return classContext.getIsNullValueDataflow(method); 753 } 754 }; 755 756 driver.execute(argv[0]); 757 } 758 759 } 760 761 | Popular Tags |