in Sources/SolToBoogie/ProcedureTranslator.cs [687:800]
private void GenerateInitializationForMappingStateVar(VariableDeclaration varDecl, Mapping mapping)
{
BoogieMapSelect lhsMap = CreateDistinctArrayMappingAddress(currentStmtList, varDecl);
//nested arrays (only 1 level for now)
if (mapping.ValueType is ArrayTypeName array)
{
Console.WriteLine($"Warning: A mapping with nested array {varDecl.Name} of valuetype {mapping.ValueType.ToString()}");
InitializeNestedArrayMappingStateVar(varDecl, mapping);
}
else if (mapping.ValueType is Mapping mappingNested)
{
InitializeNestedArrayMappingStateVar(varDecl, mapping);
// TODO: add the initialization of m[i][j]
}
else if (mapping.ValueType is UserDefinedTypeName userTypeName ||
mapping.ValueType.ToString().Equals("address") ||
mapping.ValueType.ToString().Equals("address payable") ||
mapping.ValueType.ToString().StartsWith("bytes")
)
{
currentStmtList.AddStatement(new BoogieCommentCmd($"Initialize address/contract mapping {varDecl.Name}"));
BoogieType mapKeyType;
BoogieMapSelect lhs;
GetBoogieTypesFromMapping(varDecl, mapping, out mapKeyType, out lhs);
if (!context.TranslateFlags.QuantFreeAllocs)
{
var qVar = QVarGenerator.NewQVar(0, 0);
BoogieExpr zeroExpr = new BoogieIdentifierExpr("null");
if (mapping.ValueType.ToString().StartsWith("bytes"))
zeroExpr = new BoogieLiteralExpr(BigInteger.Zero);
var bodyExpr = new BoogieBinaryOperation(
BoogieBinaryOperation.Opcode.EQ,
new BoogieMapSelect(lhs, qVar),
zeroExpr);
var qExpr = new BoogieQuantifiedExpr(true, new List<BoogieIdentifierExpr>() {qVar},
new List<BoogieType>() {mapKeyType}, bodyExpr);
currentStmtList.AddStatement(new BoogieAssumeCmd(qExpr));
}
else
{
if (mapping.ValueType.ToString().StartsWith("bytes"))
currentStmtList.AddStatement(new BoogieAssignCmd(lhs,
GetCallExprForZeroInit(mapKeyType, BoogieType.Int)));
else
currentStmtList.AddStatement(new BoogieAssignCmd(lhs, GetCallExprForZeroInit(mapKeyType, BoogieType.Ref)));
}
}
else if (mapping.ValueType.ToString().Equals("bool"))
{
currentStmtList.AddStatement(new BoogieCommentCmd($"Initialize Boolean mapping {varDecl.Name}"));
BoogieType mapKeyType;
BoogieMapSelect lhs;
GetBoogieTypesFromMapping(varDecl, mapping, out mapKeyType, out lhs);
if (!context.TranslateFlags.QuantFreeAllocs)
{
var qVar = QVarGenerator.NewQVar(0, 0);
var bodyExpr =
new BoogieUnaryOperation(BoogieUnaryOperation.Opcode.NOT, new BoogieMapSelect(lhs, qVar));
var qExpr = new BoogieQuantifiedExpr(true, new List<BoogieIdentifierExpr>() {qVar},
new List<BoogieType>() {mapKeyType}, bodyExpr);
currentStmtList.AddStatement(new BoogieAssumeCmd(qExpr));
}
else
{
currentStmtList.AddStatement(new BoogieAssignCmd(lhs, GetCallExprForZeroInit(mapKeyType, BoogieType.Bool)));
}
}
// TODO: Cleanup, StartsWith("uint") can include uint[12] as well.
else if (mapping.ValueType.ToString().StartsWith("uint") ||
mapping.ValueType.ToString().StartsWith("int"))
{
// Issue a warning for intXX type in case /useModularArithemtic option is used:
if (context.TranslateFlags.UseModularArithmetic && mapping.ValueType.ToString().StartsWith("int"))
{
Console.WriteLine($"Warning: signed integer arithmetic is not handled with /useModularArithmetic option");
}
currentStmtList.AddStatement(new BoogieCommentCmd($"Initialize Integer mapping {varDecl.Name}"));
BoogieType mapKeyType;
BoogieMapSelect lhs;
GetBoogieTypesFromMapping(varDecl, mapping, out mapKeyType, out lhs);
if (!context.TranslateFlags.QuantFreeAllocs)
{
var qVar = QVarGenerator.NewQVar(0, 0);
var bodyExpr = new BoogieBinaryOperation(
BoogieBinaryOperation.Opcode.EQ,
new BoogieMapSelect(lhs, qVar),
new BoogieLiteralExpr(0));
var qExpr = new BoogieQuantifiedExpr(true, new List<BoogieIdentifierExpr>() {qVar},
new List<BoogieType>() {mapKeyType}, bodyExpr);
currentStmtList.AddStatement(new BoogieAssumeCmd(qExpr));
}
else
{
currentStmtList.AddStatement(new BoogieAssignCmd(lhs, GetCallExprForZeroInit(mapKeyType, BoogieType.Int)));
}
if (context.TranslateFlags.InstrumentSums)
{
currentStmtList.AddStatement(new BoogieAssignCmd(getSumAccess(lhsMap), new BoogieLiteralExpr(BigInteger.Zero)));
}
}
else
{
Console.WriteLine($"Warning: A mapping with complex value type {varDecl.Name} of valuetype {mapping.ValueType.ToString()}");
}
}