1 19 20 package edu.umd.cs.findbugs.ba.deref; 21 22 import java.util.BitSet ; 23 import java.util.Set ; 24 25 import org.apache.bcel.classfile.Method; 26 import org.apache.bcel.generic.ATHROW; 27 import org.apache.bcel.generic.InstructionHandle; 28 import org.apache.bcel.generic.InvokeInstruction; 29 import org.apache.bcel.generic.MethodGen; 30 31 import edu.umd.cs.findbugs.SystemProperties; 32 import edu.umd.cs.findbugs.annotations.CheckForNull; 33 import edu.umd.cs.findbugs.ba.AnalysisContext; 34 import edu.umd.cs.findbugs.ba.AssertionMethods; 35 import edu.umd.cs.findbugs.ba.BackwardDataflowAnalysis; 36 import edu.umd.cs.findbugs.ba.BasicBlock; 37 import edu.umd.cs.findbugs.ba.CFG; 38 import edu.umd.cs.findbugs.ba.CFGBuilderException; 39 import edu.umd.cs.findbugs.ba.ClassContext; 40 import edu.umd.cs.findbugs.ba.Dataflow; 41 import edu.umd.cs.findbugs.ba.DataflowAnalysisException; 42 import edu.umd.cs.findbugs.ba.DataflowTestDriver; 43 import edu.umd.cs.findbugs.ba.DepthFirstSearch; 44 import edu.umd.cs.findbugs.ba.Edge; 45 import edu.umd.cs.findbugs.ba.EdgeTypes; 46 import edu.umd.cs.findbugs.ba.Hierarchy; 47 import edu.umd.cs.findbugs.ba.JavaClassAndMethod; 48 import edu.umd.cs.findbugs.ba.Location; 49 import edu.umd.cs.findbugs.ba.NullnessAnnotationDatabase; 50 import edu.umd.cs.findbugs.ba.ReverseDepthFirstSearch; 51 import edu.umd.cs.findbugs.ba.SignatureParser; 52 import edu.umd.cs.findbugs.ba.XFactory; 53 import edu.umd.cs.findbugs.ba.XMethod; 54 import edu.umd.cs.findbugs.ba.npe.IsNullConditionDecision; 55 import edu.umd.cs.findbugs.ba.npe.IsNullValue; 56 import edu.umd.cs.findbugs.ba.npe.IsNullValueDataflow; 57 import edu.umd.cs.findbugs.ba.npe.IsNullValueFrame; 58 import edu.umd.cs.findbugs.ba.npe.ParameterNullnessProperty; 59 import edu.umd.cs.findbugs.ba.npe.ParameterNullnessPropertyDatabase; 60 import edu.umd.cs.findbugs.ba.type.TypeDataflow; 61 import edu.umd.cs.findbugs.ba.type.TypeFrame; 62 import edu.umd.cs.findbugs.ba.vna.AvailableLoad; 63 import edu.umd.cs.findbugs.ba.vna.ValueNumber; 64 import edu.umd.cs.findbugs.ba.vna.ValueNumberDataflow; 65 import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame; 66 import edu.umd.cs.findbugs.detect.BuildUnconditionalParamDerefDatabase; 67 68 73 public class UnconditionalValueDerefAnalysis extends 74 BackwardDataflowAnalysis<UnconditionalValueDerefSet> { 75 76 public static final boolean DEBUG = SystemProperties.getBoolean("fnd.derefs.debug"); 77 public static final boolean ASSUME_NONZERO_TRIP_LOOPS = SystemProperties.getBoolean("fnd.derefs.nonzerotrip"); 78 public static final boolean IGNORE_DEREF_OF_NONNCP = 79 SystemProperties.getBoolean("fnd.derefs.ignorenonNCP", true); 80 81 public static final boolean IGNORE_DEREF_OF_NONNULL = IGNORE_DEREF_OF_NONNCP 82 || SystemProperties.getBoolean("fnd.derefs.ignorenonnull"); 83 public static final boolean CHECK_ANNOTATIONS = 84 SystemProperties.getBoolean("fnd.derefs.checkannotations", true); 85 public static final boolean CHECK_CALLS = 86 SystemProperties.getBoolean("fnd.derefs.checkcalls", true); 87 public static final boolean DEBUG_CHECK_CALLS = 88 SystemProperties.getBoolean("fnd.derefs.checkcalls.debug"); 89 90 private CFG cfg; 91 private MethodGen methodGen; 92 private ValueNumberDataflow vnaDataflow; 93 private AssertionMethods assertionMethods; 94 95 private IsNullValueDataflow invDataflow; 96 private TypeDataflow typeDataflow; 97 98 108 public UnconditionalValueDerefAnalysis( 109 ReverseDepthFirstSearch rdfs, 110 DepthFirstSearch dfs, 111 CFG cfg, 112 MethodGen methodGen, 113 ValueNumberDataflow vnaDataflow, 114 AssertionMethods assertionMethods 115 ) { 116 super(rdfs, dfs); 117 this.cfg = cfg; 118 this.methodGen = methodGen; 119 this.vnaDataflow = vnaDataflow; 120 this.assertionMethods = assertionMethods; 121 if (DEBUG) { 122 System.out.println("UnconditionalValueDerefAnalysis analysis " + methodGen.getClassName() + "." + methodGen.getName() + " : " + methodGen.getSignature()); 123 } 124 if (DEBUG && IGNORE_DEREF_OF_NONNULL) { 125 System.out.println("** Ignoring dereferences of definitely non-null values"); 126 } 127 } 128 129 135 public void clearDerefsOnNonNullBranches(IsNullValueDataflow invDataflow) { 136 this.invDataflow = invDataflow; 137 } 138 139 143 public void setTypeDataflow(TypeDataflow typeDataflow) { 144 this.typeDataflow= typeDataflow; 145 } 146 147 150 @Override 151 public boolean isFactValid(UnconditionalValueDerefSet fact) { 152 return !fact.isTop() && !fact.isBottom(); 153 } 154 155 158 @Override 159 public void transferInstruction(InstructionHandle handle, 160 BasicBlock basicBlock, UnconditionalValueDerefSet fact) 161 throws DataflowAnalysisException { 162 163 if (fact.isTop()) return; 164 Location location = new Location(handle, basicBlock); 165 166 if (isAssertion(handle) || handle.getInstruction() instanceof ATHROW ) { 173 if (DEBUG) System.out.println("MAKING BOTTOM0 AT: " + location); 174 fact.clear(); 175 return; 176 } 177 178 ValueNumberFrame vnaFrame = vnaDataflow.getFactAtLocation(location); 180 if (!vnaFrame.isValid()) { 181 if (DEBUG) System.out.println("MAKING TOP1 AT: " + location); 182 makeFactTop(fact); 185 return; 186 } 187 188 189 if (CHECK_CALLS && handle.getInstruction() instanceof InvokeInstruction) { 192 checkUnconditionalDerefDatabase(location, vnaFrame, fact); 193 } 194 195 if (CHECK_ANNOTATIONS && handle.getInstruction() instanceof InvokeInstruction) { 199 checkNonNullParams(location, vnaFrame, fact); 200 } 201 202 checkInstance(location, vnaFrame, fact); 204 205 if (false) fact.cleanDerefSet(location, vnaFrame); 206 207 if (DEBUG && fact.isTop()) System.out.println("MAKING TOP2 At: " + location); 208 209 } 210 211 220 private void checkUnconditionalDerefDatabase( 221 Location location, 222 ValueNumberFrame vnaFrame, 223 UnconditionalValueDerefSet fact) throws DataflowAnalysisException { 224 225 ParameterNullnessPropertyDatabase database = 226 AnalysisContext.currentAnalysisContext().getUnconditionalDerefParamDatabase(); 227 if (database == null) { 228 if (DEBUG_CHECK_CALLS) { 229 System.out.println("no database!"); 230 } 231 return; 232 } 233 234 InvokeInstruction inv = (InvokeInstruction) location.getHandle().getInstruction(); 235 TypeFrame typeFrame = typeDataflow.getFactAtLocation(location); 236 if (!typeFrame.isValid()) { 237 if (DEBUG_CHECK_CALLS) { 238 System.out.println("invalid type frame!"); 239 } 240 return; 241 } 242 243 SignatureParser sigParser = new SignatureParser(inv.getSignature(methodGen.getConstantPool())); 244 int numParams = sigParser.getNumParameters(); 245 246 try { 247 Set <JavaClassAndMethod> targetSet = Hierarchy.resolveMethodCallTargets( 248 inv, 249 typeFrame, 250 methodGen.getConstantPool()); 251 252 if (targetSet.isEmpty()) { 253 return; 254 } 255 256 ParameterNullnessProperty derefParamSet = null; 258 for (JavaClassAndMethod target : targetSet) { 259 if (DEBUG_CHECK_CALLS) { 260 System.out.print("Checking " + target + ": "); 261 } 262 263 ParameterNullnessProperty targetDerefParamSet = database.getProperty(target.toXMethod()); 264 if (targetDerefParamSet == null) { 265 if (DEBUG_CHECK_CALLS) { 268 System.out.print("==> no information, assume no guaranteed dereferences"); 269 } 270 271 return; 272 } 273 274 if (DEBUG_CHECK_CALLS) { 275 System.out.println("==> " + targetDerefParamSet); 276 } 277 if (derefParamSet == null) { 278 derefParamSet = new ParameterNullnessProperty(); 279 derefParamSet.copyFrom(targetDerefParamSet); 280 } else { 281 derefParamSet.intersectWith(targetDerefParamSet); 282 } 283 } 284 285 if (derefParamSet == null || derefParamSet.isEmpty()) { 286 return; 287 } 288 if (DEBUG_CHECK_CALLS) { 289 System.out.println("** Summary of call: " + derefParamSet); 290 } 291 292 IsNullValueFrame invFrame = null; 293 if (IGNORE_DEREF_OF_NONNULL && invDataflow != null) { 294 invFrame = invDataflow.getFactAtLocation(location); 295 if (!invFrame.isValid()) { 296 invFrame = null; 297 } 298 } 299 300 for (int i = 0; i < numParams; i++) { 301 if (!derefParamSet.isNonNull(i)) { 302 continue; 303 } 304 305 int argSlot = vnaFrame.getArgumentSlot(i, numParams); 306 307 if (invFrame != null) { 308 IsNullValue val = invFrame.getValue(argSlot); 309 if (val.isDefinitelyNotNull()) { 310 continue; 311 } 312 if (IGNORE_DEREF_OF_NONNCP && !val.isNullOnComplicatedPath()) continue; 313 } 314 315 fact.addDeref(vnaFrame.getValue(argSlot), location); 316 if (DEBUG_CHECK_CALLS ||VERBOSE_NULLARG_DEBUG) { 317 System.out.println("Adding deref of " + vnaFrame.getValue(argSlot) + " at location " + location); 318 for (JavaClassAndMethod target : targetSet) { 319 320 System.out.print("Checking " + target + ": "); 321 ParameterNullnessProperty targetDerefParamSet = database.getProperty(target.toXMethod()); 322 if (targetDerefParamSet == null) { 323 System.out.println(" ==> unknown"); 324 continue; 325 } 326 327 328 System.out.println("==> " + targetDerefParamSet); 329 330 } 331 332 } 333 } 334 } catch (ClassNotFoundException e) { 335 AnalysisContext.reportMissingClass(e); 336 } 337 } 338 public static final boolean VERBOSE_NULLARG_DEBUG = SystemProperties.getBoolean("fnd.debug.nullarg.verbose"); 339 340 350 private void checkNonNullParams(Location location, ValueNumberFrame vnaFrame, UnconditionalValueDerefSet fact) throws DataflowAnalysisException { 351 NullnessAnnotationDatabase database = AnalysisContext.currentAnalysisContext().getNullnessAnnotationDatabase(); 352 if (database == null) { 353 return; 354 } 355 356 InvokeInstruction inv = (InvokeInstruction) location.getHandle().getInstruction(); 357 XMethod called = XFactory.createXMethod( 358 inv, 359 methodGen.getConstantPool()); 360 SignatureParser sigParser = new SignatureParser(called.getSignature()); 361 int numParams = sigParser.getNumParameters(); 362 363 for (int i = 0; i < numParams; i++) { 364 if (IGNORE_DEREF_OF_NONNULL 365 && invDataflow != null) { 366 IsNullValueFrame invFrame = invDataflow.getFactAtLocation(location); 367 if (isNonNullValue(invFrame, invFrame.getArgumentSlot(i, numParams))) { 368 continue; 369 } 370 } 371 if (database.parameterMustBeNonNull(called, i)) { 372 ValueNumber vn = vnaFrame.getArgument(inv, methodGen.getConstantPool(), i, numParams); 374 fact.addDeref(vn, location); 375 } 376 } 377 } 378 379 388 private void checkInstance( 389 Location location, 390 ValueNumberFrame vnaFrame, 391 UnconditionalValueDerefSet fact) throws DataflowAnalysisException { 392 if (!location.isFirstInstructionInBasicBlock()) { 396 return; 397 } 398 BasicBlock fallThroughPredecessor = 399 cfg.getPredecessorWithEdgeType(location.getBasicBlock(), EdgeTypes.FALL_THROUGH_EDGE); 400 if (fallThroughPredecessor == null || !fallThroughPredecessor.isNullCheck()) { 401 return; 402 } 403 404 ValueNumber vn = vnaFrame.getInstance(location.getHandle().getInstruction(), methodGen.getConstantPool()); 406 407 if (!methodGen.isStatic()) { 409 ValueNumber v = vnaFrame.getValue(0); 410 if (v.equals(vn)) return; 411 } 412 if (vn.hasFlag(ValueNumber.CONSTANT_CLASS_OBJECT)) return; 413 414 IsNullValueFrame startFact = null; 415 416 if (invDataflow != null) { 417 startFact = invDataflow.getStartFact(fallThroughPredecessor); 418 } 419 420 if (IGNORE_DEREF_OF_NONNULL 422 && invDataflow != null 423 && isDerefOfNonNullValue(location, startFact)) { 424 return; 425 } 426 427 if (IGNORE_DEREF_OF_NONNCP 428 && invDataflow != null 429 && !isDerefOfNullOnComplexPathValue(location, startFact)) { 430 return; 431 } 432 433 if (DEBUG) { 434 System.out.println("FOUND GUARANTEED DEREFERENCE"); 435 System.out.println("Load: " + vnaFrame.getLoad(vn)); 436 System.out.println("Pred: " + fallThroughPredecessor); 437 System.out.println("startFact: " + startFact); 438 System.out.println("Location: " + location); 439 System.out.println("Value number frame: " + vnaFrame); 440 System.out.println("Dereferenced valueNumber: " + vn); 441 System.out.println("invDataflow: " + startFact); 442 System.out.println("IGNORE_DEREF_OF_NONNCP: " + IGNORE_DEREF_OF_NONNCP); 443 System.out.println("IGNORE_DEREF_OF_NONNULL: " + IGNORE_DEREF_OF_NONNULL); 444 System.out.println("isNonNull: " + isDerefOfNonNullValue(location, startFact)); 445 System.out.println("isDerefOfNullOnComplexPathValue: " + isDerefOfNullOnComplexPathValue(location, startFact)); 446 447 448 } 449 fact.addDeref(vn, location); 451 } 452 453 463 private boolean isDerefOfNonNullValue(Location locationOfDeref, IsNullValueFrame invFrameAtNullCheck) 464 throws DataflowAnalysisException { 465 if (!invFrameAtNullCheck.isValid()) { 466 return false; 468 } 469 470 int instance = invFrameAtNullCheck.getInstanceSlot( 471 locationOfDeref.getHandle().getInstruction(), 472 methodGen.getConstantPool()); 473 return isNonNullValue(invFrameAtNullCheck, instance); 474 } 475 476 486 private boolean isDerefOfNullOnComplexPathValue(Location locationOfDeref, IsNullValueFrame invFrameAtNullCheck) 487 throws DataflowAnalysisException { 488 if (!invFrameAtNullCheck.isValid()) { 489 return false; 491 } 492 493 int instance = invFrameAtNullCheck.getInstanceSlot( 494 locationOfDeref.getHandle().getInstruction(), 495 methodGen.getConstantPool()); 496 return isNullOnComplexPath(invFrameAtNullCheck, instance); 497 } 498 506 private boolean isNonNullValue(IsNullValueFrame invFrame, int slot) { 507 if (invFrame == null || !invFrame.isValid()) { 508 return false; 509 } 510 return invFrame.getValue(slot).isDefinitelyNotNull(); 511 } 512 520 private boolean isNullOnComplexPath(IsNullValueFrame invFrame, int slot) { 521 if (invFrame == null || !invFrame.isValid()) { 522 return false; 523 } 524 IsNullValue value = invFrame.getValue(slot); 525 return value.isNullOnComplicatedPath(); 526 } 527 533 private boolean isAssertion(InstructionHandle handle) { 534 return handle.getInstruction() instanceof InvokeInstruction 535 && assertionMethods.isAssertionCall((InvokeInstruction) handle.getInstruction()); 536 } 537 538 541 public void copy(UnconditionalValueDerefSet source, UnconditionalValueDerefSet dest) { 542 dest.makeSameAs(source); 543 } 544 545 548 public UnconditionalValueDerefSet createFact() { 549 return new UnconditionalValueDerefSet(vnaDataflow.getAnalysis().getNumValuesAllocated()); 550 } 551 552 555 public void initEntryFact(UnconditionalValueDerefSet result) 556 throws DataflowAnalysisException { 557 result.clear(); 558 } 559 560 563 public void initResultFact(UnconditionalValueDerefSet result) { 564 result.setIsTop(); 565 } 566 567 570 public void makeFactTop(UnconditionalValueDerefSet fact) { 571 fact.setIsTop(); 572 } 573 574 public boolean isTop(UnconditionalValueDerefSet fact) { 575 return fact.isTop(); 576 } 577 580 public void meetInto(UnconditionalValueDerefSet fact, Edge edge, 581 UnconditionalValueDerefSet result) throws DataflowAnalysisException { 582 583 if (ignoreThisEdge(edge)) { 584 return; 585 } 586 587 ValueNumber knownNonnullOnBranch = null; 588 if (isFactValid(fact)) { 590 fact = propagateDerefSetsToMergeInputValues(fact, edge); 591 if (invDataflow != null) { 592 knownNonnullOnBranch = findValueKnownNonnullOnBranch(fact, edge); 593 if (knownNonnullOnBranch != null) { 594 fact = duplicateFact(fact); 595 fact.clearDerefSet(knownNonnullOnBranch); 596 } 597 } 598 } 599 boolean isBackEdge = edge.isBackwardInBytecode(); 600 boolean sourceIsTopOfLoop = edge.sourceIsTopOfLoop(ClassContext.getLoopExitBranches(methodGen)); 601 if (sourceIsTopOfLoop && edge.getType() == EdgeTypes.FALL_THROUGH_EDGE) 602 isBackEdge = true; 603 if (false && (edge.getType() == EdgeTypes.IFCMP_EDGE || sourceIsTopOfLoop)) { 604 System.out.println("Meet into " + edge); 605 System.out.println(" foo2: " + sourceIsTopOfLoop); 606 System.out.println(" getType: " + edge.getType() ); 607 System.out.println(" Backedge according to bytecode: " + isBackEdge); 608 System.out.println(" Fact hashCode: " + System.identityHashCode(result)); 609 System.out.println(" Initial fact: " + result); 610 System.out.println(" Edge fact: " + fact); 611 } 612 if (result.isTop() || fact.isBottom()) { 613 copy(fact, result); 615 if (ASSUME_NONZERO_TRIP_LOOPS && isBackEdge && !fact.isTop()) 616 result.resultsFromBackEdge = true; 617 } else if (ASSUME_NONZERO_TRIP_LOOPS && isBackEdge && !fact.isTop()) { 618 result.unionWith(fact, vnaDataflow.getAnalysis().getFactory()); 619 result.resultsFromBackEdge = true; 620 if (DEBUG) { 621 System.out.println("\n Forcing union of " + System.identityHashCode(result) + " due to backedge info"); 622 System.out.println(" result: " + result); 623 } 624 625 } else if (result.isBottom() || fact.isTop()) { 626 } else { 628 if (ASSUME_NONZERO_TRIP_LOOPS && result.resultsFromBackEdge) { 631 result.backEdgeUpdateCount++; 632 if (result.backEdgeUpdateCount < 10) { 633 if (DEBUG) System.out.println("\n Union update of " + System.identityHashCode(result) + " due to backedge info"); 634 result.unionWith(fact, vnaDataflow.getAnalysis().getFactory()); 635 return; 636 } 637 } 638 result.mergeWith(fact, knownNonnullOnBranch, vnaDataflow.getAnalysis().getFactory()); 639 if (DEBUG) { 640 System.out.println(" updated: " + System.identityHashCode(result)); 641 System.out.println(" result: " + result); 642 return; 643 } 644 } 645 if (DEBUG && isBackEdge && edge.getType() == EdgeTypes.IFCMP_EDGE) { 646 System.out.println(" result: " + result); 647 } 648 } 649 650 661 private UnconditionalValueDerefSet propagateDerefSetsToMergeInputValues( 662 UnconditionalValueDerefSet fact, Edge edge) { 663 664 ValueNumberFrame blockValueNumberFrame = 665 vnaDataflow.getResultFact(edge.getSource()); 666 ValueNumberFrame targetValueNumberFrame = 667 vnaDataflow.getStartFact(edge.getTarget()); 668 669 UnconditionalValueDerefSet originalFact = fact; 670 fact = duplicateFact(fact); 671 672 if (blockValueNumberFrame.isValid() && targetValueNumberFrame.isValid() && 673 blockValueNumberFrame.getNumSlots() == targetValueNumberFrame.getNumSlots()) { 674 if (DEBUG) { 675 System.out.println("** Valid VNA frames for " + edge); 676 System.out.println("** Block : " + blockValueNumberFrame); 677 System.out.println("** Target: " + targetValueNumberFrame); 678 } 679 680 for (int i = 0; i < blockValueNumberFrame.getNumSlots(); i++) { 681 ValueNumber blockVN = blockValueNumberFrame.getValue(i); 682 ValueNumber targetVN = targetValueNumberFrame.getValue(i); 683 fact.clearDerefSet(blockVN); 684 if (originalFact.isUnconditionallyDereferenced(targetVN)) 685 fact.setDerefSet(blockVN, originalFact.getUnconditionalDerefLocationSet(targetVN)); 686 687 } 689 for(ValueNumber blockVN : blockValueNumberFrame.valueNumbersForLoads()) { 690 AvailableLoad load = blockValueNumberFrame.getLoad(blockVN); 691 if (load == null) continue; 692 ValueNumber [] targetVNs = targetValueNumberFrame.getAvailableLoad(load); 693 if (targetVNs != null) 694 for(ValueNumber targetVN : targetVNs) 695 if (targetVN.hasFlag(ValueNumber.PHI_NODE) && fact.isUnconditionallyDereferenced(targetVN) 696 && !fact.isUnconditionallyDereferenced(blockVN)) { 697 AvailableLoad targetLoad = targetValueNumberFrame.getLoad(targetVN); 699 if (!load.equals(targetLoad)) continue; 700 if (DEBUG) { 701 System.out.println("** Copy vn derefs for " + load +" from " + targetVN + 702 " --> " + blockVN); 703 System.out.println("** block phi for " + System.identityHashCode(blockValueNumberFrame) 704 + "is " + blockValueNumberFrame.phiNodeForLoads); 705 System.out.println("** target phi for " + System.identityHashCode(targetValueNumberFrame) 706 + "is " + targetValueNumberFrame.phiNodeForLoads); 707 } 708 fact.setDerefSet(blockVN, fact.getUnconditionalDerefLocationSet(targetVN)); 709 710 } 711 712 } 713 } 714 if (DEBUG) { 715 System.out.println("Target VNF: " + targetValueNumberFrame); 716 System.out.println("Block VNF: " + blockValueNumberFrame); 717 System.out.println("fact: " + fact); 718 } 719 fact.cleanDerefSet(null, blockValueNumberFrame); 720 return fact; 721 } 722 723 729 private UnconditionalValueDerefSet duplicateFact(UnconditionalValueDerefSet fact) { 730 UnconditionalValueDerefSet copyOfFact = createFact(); 731 copy(fact, copyOfFact); 732 fact = copyOfFact; 733 return fact; 734 } 735 736 744 private @CheckForNull ValueNumber findValueKnownNonnullOnBranch( 745 UnconditionalValueDerefSet fact, Edge edge) { 746 747 IsNullValueFrame invFrame = invDataflow.getResultFact(edge.getSource()); 748 if (!invFrame.isValid()) { 749 return null; 750 } 751 IsNullConditionDecision decision = invFrame.getDecision(); 752 if (decision == null) { 753 return null; 754 } 755 756 IsNullValue inv = decision.getDecision(edge.getType()); 757 if (inv == null || !inv.isDefinitelyNotNull()) { 758 return null; 759 } 760 ValueNumber value = decision.getValue(); 761 if (DEBUG) { 762 System.out.println("Value number " + value + " is known nonnull on " + edge); 763 } 764 765 return value; 766 } 767 768 774 private boolean ignoreThisEdge(Edge edge) { 775 return edge.isExceptionEdge(); 776 } 777 778 781 public boolean same(UnconditionalValueDerefSet fact1, UnconditionalValueDerefSet fact2) { 782 return fact1.resultsFromBackEdge || fact1.isSameAs(fact2); 783 } 784 785 @Override 786 public void startIteration() { 787 } 789 790 @Override 791 public int getLastUpdateTimestamp(UnconditionalValueDerefSet fact) { 792 return fact.getLastUpdateTimestamp(); 793 } 794 @Override 795 public void setLastUpdateTimestamp(UnconditionalValueDerefSet fact, int lastUpdate) { 796 fact.setLastUpdateTimestamp(lastUpdate); 797 } 798 public static void main(String [] args) throws Exception { 799 if (args.length != 1) { 800 System.err.println("Usage: " + UnconditionalValueDerefAnalysis.class.getName() + " <classfile>"); 801 System.exit(1); 802 } 803 804 DataflowTestDriver<UnconditionalValueDerefSet, UnconditionalValueDerefAnalysis> driver = 805 new DataflowTestDriver<UnconditionalValueDerefSet, UnconditionalValueDerefAnalysis>() { 806 809 @Override 810 public Dataflow<UnconditionalValueDerefSet, UnconditionalValueDerefAnalysis> createDataflow(ClassContext classContext, Method method) throws CFGBuilderException, DataflowAnalysisException { 811 return classContext.getUnconditionalValueDerefDataflow(method); 812 } 813 }; 814 if (SystemProperties.getBoolean("forwardcfg")) { 815 driver.overrideIsForwards(); 816 } 817 driver.execute(args[0]); 818 } 819 } | Popular Tags |