00001 package edu.ksu.cis.bandera.abstraction;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 import ca.mcgill.sable.soot.*;
00037 import ca.mcgill.sable.soot.grimp.*;
00038 import ca.mcgill.sable.soot.jimple.*;
00039 import java.util.*;
00040 import edu.ksu.cis.bandera.jext.*;
00041 import edu.ksu.cis.bandera.abstraction.typeinference.*;
00042 public class PredicateTypeChecker extends AbstractBanderaValueSwitch {
00043 private CoercionManager cm;
00044 private TypeTable typeTable;
00045 private Vector messages = new Vector();
00046 private Hashtable variableSetTable;
00047
00048
00049
00050
00051 private PredicateTypeChecker(CoercionManager cm, TypeTable typeTable, Hashtable varSetTable) {
00052 this.cm = cm;
00053 this.typeTable = typeTable;
00054 variableSetTable = varSetTable;
00055 }
00056 public void caseAddExpr(AddExpr v) {
00057 doBinop(v);
00058 }
00059 public void caseAndExpr(AndExpr v) {
00060 doBinop(v);
00061 }
00062 public void caseArrayRef(ArrayRef v) {
00063 v.getBase().apply(this);
00064 typeTable.put(v, ((ArrayAbstraction) typeTable.get(v.getBase())).getIndexAbstraction());
00065 HashSet variableSet = new HashSet(2);
00066 variableSet.add(v);
00067 variableSetTable.put(v, variableSet);
00068 }
00069 public void caseCastExpr(CastExpr v) {
00070 v.getOp().apply(this);
00071 typeTable.put(v, typeTable.get(v.getOp()));
00072 HashSet variableSet = new HashSet();
00073 variableSet.addAll((Set) variableSetTable.get(v.getOp()));
00074 variableSetTable.put(v, variableSet);
00075 }
00076
00077
00078
00079
00080 public void caseComplementExpr(ComplementExpr expr) {
00081 expr.getOp().apply(this);
00082 HashSet variableSet = new HashSet();
00083 variableSet.addAll((Set) variableSetTable.get(expr.getOp()));
00084 variableSetTable.put(expr, variableSet);
00085 }
00086 public void caseDivExpr(DivExpr v) {
00087 doBinop(v);
00088 }
00089 public void caseDoubleConstant(DoubleConstant v) {
00090 typeTable.put(v, ConcreteRealAbstraction.v());
00091 variableSetTable.put(v, new HashSet(0));
00092 }
00093 public void caseEqExpr(EqExpr v) {
00094 doBinop(v);
00095 }
00096 public void caseFloatConstant(FloatConstant v) {
00097 typeTable.put(v, ConcreteRealAbstraction.v());
00098 variableSetTable.put(v, new HashSet(0));
00099 }
00100 public void caseGeExpr(GeExpr v) {
00101 doBinop(v);
00102 }
00103 public void caseGtExpr(GtExpr v) {
00104 doBinop(v);
00105 }
00106 public void caseInstanceFieldRef(InstanceFieldRef v) {
00107 v.getBase().apply(this);
00108 typeTable.put(v, typeTable.get(v.getField()));
00109 HashSet variableSet = new HashSet();
00110 variableSet.add(v);
00111 variableSet.addAll((Set) variableSetTable.get(v.getBase()));
00112 variableSetTable.put(v, variableSet);
00113 }
00114 public void caseInstanceOfExpr(InstanceOfExpr v) {
00115 v.getOp().apply(this);
00116 typeTable.put(v, ConcreteIntegralAbstraction.v());
00117 HashSet variableSet = new HashSet();
00118 variableSet.addAll((Set) variableSetTable.get(v.getOp()));
00119 variableSetTable.put(v, variableSet);
00120 }
00121 public void caseIntConstant(IntConstant v) {
00122 typeTable.put(v, ConcreteIntegralAbstraction.v());
00123 variableSetTable.put(v, new HashSet(0));
00124 }
00125 public void caseLeExpr(LeExpr v) {
00126 doBinop(v);
00127 }
00128 public void caseLengthExpr(LengthExpr v) {
00129 v.getOp().apply(this);
00130 typeTable.put(v, ((ArrayAbstraction) typeTable.get(v.getOp())).getIndexAbstraction());
00131 HashSet variableSet = new HashSet();
00132 variableSet.add(v);
00133 variableSet.addAll((Set) variableSetTable.get(v.getOp()));
00134 variableSetTable.put(v, variableSet);
00135 }
00136
00137
00138
00139
00140 public void caseLocalExpr(LocalExpr v) {
00141 typeTable.put(v, typeTable.get(v.getLocal()));
00142 HashSet variableSet = new HashSet(2);
00143 variableSet.add(v);
00144 variableSetTable.put(v, variableSet);
00145 }
00146
00147
00148
00149
00150 public void caseLocationTestExpr(LocationTestExpr e) {
00151 variableSetTable.put(e, new HashSet());
00152 }
00153
00154
00155
00156
00157 public void caseLogicalAndExpr(LogicalAndExpr expr) {
00158 expr.getOp1().apply(this);
00159 expr.getOp2().apply(this);
00160 HashSet variableSet = new HashSet();
00161 variableSet.addAll((Set) variableSetTable.get(expr.getOp1()));
00162 variableSet.addAll((Set) variableSetTable.get(expr.getOp2()));
00163 variableSetTable.put(expr, variableSet);
00164 }
00165
00166
00167
00168
00169 public void caseLogicalOrExpr(LogicalOrExpr expr) {
00170 expr.getOp1().apply(this);
00171 expr.getOp2().apply(this);
00172 HashSet variableSet = new HashSet();
00173 variableSet.addAll((Set) variableSetTable.get(expr.getOp1()));
00174 variableSet.addAll((Set) variableSetTable.get(expr.getOp2()));
00175 variableSetTable.put(expr, variableSet);
00176 }
00177 public void caseLongConstant(LongConstant v) {
00178 typeTable.put(v, ConcreteIntegralAbstraction.v());
00179 variableSetTable.put(v, new HashSet(0));
00180 }
00181 public void caseLtExpr(LtExpr v) {
00182 doBinop(v);
00183 }
00184 public void caseMulExpr(MulExpr v) {
00185 doBinop(v);
00186 }
00187 public void caseNeExpr(NeExpr v) {
00188 doBinop(v);
00189 }
00190 public void caseNegExpr(NegExpr v) {
00191 v.getOp().apply(this);
00192 typeTable.put(v, typeTable.get(v.getOp()));
00193 HashSet variableSet = new HashSet();
00194 variableSet.addAll((Set) variableSetTable.get(v.getOp()));
00195 variableSetTable.put(v, variableSet);
00196 }
00197 public void caseNullConstant(NullConstant v) {
00198 typeTable.put(v, ClassAbstraction.v("java.lang.Object"));
00199 variableSetTable.put(v, new HashSet(0));
00200 }
00201 public void caseOrExpr(OrExpr v) {
00202 doBinop(v);
00203 }
00204 public void caseRemExpr(RemExpr v) {
00205 doBinop(v);
00206 }
00207 public void caseShlExpr(ShlExpr v) {
00208 doBinop(v);
00209 }
00210 public void caseShrExpr(ShrExpr v) {
00211 doBinop(v);
00212 }
00213 public void caseStaticFieldRef(StaticFieldRef v) {
00214 typeTable.put(v, typeTable.get(v.getField()));
00215 HashSet variableSet = new HashSet(2);
00216 variableSet.add(v);
00217 variableSetTable.put(v, variableSet);
00218 }
00219 public void caseStringConstant(StringConstant v) {
00220 typeTable.put(v, ClassAbstraction.v("java.lang.String"));
00221 variableSetTable.put(v, new HashSet(0));
00222 }
00223 public void caseSubExpr(SubExpr v) {
00224 doBinop(v);
00225 }
00226 public void caseUshrExpr(UshrExpr v) {
00227 doBinop(v);
00228 }
00229 public void caseXorExpr(XorExpr v) {
00230 doBinop(v);
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 public static Vector check(CoercionManager cm, TypeTable typeTable, Value predicate, Hashtable varSetTable) {
00240 PredicateTypeChecker ptc = new PredicateTypeChecker(cm, typeTable, varSetTable);
00241 predicate.apply(ptc);
00242 return ptc.messages;
00243 }
00244
00245
00246
00247
00248 private void doBinop(BinopExpr v) {
00249
00250 Value v1 = v.getOp1();
00251 Value v2 = v.getOp2();
00252 Type v1type = v1.getType();
00253 v1.apply(this);
00254 if (v2 instanceof NullConstant)
00255 {
00256 if (v1type instanceof RefType)
00257 {
00258 typeTable.put(v2, ClassAbstraction.v(((RefType) v1type).className));
00259 variableSetTable.put(v2, new HashSet(0));
00260 } else if (v1type instanceof ArrayType)
00261 {
00262
00263
00264 v2.apply(this);
00265 } else v2.apply(this);
00266
00267 } else v2.apply(this);
00268
00269
00270
00271 HashSet types = new HashSet();
00272 types.add(typeTable.get(v.getOp1()));
00273 types.add(typeTable.get(v.getOp2()));
00274 Abstraction a = cm.lub(types);
00275 if (a != null)
00276 typeTable.put(v, a);
00277 else
00278 messages.add("Type mismatch for " + v);
00279 if ((a instanceof ClassAbstraction) || (a instanceof ArrayAbstraction)) {
00280
00281 } else if (((a != typeTable.get(v.getOp1())) && !(v.getOp1() instanceof Constant))
00282 || ((a != typeTable.get(v.getOp2())) && !(v.getOp2() instanceof Constant))) {
00283 throw new RuntimeException("Type mismatch for " + v + "\nNote: Cannot coerce a variable in a predicate");
00284 }
00285 typeTable.put(v.getOp1(), a);
00286 typeTable.put(v.getOp2(), a);
00287 HashSet variableSet = new HashSet();
00288 variableSet.addAll((Set) variableSetTable.get(v.getOp1()));
00289 variableSet.addAll((Set) variableSetTable.get(v.getOp2()));
00290 variableSetTable.put(v, variableSet);
00291 }
00292 }