--- /dev/null
+package Analysis.SSJava;
+
+import IR.ClassDescriptor;
+
+public class CompositeLocation extends Location {
+
+ private NTuple<Location> locTuple;
+
+ public CompositeLocation(ClassDescriptor cd) {
+ super(cd);
+ }
+
+ public void addSingleLocation(Location loc) {
+ locTuple.addElement(loc);
+ }
+
+}
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
+import java.util.StringTokenizer;
import java.util.Vector;
import IR.AnnotationDescriptor;
import IR.ClassDescriptor;
import IR.FieldDescriptor;
import IR.MethodDescriptor;
+import IR.Operation;
import IR.State;
import IR.SymbolTable;
import IR.TypeDescriptor;
import IR.Tree.DeclarationNode;
import IR.Tree.ExpressionNode;
import IR.Tree.Kind;
+import IR.Tree.OpNode;
import Util.Lattice;
public class FlowDownCheck {
case Kind.AssignmentNode:
checkAssignmentNode(md, nametable, (AssignmentNode) en, td);
return;
+
+ case Kind.OpNode:
+ checkOpNode(md, nametable, (OpNode) en, td);
+ return;
}
/*
* switch(en.kind()) { case Kind.AssignmentNode:
*/
}
+ void checkOpNode(MethodDescriptor md, SymbolTable nametable, OpNode on, TypeDescriptor td) {
+
+ Lattice<String> locOrder = (Lattice<String>) state.getCd2LocationOrder().get(md.getClassDesc());
+
+ checkExpressionNode(md, nametable, on.getLeft(), null);
+ if (on.getRight() != null)
+ checkExpressionNode(md, nametable, on.getRight(), null);
+
+ TypeDescriptor ltd = on.getLeft().getType();
+ TypeDescriptor rtd = on.getRight() != null ? on.getRight().getType() : null;
+
+ if (ltd.getAnnotationMarkers().size() == 0) {
+ // constant value
+ // TODO
+ // ltd.addAnnotationMarker(new AnnotationDescriptor(Lattice.TOP));
+ }
+ if (rtd != null && rtd.getAnnotationMarkers().size() == 0) {
+ // constant value
+ // TODO
+ // rtd.addAnnotationMarker(new AnnotationDescriptor(Lattice.TOP));
+ }
+
+ System.out.println("checking op node");
+ System.out.println("td=" + td);
+ System.out.println("ltd=" + ltd);
+ System.out.println("rtd=" + rtd);
+
+ Operation op = on.getOp();
+
+ switch (op.getOp()) {
+
+ case Operation.UNARYPLUS:
+ case Operation.UNARYMINUS:
+ case Operation.LOGIC_NOT:
+ // single operand
+ on.setType(new TypeDescriptor(TypeDescriptor.BOOLEAN));
+ break;
+
+ case Operation.LOGIC_OR:
+ case Operation.LOGIC_AND:
+ case Operation.COMP:
+ case Operation.BIT_OR:
+ case Operation.BIT_XOR:
+ case Operation.BIT_AND:
+ case Operation.ISAVAILABLE:
+ case Operation.EQUAL:
+ case Operation.NOTEQUAL:
+ case Operation.LT:
+ case Operation.GT:
+ case Operation.LTE:
+ case Operation.GTE:
+ case Operation.ADD:
+ case Operation.SUB:
+ case Operation.MULT:
+ case Operation.DIV:
+ case Operation.MOD:
+ case Operation.LEFTSHIFT:
+ case Operation.RIGHTSHIFT:
+ case Operation.URIGHTSHIFT:
+
+ Set<String> operandSet = new HashSet<String>();
+ String leftLoc = ltd.getAnnotationMarkers().get(0).getMarker();
+ String rightLoc = rtd.getAnnotationMarkers().get(0).getMarker();
+
+ operandSet.add(leftLoc);
+ operandSet.add(rightLoc);
+
+ // TODO
+ // String glbLoc = locOrder.getGLB(operandSet);
+ // on.getType().addAnnotationMarker(new AnnotationDescriptor(glbLoc));
+ // System.out.println(glbLoc + "<-" + leftLoc + " " + rightLoc);
+
+ break;
+
+ default:
+ throw new Error(op.toString());
+ }
+
+ if (td != null) {
+ String lhsLoc = td.getAnnotationMarkers().get(0).getMarker();
+ if (locOrder.isGreaterThan(lhsLoc, on.getType().getAnnotationMarkers().get(0).getMarker())) {
+ throw new Error("The location of LHS is higher than RHS: " + on.printNode(0));
+ }
+ }
+
+ }
+
void checkAssignmentNode(MethodDescriptor md, SymbolTable nametable, AssignmentNode an,
TypeDescriptor td) {
+ boolean postinc = true;
+ if (an.getOperation().getBaseOp() == null
+ || (an.getOperation().getBaseOp().getOp() != Operation.POSTINC && an.getOperation()
+ .getBaseOp().getOp() != Operation.POSTDEC))
+ postinc = false;
+ if (!postinc)
+ checkExpressionNode(md, nametable, an.getSrc(), td);
+
ClassDescriptor cd = md.getClassDesc();
Lattice<String> locOrder = (Lattice<String>) state.getCd2LocationOrder().get(cd);
+ System.out.println("an=" + an.printNode(0));
String destLocation = an.getDest().getType().getAnnotationMarkers().elementAt(0).getMarker();
String srcLocation = an.getSrc().getType().getAnnotationMarkers().elementAt(0).getMarker();
if (!locOrder.isGreaterThan(srcLocation, destLocation)) {
- throw new Error("Value flow from " + srcLocation + " to " + destLocation
- + "does not respect location hierarchy.");
+ throw new Error("The value flow from " + srcLocation + " to " + destLocation
+ + " does not respect location hierarchy.");
}
}
throw new Error(vd.getSymbol() + " has more than one location.");
}
- // check if location is defined
- String locationID = annotationVec.elementAt(0).getMarker();
- Lattice<String> lattice = (Lattice<String>) state.getCd2LocationOrder().get(cd);
+ AnnotationDescriptor ad = annotationVec.elementAt(0);
+
+ if (ad.getType() == AnnotationDescriptor.MARKER_ANNOTATION) {
- if (lattice == null || (!lattice.containsKey(locationID))) {
- throw new Error("Location " + locationID
- + " is not defined in the location hierarchy of class " + cd.getSymbol() + ".");
+ // check if location is defined
+ String locationID = ad.getMarker();
+ Lattice<String> lattice = (Lattice<String>) state.getCd2LocationOrder().get(cd);
+
+
+ if (lattice == null || (!lattice.containsKey(locationID))) {
+ throw new Error("Location " + locationID
+ + " is not defined in the location hierarchy of class " + cd.getSymbol() + ".");
+ }
+
+ } else if (ad.getType() == AnnotationDescriptor.SINGLE_ANNOTATION) {
+ if (ad.getMarker().equals(SSJavaAnalysis.DELTA)) {
+
+ if (ad.getData().length() == 0) {
+ throw new Error("Delta function of " + vd.getSymbol() + " does not have any locations: "
+ + cd.getSymbol() + ".");
+ }
+
+ StringTokenizer token = new StringTokenizer(ad.getData(), ",");
+ while (token.hasMoreTokens()) {
+ String deltaOperand = token.nextToken();
+
+ }
+
+ }
}
}
}
// check if location is defined
- String locationID = annotationVec.elementAt(0).getMarker();
- Lattice<String> lattice = (Lattice<String>) state.getCd2LocationOrder().get(cd);
+ AnnotationDescriptor ad = annotationVec.elementAt(0);
+ if (ad.getType() == AnnotationDescriptor.MARKER_ANNOTATION) {
+ String locationID = annotationVec.elementAt(0).getMarker();
+ Lattice<String> lattice = (Lattice<String>) state.getCd2LocationOrder().get(cd);
+
+
+ if (lattice == null || (!lattice.containsKey(locationID))) {
+ throw new Error("Location " + locationID
+ + " is not defined in the location hierarchy of class " + cd.getSymbol() + ".");
+ }
+ } else if (ad.getType() == AnnotationDescriptor.SINGLE_ANNOTATION) {
+ if (ad.getMarker().equals(SSJavaAnalysis.DELTA)) {
- if (lattice == null || (!lattice.containsKey(locationID))) {
- throw new Error("Location " + locationID
- + " is not defined in the location hierarchy of class " + cd.getSymbol() + ".");
+ if (ad.getData().length() == 0) {
+ throw new Error("Delta function of " + fd.getSymbol() + " does not have any locations: "
+ + cd.getSymbol() + ".");
+ }
+
+ StringTokenizer token = new StringTokenizer(ad.getData(), ",");
+ while (token.hasMoreTokens()) {
+ String deltaOperand = token.nextToken();
+ // TODO: set delta operand to corresponding type descriptor
+ }
+ }
}
}
--- /dev/null
+package Analysis.SSJava;
+
+import IR.ClassDescriptor;
+
+public class Location {
+
+ public static final int TOP = 1;
+ public static final int NORMAL = 2;
+ public static final int BOTTOM = 3;
+
+ private int type;
+ private ClassDescriptor cd;
+ private String loc;
+
+ public Location(ClassDescriptor cd, String loc) {
+ this.cd = cd;
+ this.loc = loc;
+ this.type = NORMAL;
+ }
+
+ public Location(ClassDescriptor cd) {
+ this.cd = cd;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public ClassDescriptor getClassDescriptor() {
+ return cd;
+ }
+
+ public String getLocIdentifier() {
+ return loc;
+ }
+
+ public int getType() {
+ return this.type;
+ }
+
+ public boolean equals(Object o) {
+ if (!(o instanceof Location)) {
+ return false;
+ }
+
+ Location loc = (Location) o;
+
+ if (loc.getClassDescriptor().equals(getClassDescriptor())) {
+ if (loc.getLocIdentifier() == null || getLocIdentifier() == null) {
+ if (loc.getType() == getType()) {
+ return true;
+ }
+ } else {
+ if (loc.getLocIdentifier().equals(getLocIdentifier())) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public int hashCode() {
+
+ int hash = cd.hashCode();
+ if (loc != null) {
+ hash += loc.hashCode();
+ }
+ return hash;
+
+ }
+
+}
--- /dev/null
+package Analysis.SSJava;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class NTuple<T> {
+
+ private List<T> elements;
+
+ public NTuple(T ... elements) {
+ this.elements = Arrays.asList(elements);
+ }
+
+ public String toString() {
+ return elements.toString();
+ }
+
+ public T at(int index) {
+ return elements.get(index);
+ }
+
+ public int size() {
+ return elements.size();
+ }
+
+ public void addElement(T newElement) {
+ this.elements.add(newElement);
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (o == null || o.getClass() != this.getClass()) {
+ return false;
+ }
+ return (((NTuple) o).elements).equals(elements);
+ }
+
+ public int hashCode() {
+ return elements.hashCode();
+ }
+
+}
public class SSJavaAnalysis {
+ public static final String DELTA = "delta";
State state;
HashSet toanalyze;
public static final int FULL_ANNOTATION = 3;
private String marker;
- private Set arrayedValues; // for single annotation
+ private String data; // for single annotation
private int type;
public AnnotationDescriptor(String annotationName) {
this.type = MARKER_ANNOTATION;
}
+ public AnnotationDescriptor(String annotationName, String data) {
+ // constructor for marker annotation
+ super(annotationName);
+ this.marker = annotationName;
+ this.type = SINGLE_ANNOTATION;
+ this.data = data;
+ }
+
public int getType() {
return type;
}
public String getMarker() {
return marker;
}
+
+ public String getData(){
+ return data;
+ }
public boolean equals(Object o) {
if (o instanceof AnnotationDescriptor) {
import java.util.*;
-import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;
public class BuildIR {
}
}
- public void parseInitializers(ClassDescriptor cn){
- Vector fv=cn.getFieldVec();
+public void parseInitializers(ClassDescriptor cn){
+ Vector fv=cn.getFieldVec();
int pos = 0;
- for(int i=0;i<fv.size();i++) {
- FieldDescriptor fd=(FieldDescriptor)fv.get(i);
- if(fd.getExpressionNode()!=null) {
+ for(int i=0;i<fv.size();i++) {
+ FieldDescriptor fd=(FieldDescriptor)fv.get(i);
+ if(fd.getExpressionNode()!=null) {
Iterator methodit = cn.getMethods();
while(methodit.hasNext()){
MethodDescriptor currmd=(MethodDescriptor)methodit.next();
}
}
pos++;
- }
- }
+ }
+ }
}
private ClassDescriptor parseEnumDecl(ClassDescriptor cn, ParseNode pn) {
}
}
- private void parseLocationOrder(ClassDescriptor cd, ParseNode pn){
- ParseNodeVector pnv=pn.getChildren();
- Lattice<String> locOrder=new Lattice<String>();
- for(int i=0; i<pnv.size(); i++) {
- ParseNode loc=pnv.elementAt(i);
+ private void parseLocationOrder(ClassDescriptor cd, ParseNode pn) {
+ ParseNodeVector pnv = pn.getChildren();
+ Lattice<String> locOrder =
+ new Lattice<String>("_top_","_bottom_");
+ for (int i = 0; i < pnv.size(); i++) {
+ ParseNode loc = pnv.elementAt(i);
String lowerLoc=loc.getChildren().elementAt(0).getLabel();
- String higherLoc=loc.getChildren().elementAt(1).getLabel();
+ String higherLoc= loc.getChildren().elementAt(1).getLabel();
locOrder.put(higherLoc, lowerLoc);
- locOrder.put(lowerLoc,null);
- if(locOrder.isIntroducingCycle(higherLoc)){
- throw new Error("Error: the order relation "+lowerLoc+" < "+higherLoc+" introduces a cycle.");
+ if (locOrder.isIntroducingCycle(higherLoc)) {
+ throw new Error("Error: the order relation " + lowerLoc + " < " + higherLoc
+ + " introduces a cycle.");
}
}
state.addLocationOrder(cd, locOrder);
return m;
}
- private void parseAnnotationList(ParseNode pn, Modifiers m){
- ParseNodeVector pnv=pn.getChildren();
- for(int i=0; i<pnv.size(); i++) {
- ParseNode body_list=pnv.elementAt(i);
- if(isNode(body_list,"annotation_body")){
- ParseNode body_node=body_list.getFirstChild();
- if (isNode(body_node,"marker_annotation")){
- m.addAnnotation(new AnnotationDescriptor(body_node.getChild("name").getTerminal()));
- }else if(isNode(body_node,"single_annotation")){
- throw new Error("Annotation with single piece of data is not supported yet.");
- } else if(isNode(body_node,"normal_annotation")){
- throw new Error("Annotation with multiple data members is not supported yet.");
- }
+ private void parseAnnotationList(ParseNode pn, Modifiers m) {
+ ParseNodeVector pnv = pn.getChildren();
+ for (int i = 0; i < pnv.size(); i++) {
+ ParseNode body_list = pnv.elementAt(i);
+ if (isNode(body_list, "annotation_body")) {
+ ParseNode body_node = body_list.getFirstChild();
+ if (isNode(body_node, "marker_annotation")) {
+ m.addAnnotation(new AnnotationDescriptor(body_node.getChild("name").getTerminal()));
+ } else if (isNode(body_node, "single_annotation")) {
+ m.addAnnotation(new AnnotationDescriptor(body_node.getChild("name").getTerminal(),
+ body_node.getChild("element_value").getTerminal()));
+ } else if (isNode(body_node, "normal_annotation")) {
+ throw new Error("Annotation with multiple data members is not supported yet.");
}
- }
+ }
+ }
}
private boolean isNode(ParseNode pn, String label) {
:}
;
single_element_annotation_body ::=
- IDENTIFIER:id LPAREN element_value:ev RPAREN {:
+ IDENTIFIER:id LPAREN STRING_LITERAL:ev RPAREN {:
ParseNode pn=new ParseNode("single_annotation");
pn.addChild("name").addChild(id);
pn.addChild("element_value").addChild(ev);
import java.util.Set;
public class Lattice<T> {
+
private Hashtable<T, Set<T>> table;
int size;
- public Lattice() {
+ private T top;
+ private T bottom;
+
+ public Lattice(T top, T bottom) {
table = new Hashtable<T, Set<T>>();
+ this.top = top;
+ this.bottom = bottom;
+
+ table.put(top, new HashSet<T>());
+
+ }
+
+ public T getTopItem() {
+ return top;
+ }
+
+ public T getBottomItem() {
+ return bottom;
}
public boolean put(T key, T value) {
Set<T> s;
+
+ Set<T> topNeighbor = table.get(top);
+
if (table.containsKey(key)) {
s = table.get(key);
} else {
+ // new key, need to be connected with top
+ topNeighbor.add(key);
+
s = new HashSet<T>();
table.put(key, s);
}
- if (value!=null && !s.contains(value)) {
+ if (value != null && !s.contains(value)) {
size++;
s.add(value);
+
+ if (!table.containsKey(value)) {
+ Set<T> lowerNeighbor = new HashSet<T>();
+ lowerNeighbor.add(bottom);
+ table.put(value, lowerNeighbor);
+ }
+
+ // if value is already connected with top, it is no longer to be
+ topNeighbor.remove(value);
+
+ // if key is already connected with bottom,, it is no longer to be
+ table.get(key).remove(getBottomItem());
+
return true;
} else
return false;