CommonMallocStatement.java
package dev.civl.mc.model.common.statement;
import java.util.HashSet;
import java.util.Set;
import dev.civl.mc.model.IF.CIVLSource;
import dev.civl.mc.model.IF.Scope;
import dev.civl.mc.model.IF.expression.ConditionalExpression;
import dev.civl.mc.model.IF.expression.Expression;
import dev.civl.mc.model.IF.expression.LHSExpression;
import dev.civl.mc.model.IF.expression.VariableExpression;
import dev.civl.mc.model.IF.location.Location;
import dev.civl.mc.model.IF.statement.MallocStatement;
import dev.civl.mc.model.IF.statement.Statement;
import dev.civl.mc.model.IF.type.CIVLType;
import dev.civl.mc.model.IF.variable.Variable;
import dev.civl.sarl.IF.SymbolicUniverse;
import dev.civl.sarl.IF.type.SymbolicArrayType;
import dev.civl.sarl.IF.type.SymbolicType;
public class CommonMallocStatement extends CommonStatement
implements
MallocStatement {
private int id;
private Expression scopeExpression;
private CIVLType staticElementType;
private SymbolicType dynamicElementType;
private SymbolicArrayType dynamicObjectType;
private Expression sizeExpression;
private LHSExpression lhs;
public CommonMallocStatement(CIVLSource civlSource, Scope hscope,
Scope lscope, Location source, Expression guard, int mallocId,
Expression heapPointerExpression, CIVLType staticElementType,
SymbolicType dynamicElementType,
SymbolicArrayType dynamicObjectType, Expression sizeExpression,
LHSExpression lhs) {
super(civlSource, hscope, lscope, source, guard);
this.id = mallocId;
this.scopeExpression = heapPointerExpression;
this.staticElementType = staticElementType;
this.dynamicElementType = dynamicElementType;
this.dynamicObjectType = dynamicObjectType;
this.sizeExpression = sizeExpression;
this.lhs = lhs;
}
@Override
public int getMallocId() {
return id;
}
@Override
public Expression getScopeExpression() {
return scopeExpression;
}
@Override
public CIVLType getStaticElementType() {
return staticElementType;
}
@Override
public SymbolicType getDynamicElementType() {
return dynamicElementType;
}
@Override
public SymbolicArrayType getDynamicObjectType() {
return dynamicObjectType;
}
@Override
public Expression getSizeExpression() {
return sizeExpression;
}
@Override
public LHSExpression getLHS() {
return lhs;
}
@Override
public String toString() {
String result;
if (lhs != null)
result = lhs + " = ";
else
result = "";
result += "(" + staticElementType + "*" + ")";
result += "$malloc(" + scopeExpression + ", " + sizeExpression + ")";
return result;
}
@Override
public void calculateDerefs() {
this.hasDerefs = false;
if (lhs != null) {
lhs.calculateDerefs();
hasDerefs = lhs.hasDerefs();
}
// this.heapPointerExpression.calculateDerefs();
// this.sizeExpression.calculateDerefs();
// this.hasDerefs = lhsDeref || this.heapPointerExpression.hasDerefs()
// || this.sizeExpression.hasDerefs();
}
@Override
public void purelyLocalAnalysisOfVariables(Scope funcScope) {
super.purelyLocalAnalysisOfVariables(funcScope);
if (lhs != null) {
lhs.purelyLocalAnalysisOfVariables(funcScope);
}
this.scopeExpression.purelyLocalAnalysisOfVariables(funcScope);
this.sizeExpression.purelyLocalAnalysisOfVariables(funcScope);
}
@Override
public void purelyLocalAnalysis() {
this.guard().purelyLocalAnalysis();
boolean lhsPL = true;
if (lhs != null) {
lhs.purelyLocalAnalysis();
lhsPL = lhs.isPurelyLocal();
}
this.scopeExpression.purelyLocalAnalysis();
this.sizeExpression.purelyLocalAnalysis();
this.purelyLocal = lhsPL && this.guard().isPurelyLocal()
&& this.scopeExpression.isPurelyLocal()
&& this.sizeExpression.isPurelyLocal();
}
@Override
public void replaceWith(ConditionalExpression oldExpression,
VariableExpression newExpression) {
super.replaceWith(oldExpression, newExpression);
if (sizeExpression == oldExpression) {
sizeExpression = newExpression;
return;
}
this.sizeExpression.replaceWith(oldExpression, newExpression);
}
@Override
public Statement replaceWith(ConditionalExpression oldExpression,
Expression newExpression) {
Expression newGuard = guardReplaceWith(oldExpression, newExpression);
CommonMallocStatement newStatement = null;
if (newGuard != null) {
newStatement = new CommonMallocStatement(this.getSource(),
this.statementScope, this.lowestScope, this.source(),
newGuard, this.id, this.scopeExpression, staticElementType,
dynamicElementType, dynamicObjectType, this.sizeExpression,
lhs);
} else {
Expression newSizeExpression = sizeExpression
.replaceWith(oldExpression, newExpression);
if (newSizeExpression != null) {
newStatement = new CommonMallocStatement(this.getSource(),
this.statementScope, this.lowestScope, this.source(),
this.guard(), id, this.scopeExpression,
staticElementType, dynamicElementType,
dynamicObjectType, newSizeExpression, lhs);
}
}
return newStatement;
}
@Override
public Set<Variable> variableAddressedOf(Scope scope) {
Set<Variable> result = new HashSet<>();
Set<Variable> argumentResult;
if (lhs != null) {
Variable lhsVariable = lhs.variableWritten(scope);
if (lhsVariable != null)
result.add(lhsVariable);
}
argumentResult = scopeExpression.variableAddressedOf(scope);
if (argumentResult != null)
result.addAll(argumentResult);
argumentResult = sizeExpression.variableAddressedOf(scope);
if (argumentResult != null)
result.addAll(argumentResult);
return result;
}
@Override
public Set<Variable> variableAddressedOf() {
Set<Variable> result = new HashSet<>();
Set<Variable> argumentResult;
argumentResult = scopeExpression.variableAddressedOf();
if (argumentResult != null)
result.addAll(argumentResult);
argumentResult = sizeExpression.variableAddressedOf();
if (argumentResult != null)
result.addAll(argumentResult);
return result;
}
@Override
public StatementKind statementKind() {
return StatementKind.MALLOC;
}
@Override
protected void calculateConstantValueWork(SymbolicUniverse universe) {
// TODO Auto-generated method stub
}
@Override
protected boolean containsHereWork() {
return this.scopeExpression.containsHere();
}
@Override
public void complete(SymbolicType dynamicElementType,
SymbolicArrayType dynamicObjectType) {
this.dynamicElementType = dynamicElementType;
this.dynamicObjectType = dynamicObjectType;
}
@Override
public boolean equals(Object obj) {
if (super.equals(obj)) {
CommonMallocStatement other = (CommonMallocStatement) obj;
return other.id == id;
}
return false;
}
@Override
public Set<Variable> freeVariables() {
Set<Variable> result = super.freeVariables();
if (lhs != null)
result.addAll(lhs.freeVariables());
if (scopeExpression != null)
result.addAll(scopeExpression.freeVariables());
result.addAll(sizeExpression.freeVariables());
if (staticElementType != null)
result.addAll(staticElementType.freeVariables());
return result;
}
}