Added minimum size analysis.
[repair.git] / Repair / RepairCompiler / MCC / IR / DotExpr.java
index 9361d5e8af95602663d3c1a8d70c31fbf83cd6f6..2e5021e940909a488fec446aa81790f79f63f319 100755 (executable)
@@ -4,16 +4,16 @@ import java.util.*;
 import MCC.Compiler;
 
 public class DotExpr extends Expr {
-    
+
     Expr left;
     String field;
     Expr index;
-    
+
     static boolean DOMEMCHECKS=false;
     static boolean DOTYPECHECKS=false;
     static boolean DONULL=false;
 
-    
+
     public DotExpr(Expr left, String field, Expr index) {
         this.left = left;
         this.field = field;
@@ -57,20 +57,23 @@ public class DotExpr extends Expr {
     public boolean isSafe() {
        if (!left.isSafe())
            return false;
+
        FieldDescriptor tmpfd=fd;
-       if (tmpfd instanceof ArrayDescriptor)
-           return false; // Arrays could be out of bounds
+
        if (tmpfd.getPtr()) // Pointers cound be invalid
            return false;
-       return true;
-    }
 
-    public void findmatch(Descriptor d, Set s) {
-       if (d==fd)
-           s.add(this);
-       left.findmatch(d,s);
-       if (intindex!=null)
-           intindex.findmatch(d,s);
+       if (tmpfd instanceof ArrayDescriptor) {
+            Expr arrayindex=((ArrayDescriptor)tmpfd).getIndexBound();
+            if (index instanceof IntegerLiteralExpr&&arrayindex instanceof IntegerLiteralExpr) {
+                int indexvalue=((IntegerLiteralExpr)index).getValue();
+                int arrayindexvalue=((IntegerLiteralExpr)arrayindex).getValue();
+                if (indexvalue>=0&&indexvalue<arrayindexvalue)
+                    return true;
+            }
+           return false; // Otherwise, arrays could be out of bounds
+        }
+        return true;
     }
 
     public Set freeVars() {
@@ -107,7 +110,15 @@ public class DotExpr extends Expr {
            name+="["+index.name()+"]";
        return name;
     }
-    
+
+    public void findmatch(Descriptor d, Set s) {
+       if (d==fd)
+           s.add(this);
+       left.findmatch(d,s);
+       if (intindex!=null)
+           intindex.findmatch(d,s);
+    }
+
     public Set useDescriptor(Descriptor d) {
        HashSet newset=new HashSet();
        if (d==fd)
@@ -143,7 +154,7 @@ public class DotExpr extends Expr {
 
     public Set getRequiredDescriptors() {
         Set v = left.getRequiredDescriptors();
-        
+
         if (intindex != null) {
             v.addAll(intindex.getRequiredDescriptors());
         }
@@ -167,31 +178,31 @@ public class DotExpr extends Expr {
 
        if (writer.getInvariantValue()!=null&&
            writer.getInvariantValue().isInvariant(this)) {
+           writer.addDeclaration(getType().getGenerateType().getSafeSymbol().toString(), dest.getSafeSymbol());
+           writer.outputline(dest.getSafeSymbol()+"="+writer.getInvariantValue().getValue(this).getSafeSymbol()+";");
            writer.outputline("maybe="+writer.getInvariantValue().getMaybe(this).getSafeSymbol()+";");
-           writer.outputline(getType().getGenerateType().getSafeSymbol()+
-                             " "+dest.getSafeSymbol()+"="+writer.getInvariantValue().getValue(this).getSafeSymbol()+";");
            return;
        }
 
-        writer.output("// " +  leftd.getSafeSymbol() + " <-- ");
+        writer.output("/* " +  leftd.getSafeSymbol() + " <-- ");
         left.prettyPrint(writer);
-        writer.outputline("");
+        writer.outputline("*/");
 
         left.generate(writer, leftd);
 
-        writer.output("// " +  leftd.getSafeSymbol() + " = ");
+        writer.output("/* " +  leftd.getSafeSymbol() + " = ");
         left.prettyPrint(writer);
-        writer.outputline("");
-      
+        writer.outputline("*/");
+
         StructureTypeDescriptor struct = (StructureTypeDescriptor) left.getType();
         Expr offsetbits;
 
         // #ATTN#: getOffsetExpr needs to be called with the fielddescriptor object that is in the vector list
-        // this means that if the field is an arraydescriptor you have to call getOffsetExpr with the array 
+        // this means that if the field is an arraydescriptor you have to call getOffsetExpr with the array
         // descriptor not the underlying field descriptor
 
         /* we calculate the offset in bits */
-        
+
         offsetbits = struct.getOffsetExpr(fd);
 
        FieldDescriptor fd=this.fd;
@@ -200,7 +211,8 @@ public class DotExpr extends Expr {
        boolean doboundscheck=true;
        boolean performedboundscheck=false;
 
-       writer.outputline(getType().getGenerateType() + " " + dest.getSafeSymbol()+"=0;");
+       writer.addDeclaration(getType().getGenerateType().toString(),dest.getSafeSymbol());
+       writer.outputline(dest.getSafeSymbol()+"=0;");
 
         if (intindex != null) {
             if (intindex instanceof IntegerLiteralExpr && ((IntegerLiteralExpr) intindex).getValue() == 0) {
@@ -212,24 +224,24 @@ public class DotExpr extends Expr {
                    indexvd.setType(ReservedTypeDescriptor.INT);
                    writer.getSymbolTable().add(indexvd);
 
-                   writer.output("// " + indexvd.getSafeSymbol() + " <-- ");
+                   writer.output("/* " + indexvd.getSafeSymbol() + " <-- ");
 
                    intindex.prettyPrint(writer);
-                   writer.outputline("");
+                   writer.outputline("*/");
                    intindex.generate(writer, indexvd);
-                   writer.output("// " + indexvd.getSafeSymbol() + " = ");
+                   writer.output("/* " + indexvd.getSafeSymbol() + " = ");
                    intindex.prettyPrint(writer);
-                   writer.outputline("");
+                   writer.outputline("*/");
                    Expr indexbound=((ArrayDescriptor)this.fd).getIndexBound();
                    VarDescriptor indexboundvd=VarDescriptor.makeNew("indexbound");
 
                    indexbound.generate(writer,indexboundvd);
-                   
+
                    writer.outputline("if ("+indexvd.getSafeSymbol()+">=0 &&"+indexvd.getSafeSymbol()+"<"+indexboundvd.getSafeSymbol()+")");
                    writer.startblock();
                    VarExpr indexve=new VarExpr(indexvd);
                    offsetbits = new OpExpr(Opcode.ADD, offsetbits, new OpExpr(Opcode.MULT, basesize, indexve));
-                   
+
                    performedboundscheck=true;
                } else
                    offsetbits = new OpExpr(Opcode.ADD, offsetbits, new OpExpr(Opcode.MULT, basesize, intindex));
@@ -241,56 +253,60 @@ public class DotExpr extends Expr {
                public IRErrorReporter getErrorReporter() { throw new IRException("badness"); }
                public SymbolTable getSymbolTable() { return st; }
            });
-       
+
         if (td2 == null) {
            throw new IRException();
         } else if (td2 != ReservedTypeDescriptor.INT) {
            throw new IRException();
        }
-               
+
         boolean dotypecheck = false;
 
        VarDescriptor ob = VarDescriptor.makeNew("offsetinbits");
-       writer.output("// " + ob.getSafeSymbol() + " <-- ");
+       writer.output("/* " + ob.getSafeSymbol() + " <-- ");
        offsetbits.prettyPrint(writer);
-       writer.outputline("");
+       writer.outputline("*/");
        offsetbits.generate(writer, ob);
-       writer.output("// " + ob.getSafeSymbol() + " = ");
+       writer.output("/* " + ob.getSafeSymbol() + " = ");
        offsetbits.prettyPrint(writer);
-       writer.outputline("");
-       
+       writer.outputline("*/");
+
        /* derive offset in bytes */
        VarDescriptor offset = VarDescriptor.makeNew("offset");
-       writer.outputline("int " + offset.getSafeSymbol() + " = " + ob.getSafeSymbol() + " >> 3;");
-       
+       writer.addDeclaration("int", offset.getSafeSymbol());
+       writer.outputline(offset.getSafeSymbol() + " = " + ob.getSafeSymbol() + " >> 3;");
+
        if (fd.getType() instanceof ReservedTypeDescriptor && !fd.getPtr()) {
            VarDescriptor shift = VarDescriptor.makeNew("shift");
-           writer.outputline("int " + shift.getSafeSymbol() + " = " + ob.getSafeSymbol() + 
+           writer.addDeclaration("int", shift.getSafeSymbol());
+           writer.outputline(shift.getSafeSymbol() + " = " + ob.getSafeSymbol() +
                              " - (" + offset.getSafeSymbol() + " << 3);");
            int mask = bitmask(((IntegerLiteralExpr)fd.getType().getSizeExpr()).getValue());
-           
+
            /* type var = ((*(int *) (base + offset)) >> shift) & mask */
            writer.outputline("if ("+leftd.getSafeSymbol()+")");
-           writer.outputline(dest.getSafeSymbol() + " = ((*(int *)" + 
-                             "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ")) " + 
-                             " >> " + shift.getSafeSymbol() + ") & 0x" + Integer.toHexString(mask) + ";");  
+           writer.outputline(dest.getSafeSymbol() + " = ((*(int *)" +
+                             "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ")) " +
+                             " >> " + shift.getSafeSymbol() + ") & 0x" + Integer.toHexString(mask) + ";");
            writer.outputline("else maybe=1;");
        } else { /* a structure address or a ptr */
            String ptr = fd.getPtr() ? "*(int *)" : "";
            /* type var = [*(int *)] (base + offset) */
            writer.outputline("if ("+leftd.getSafeSymbol()+")");
            writer.startblock();
-           writer.outputline(dest.getSafeSymbol() + 
-                             " = " + ptr + "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ");");  
+           writer.outputline(dest.getSafeSymbol() +
+                             " = " + ptr + "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ");");
            if (fd.getPtr()) {
                writer.outputline("if ("+dest.getSafeSymbol()+")");
                writer.startblock();
                VarDescriptor typevar=VarDescriptor.makeNew("typechecks");
                if (DOMEMCHECKS&&(!DOTYPECHECKS)) {
-                   writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidmemory(" + dest.getSafeSymbol() + ", " + this.td.getId() + ");");
+                   writer.addDeclaration("bool", typevar.getSafeSymbol());
+                   writer.outputline(typevar.getSafeSymbol()+"=assertvalidmemory(" + dest.getSafeSymbol() + ", " + this.td.getId() + ");");
                    dotypecheck = true;
                } else if (DOTYPECHECKS) {
-                   writer.outputline("bool "+typevar.getSafeSymbol()+"=assertvalidtype(" + dest.getSafeSymbol() + ", " + this.td.getId() + ");");
+                   writer.addDeclaration("bool", typevar.getSafeSymbol());
+                   writer.outputline(typevar.getSafeSymbol()+"=assertvalidtype(" + dest.getSafeSymbol() + ", " + this.td.getId() + ");");
                }
 
                if (DOTYPECHECKS||DOMEMCHECKS) {
@@ -321,13 +337,13 @@ public class DotExpr extends Expr {
 
     private int bitmask(int bits) {
         int mask = 0;
-        
+
         for (int i = 0; i < bits; i++) {
             mask <<= 1;
             mask += 1;
         }
 
-        return mask;            
+        return mask;
     }
 
     public void prettyPrint(PrettyPrinter pp) {
@@ -347,6 +363,13 @@ public class DotExpr extends Expr {
        return (tmpfd.getPtr()||(tmpfd.getType() instanceof ReservedTypeDescriptor));
     }
 
+    public boolean isPtr() {
+       FieldDescriptor tmpfd=fd;
+       if (tmpfd instanceof ArrayDescriptor)
+           tmpfd=((ArrayDescriptor)tmpfd).getField();
+       return tmpfd.getPtr();
+    }
+
     boolean typechecked=false;
     public TypeDescriptor typecheck(SemanticAnalyzer sa) {
        if (typechecked)
@@ -354,7 +377,7 @@ public class DotExpr extends Expr {
        else typechecked=true;
         TypeDescriptor lefttype = left.typecheck(sa);
         TypeDescriptor indextype = index == null ? null : index.typecheck(sa);
-       
+
        {
            /* finished typechecking...so we can fill the fields in */
            StructureTypeDescriptor struct = (StructureTypeDescriptor) left.getType();
@@ -368,6 +391,9 @@ public class DotExpr extends Expr {
                assert intindex == null;
                intindex = ld.getIndex();
            } else {
+                if (fd==null) {
+                    throw new Error("Null fd for: "+field);
+                }
                fieldtype = fd.getType();
                intindex=index;
            }
@@ -387,7 +413,7 @@ public class DotExpr extends Expr {
             }
         }
 
-        if (lefttype instanceof StructureTypeDescriptor) {            
+        if (lefttype instanceof StructureTypeDescriptor) {
             StructureTypeDescriptor struct = (StructureTypeDescriptor) lefttype;
             FieldDescriptor fd = struct.getField(field);
             LabelDescriptor ld = struct.getLabel(field);
@@ -397,21 +423,21 @@ public class DotExpr extends Expr {
 
                 if (indextype == null && fd instanceof ArrayDescriptor) {
                     sa.getErrorReporter().report(null, "Must specify an index what accessing array field '" + struct.getSymbol() + "." + fd.getSymbol() + "'");
-                    return null;                
+                    return null;
                 } else if (indextype != null && !(fd instanceof ArrayDescriptor)) {
                     sa.getErrorReporter().report(null, "Cannot specify an index when accessing non-array field '" + struct.getSymbol() + "." + fd.getSymbol() + "'");
                     return null;
                 }
-                
+
                 this.td = fd.getType();
             } else if (ld != null) { /* label */
                 assert fd == null;
 
-                if (index != null) { 
+                if (index != null) {
                     sa.getErrorReporter().report(null, "A label cannot be accessed as an array");
                     return null;
                 }
-                
+
                 this.td = ld.getType();
             } else {
                 sa.getErrorReporter().report(null, "No such field or label '" + field + "' in structure '" + struct.getSymbol() + "'");
@@ -432,4 +458,3 @@ public class DotExpr extends Expr {
         }
     }
 }
-