001: /*
002: * FindBugs - Find Bugs in Java programs
003: * Copyright (C) 2006, University of Maryland
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package edu.umd.cs.findbugs.ba.npe2;
021:
022: import org.apache.bcel.Constants;
023:
024: import edu.umd.cs.findbugs.ba.DataflowAnalysisException;
025: import edu.umd.cs.findbugs.ba.Edge;
026: import edu.umd.cs.findbugs.ba.EdgeTypes;
027: import edu.umd.cs.findbugs.ba.Location;
028: import edu.umd.cs.findbugs.ba.vna.ValueNumber;
029: import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame;
030:
031: /**
032: * @author David Hovemeyer
033: */
034: public class IfNullCondition extends Condition {
035: private ValueNumber valueNumber;
036: private Decision ifcmpDecision;
037: private Decision fallThroughDecision;
038:
039: public IfNullCondition(Location location) {
040: super (location);
041: }
042:
043: /* (non-Javadoc)
044: * @see edu.umd.cs.findbugs.ba.npe2.Condition#getDecision(edu.umd.cs.findbugs.ba.Edge)
045: */
046: @Override
047: public Decision getDecision(Edge edge) {
048: return edge.getType() == EdgeTypes.IFCMP_EDGE ? ifcmpDecision
049: : fallThroughDecision;
050: }
051:
052: /* (non-Javadoc)
053: * @see edu.umd.cs.findbugs.ba.npe2.Condition#getValueNumber()
054: */
055: @Override
056: public ValueNumber getValueNumber() {
057: return valueNumber;
058: }
059:
060: /* (non-Javadoc)
061: * @see edu.umd.cs.findbugs.ba.npe2.Condition#refresh(edu.umd.cs.findbugs.ba.vna.ValueNumberFrame, edu.umd.cs.findbugs.ba.npe2.DefinitelyNullSet)
062: */
063: @Override
064: public void refresh(ValueNumberFrame vnaFrame,
065: DefinitelyNullSet definitelyNullSet)
066: throws DataflowAnalysisException {
067: valueNumber = vnaFrame.getTopValue();
068:
069: NullnessValue nullnessValue = definitelyNullSet
070: .getNulllessValue(valueNumber);
071: short opcode = getLocation().getHandle().getInstruction()
072: .getOpcode();
073:
074: if (nullnessValue.isDefinitelyNull()
075: || nullnessValue.isDefinitelyNotNull()) {
076: // Comparison is redundant.
077:
078: boolean ifcmpFeasible = nullnessValue.isDefinitelyNull() == (opcode == Constants.IFNULL);
079: ifcmpDecision = new Decision(ifcmpFeasible,
080: ifcmpFeasible ? nullnessValue.toCheckedValue()
081: : null);
082:
083: boolean fallThroughFeasible = nullnessValue
084: .isDefinitelyNull() != (opcode == Constants.IFNONNULL);
085: fallThroughDecision = new Decision(fallThroughFeasible,
086: fallThroughFeasible ? nullnessValue
087: .toCheckedValue() : null);
088:
089: return;
090: }
091:
092: NullnessValue definitelyNull = NullnessValue
093: .definitelyNullValue().toCheckedValue();
094: NullnessValue definitelyNotNull = NullnessValue
095: .definitelyNotNullValue().toCheckedValue();
096:
097: // Nullness is unknown, assume both branches are feasible.
098: ifcmpDecision = new Decision(true,
099: (opcode == Constants.IFNULL) ? definitelyNull
100: : definitelyNotNull);
101: fallThroughDecision = new Decision(true,
102: (opcode == Constants.IFNULL) ? definitelyNotNull
103: : definitelyNull);
104: }
105: }
|