//Construct Memory Maps for Arrays for Mapping and ArrayTypeName types. private void ConstructMappingMemoryArray(Mapping mapping, HashSet <KeyValuePair <BoogieType, BoogieType> > generatedTypes) { BoogieType boogieKeyType = Conversion_Utility_Tool.GetBoogieTypeFromSolidityTypeName(mapping.KeyType); BoogieType boogieValueType = null; if (mapping.ValueType is Mapping submapping) { boogieValueType = BoogieType.Ref; ConstructMappingMemoryArray(submapping, generatedTypes); } else if (mapping.ValueType is ArrayTypeName array) { boogieValueType = BoogieType.Ref; ConstructArrayMemoryMap(array, generatedTypes); } else { boogieValueType = Conversion_Utility_Tool.GetBoogieTypeFromSolidityTypeName(mapping.ValueType); } KeyValuePair <BoogieType, BoogieType> pair = new KeyValuePair <BoogieType, BoogieType>(boogieKeyType, boogieValueType); if (!generatedTypes.Contains(pair)) { generatedTypes.Add(pair); BuildSingleMapMemoryName(boogieKeyType, boogieValueType); } }
public BoogieTypedIdent MakeFreshTypedIdent(BoogieType type) { int index = ++freshIdentifierCount; string name = "__var_" + index; return(new BoogieTypedIdent(name, type)); }
//generate fresh identifier using BoogieType public BoogieTypedIdent createFreshIdentifier(BoogieType type) { //return new BoogieTypedIdent. string name = "__var_" + indentifierCount; return(new BoogieTypedIdent(name, type)); }
private List <BoogieVariable> GetParamsOfFunction(FunctionDefinition funcDef) { List <BoogieVariable> parameters = new List <BoogieVariable>(); foreach (VariableDeclaration param in funcDef.Parameters.Parameters) { string name = TransUtils.GetCanonicalLocalVariableName(param); BoogieType type = TransUtils.GetBoogieTypeFromSolidityTypeName(param.TypeName); BoogieVariable localVar = new BoogieLocalVariable(new BoogieTypedIdent(name, type)); parameters.Add(localVar); } var retParamCount = 0; foreach (VariableDeclaration param in funcDef.ReturnParameters.Parameters) { //string name = "__ret" + funcDef.Name; string name = $"__ret_{retParamCount++}_" + funcDef.Name; if (!string.IsNullOrEmpty(param.Name)) { name = TransUtils.GetCanonicalLocalVariableName(param); } BoogieType type = TransUtils.GetBoogieTypeFromSolidityTypeName(param.TypeName); BoogieVariable localVar = new BoogieLocalVariable(new BoogieTypedIdent(name, type)); parameters.Add(localVar); } return(parameters); }
private void GenerateMemoryVariablesForArray(ArrayTypeName array, HashSet <KeyValuePair <BoogieType, BoogieType> > generatedTypes) { BoogieType boogieKeyType = BoogieType.Int; BoogieType boogieValType = null; if (array.BaseType is ArrayTypeName subarray) { boogieValType = BoogieType.Ref; GenerateMemoryVariablesForArray(subarray, generatedTypes); } else if (array.BaseType is Mapping mapping) { boogieValType = BoogieType.Ref; GenerateMemoryVariablesForMapping(mapping, generatedTypes); } else { boogieValType = TransUtils.GetBoogieTypeFromSolidityTypeName(array.BaseType); } KeyValuePair <BoogieType, BoogieType> pair = new KeyValuePair <BoogieType, BoogieType>(boogieKeyType, boogieValType); if (!generatedTypes.Contains(pair)) { generatedTypes.Add(pair); GenerateSingleMemoryVariable(boogieKeyType, boogieValType); } }
//Build Memory Map for Array types, private void ConstructArrayMemoryMap(ArrayTypeName array, HashSet <KeyValuePair <BoogieType, BoogieType> > generatedTypes) { BoogieType boogieKeyType = BoogieType.Int; BoogieType boogieValueType = null; if (array.BaseType is ArrayTypeName subarray) { boogieValueType = BoogieType.Ref; ConstructArrayMemoryMap(subarray, generatedTypes); //construct array memory map with sub array } else if (array.BaseType is Mapping mapping) { boogieValueType = BoogieType.Ref; ConstructMappingMemoryArray(mapping, generatedTypes); // construct array memory map using mapping type } else { boogieValueType = Conversion_Utility_Tool.GetBoogieTypeFromSolidityTypeName(array.BaseType); //type cannot be resolve, request type declaration } KeyValuePair <BoogieType, BoogieType> pair = new KeyValuePair <BoogieType, BoogieType>(boogieKeyType, boogieValueType); if (generatedTypes.Contains(pair) == false) { generatedTypes.Add(pair); BuildSingleMapMemoryName(boogieKeyType, boogieValueType); } }
public BoogieExpr GetMemoryMapSelectExpr(VariableDeclaration decl, BoogieType mapKeyType, BoogieType mapValType, BoogieExpr baseExpr, BoogieExpr indexExpr) { string mapName = GetMemoryMapName(decl, mapKeyType, mapValType); BoogieIdentifierExpr mapIdent = new BoogieIdentifierExpr(mapName); BoogieMapSelect mapSelectExpr = new BoogieMapSelect(mapIdent, baseExpr); mapSelectExpr = new BoogieMapSelect(mapSelectExpr, indexExpr); return(mapSelectExpr); }
public string GetMemoryMapName(VariableDeclaration decl, BoogieType keyType, BoogieType valType) { if (notAliased(decl) && !context.TranslateFlags.UseMultiDim) { return(GetCanonicalMemName(keyType, valType) + "_" + context.Analysis.Alias.getGroupName(decl)); } return(GetCanonicalMemName(keyType, valType)); }
private List <BoogieVariable> CollectLocalVars(ContractDefinition contract) { List <BoogieVariable> localVars = new List <BoogieVariable>() { new BoogieLocalVariable(new BoogieTypedIdent("this", BoogieType.Ref)), new BoogieLocalVariable(new BoogieTypedIdent("msgsender_MSG", BoogieType.Ref)), new BoogieLocalVariable(new BoogieTypedIdent("msgvalue_MSG", BoogieType.Int)), new BoogieLocalVariable(new BoogieTypedIdent("choice", BoogieType.Int)), }; // use to remove duplicated variables by name HashSet <string> uniqueVarNames = new HashSet <string>() { "this", "msgsender_MSG", "msgvalue_MSG", "choice" }; // Consider all visible functions HashSet <FunctionDefinition> funcDefs = context.GetVisibleFunctionsByContract(contract); foreach (FunctionDefinition funcDef in funcDefs) { if (funcDef.Visibility == EnumVisibility.PUBLIC || funcDef.Visibility == EnumVisibility.EXTERNAL) { foreach (VariableDeclaration param in funcDef.Parameters.Parameters) { string name = TransUtils.GetCanonicalLocalVariableName(param); if (!uniqueVarNames.Contains(name)) { BoogieType type = TransUtils.GetBoogieTypeFromSolidityTypeName(param.TypeName); BoogieVariable localVar = new BoogieLocalVariable(new BoogieTypedIdent(name, type)); localVars.Add(localVar); uniqueVarNames.Add(name); } } var retParamCount = 0; foreach (VariableDeclaration param in funcDef.ReturnParameters.Parameters) { //string name = "__ret" + funcDef.Name; string name = $"__ret_{retParamCount++}_" + funcDef.Name; if (!string.IsNullOrEmpty(param.Name)) { name = TransUtils.GetCanonicalLocalVariableName(param); } if (!uniqueVarNames.Contains(name)) { BoogieType type = TransUtils.GetBoogieTypeFromSolidityTypeName(param.TypeName); BoogieVariable localVar = new BoogieLocalVariable(new BoogieTypedIdent(name, type)); localVars.Add(localVar); uniqueVarNames.Add(name); } } } } return(localVars); }
//return a BoogieExpression public static BoogieExpr GetMemoryMapSelectExpr(BoogieType mapKeyType, BoogieType mapValType, BoogieExpr baseExpr, BoogieExpr indexExpr) { string generateMapName = generateMemoryMapName(mapKeyType, mapValType); BoogieIdentifierExpr mapIdentifier = new BoogieIdentifierExpr(generateMapName); BoogieMapSelect mapSelectExpr = new BoogieMapSelect(mapIdentifier, baseExpr); mapSelectExpr = new BoogieMapSelect(mapSelectExpr, indexExpr); return(mapSelectExpr); }
private void GenerateSingleMemoryVariable(BoogieType keyType, BoogieType valType) { BoogieMapType map = new BoogieMapType(keyType, valType); map = new BoogieMapType(BoogieType.Ref, map); string name = MapArrayHelper.GetMemoryMapName(keyType, valType); context.Program.AddDeclaration(new BoogieGlobalVariable(new BoogieTypedIdent(name, map))); }
//Build Single Memory Map using key and value types private void BuildSingleMapMemoryName(BoogieType keyTypes, BoogieType valueTypes) { BoogieMapType map = new BoogieMapType(keyTypes, valueTypes); map = new BoogieMapType(BoogieType.Ref, map); string name = Flags_HelperClass.generateMemoryMapName(keyTypes, valueTypes); context.getProgram.AddBoogieDeclaration(new BoogieGlobalVariable(new BoogieTypedIdent(name, map))); }
public static BoogieFuncCallExpr GetCallExprForZeroInit(BoogieType curType) { string fnName = "zero"; while (curType is BoogieMapType map) { fnName = $"{fnName}{String.Join("", map.Arguments)}"; curType = map.Result; } fnName = $"{fnName}{curType}Arr"; return(new BoogieFuncCallExpr(fnName, new List <BoogieExpr>())); }
private void GenerateBoogieRecord(string typeName, BoogieType btype) { // generate the internal one without base constructors string procName = "boogie_si_record_sol2Bpl_" + typeName; var inVar = new BoogieFormalParam(new BoogieTypedIdent("x", btype)); List <BoogieVariable> inParams = new List <BoogieVariable>() { inVar }; List <BoogieVariable> outParams = new List <BoogieVariable>(); BoogieProcedure procedure = new BoogieProcedure(procName, inParams, outParams, null); context.Program.AddDeclaration(procedure); }
public List <BoogieDeclaration> GetMultiDimArrayLens(VariableDeclaration decl) { List <BoogieDeclaration> lenVars = new List <BoogieDeclaration>(); TypeName curType = decl.TypeName; List <BoogieType> indTypes = new List <BoogieType>() { BoogieType.Ref }; int lvl = 0; while (curType is Mapping || curType is ArrayTypeName) { if (curType is Mapping map) { curType = map.ValueType; indTypes.Add(TransUtils.GetBoogieTypeFromSolidityTypeName(map.KeyType)); } else if (curType is ArrayTypeName arr) { BoogieType mapType = BoogieType.Int; BoogieType initType = BoogieType.Int; for (int i = indTypes.Count - 1; i >= 0; i--) { initType = mapType; mapType = new BoogieMapType(indTypes[i], mapType); } if (arr.Length != null && initType is BoogieMapType lenMap) { BoogieFunction initFn = GenerateMultiDimInitFunction(lenMap); lenVars.Add(initFn); } BoogieGlobalVariable lenVar = new BoogieGlobalVariable(new BoogieTypedIdent(GetMultiDimLengthName(decl, lvl), mapType)); lenVars.Add(lenVar); curType = arr.BaseType; indTypes.Add(BoogieType.Int); } lvl++; } return(lenVars); }
public static BoogieFunction GenerateMultiDimZeroFunction(VariableDeclaration decl) { TypeName curType = decl.TypeName; List <BoogieType> boogieType = new List <BoogieType>(); while (curType is Mapping || curType is ArrayTypeName) { if (curType is Mapping map) { boogieType.Insert(0, TransUtils.GetBoogieTypeFromSolidityTypeName(map.KeyType)); curType = map.ValueType; } else if (curType is ArrayTypeName arr) { boogieType.Insert(0, BoogieType.Int); curType = arr.BaseType; } } BoogieType valType = TransUtils.GetBoogieTypeFromSolidityTypeName(curType); BoogieExpr boogieInit = TransUtils.GetDefaultVal(valType); string smtType = GetSmtType(valType); string smtInit = boogieInit.ToString().Equals("null") ? "0" : boogieInit.ToString(); BoogieType mapType = valType; string fnName = $"{valType.ToString()}Arr"; foreach (BoogieType type in boogieType) { smtType = $"(Array {GetSmtType(type)} {smtType})"; mapType = new BoogieMapType(type, mapType); smtInit = $"((as const {smtType}) {smtInit})"; fnName = $"{type.ToString()}{fnName}"; } var outVar = new BoogieFormalParam(new BoogieTypedIdent("ret", mapType)); var smtDefinedAttr = new BoogieAttribute("smtdefined", $"\"{smtInit}\""); return(new BoogieFunction($"zero{fnName}", new List <BoogieVariable>(), new List <BoogieVariable>() { outVar }, new List <BoogieAttribute>() { smtDefinedAttr })); }
public static string GetSmtType(BoogieType type) { if (type.Equals(BoogieType.Bool)) { return("Bool"); } else if (type.Equals(BoogieType.Int)) { return("Int"); } else if (type.Equals(BoogieType.Ref)) { return("Int"); } throw new Exception($"Unknown BoogieType {type}"); }
public static BoogieExpr GetDefaultVal(BoogieType boogieType) { if (boogieType.Equals(BoogieType.Int)) { return(new BoogieLiteralExpr(BigInteger.Zero)); } else if (boogieType.Equals(BoogieType.Bool)) { return(new BoogieLiteralExpr(false)); } else if (boogieType.Equals(BoogieType.Ref)) { return(new BoogieIdentifierExpr("null")); } throw new Exception($"Unknown BoogieType {boogieType}"); }
public static BoogieFunction GenerateMultiDimInitFunction(BoogieMapType type) { BoogieType curType = type; List <BoogieType> boogieType = new List <BoogieType>(); while (curType is BoogieMapType map) { if (map.Arguments.Count != 1) { throw new Exception("Boogie map must have one argument"); } boogieType.Insert(0, map.Arguments[0]); curType = map.Result; } BoogieVariable arg = new BoogieFormalParam(new BoogieTypedIdent("n", curType)); string smtInit = "n"; string smtType = GetSmtType(curType); string fnName = $"{curType.ToString()}Arr"; foreach (BoogieType dimType in boogieType) { smtType = $"(Array {GetSmtType(dimType)} {smtType})"; smtInit = $"((as const {smtType}) {smtInit})"; fnName = $"{dimType.ToString()}{fnName}"; } var outVar = new BoogieFormalParam(new BoogieTypedIdent("ret", type)); var smtDefinedAttr = new BoogieAttribute("smtdefined", $"\"{smtInit}\""); return(new BoogieFunction($"init{fnName}", new List <BoogieVariable>() { arg }, new List <BoogieVariable>() { outVar }, new List <BoogieAttribute>() { smtDefinedAttr })); }
public static BoogieExpr GetCallExprForInit(BoogieType curType, BoogieExpr initExpr) { if (!(curType is BoogieMapType)) { return(initExpr); } string fnName = "init"; while (curType is BoogieMapType map) { fnName = $"{fnName}{String.Join("", map.Arguments)}"; curType = map.Result; } fnName = $"{fnName}{curType}Arr"; return(new BoogieFuncCallExpr(fnName, new List <BoogieExpr>() { initExpr })); }
private void GenerateSingleMemoryVariable(VariableDeclaration decl, BoogieType keyType, BoogieType valType, HashSet <String> generatedMaps) { BoogieMapType map = new BoogieMapType(keyType, valType); map = new BoogieMapType(BoogieType.Ref, map); string name = mapHelper.GetMemoryMapName(decl, keyType, valType); if (!generatedMaps.Contains(name)) { BoogieFunction initFn = MapArrayHelper.GenerateMultiDimZeroFunction(keyType, valType); if (!context.initFns.Contains(initFn.Name)) { context.initFns.Add(initFn.Name); context.Program.AddDeclaration(initFn); } generatedMaps.Add(name); context.Program.AddDeclaration(new BoogieGlobalVariable(new BoogieTypedIdent(name, map))); } }
private void GenerateMemoryVariablesForArray(VariableDeclaration decl, ArrayTypeName array, HashSet <String> generatedMaps, int lvl) { BoogieType boogieKeyType = BoogieType.Int; BoogieType boogieValType = null; if (array.BaseType is ArrayTypeName subarray) { boogieValType = BoogieType.Ref; GenerateMemoryVariablesForArray(decl, subarray, generatedMaps, lvl + 1); // The last level gets initialized all at once if (context.TranslateFlags.LazyAllocNoMod) { BoogieMapType mapType = new BoogieMapType(BoogieType.Ref, new BoogieMapType(boogieKeyType, BoogieType.Bool)); context.Program.AddDeclaration(new BoogieGlobalVariable(new BoogieTypedIdent(mapHelper.GetNestedAllocName(decl, lvl), mapType))); } } else if (array.BaseType is Mapping mapping) { boogieValType = BoogieType.Ref; GenerateMemoryVariablesForMapping(decl, mapping, generatedMaps, lvl + 1); if (context.TranslateFlags.LazyAllocNoMod) { BoogieMapType mapType = new BoogieMapType(BoogieType.Ref, new BoogieMapType(boogieKeyType, BoogieType.Bool)); context.Program.AddDeclaration(new BoogieGlobalVariable(new BoogieTypedIdent(mapHelper.GetNestedAllocName(decl, lvl), mapType))); } } else { boogieValType = TransUtils.GetBoogieTypeFromSolidityTypeName(array.BaseType); } KeyValuePair <BoogieType, BoogieType> pair = new KeyValuePair <BoogieType, BoogieType>(boogieKeyType, boogieValType); GenerateSingleMemoryVariable(decl, boogieKeyType, boogieValType, generatedMaps); }
public static BoogieFunction GenerateMultiDimZeroFunction(BoogieType keyType, BoogieType valType) { BoogieExpr boogieInit = TransUtils.GetDefaultVal(valType); string smtType = GetSmtType(valType); BoogieType mapType = new BoogieMapType(keyType, valType); string fnName = $"zero{keyType.ToString()}{valType.ToString()}Arr"; string smtInit = boogieInit.ToString().Equals("null") ? "0" : boogieInit.ToString(); smtInit = $"((as const (Array {GetSmtType(keyType)} {smtType})) {smtInit})"; var outVar = new BoogieFormalParam(new BoogieTypedIdent("ret", mapType)); var smtDefinedAttr = new BoogieAttribute("smtdefined", $"\"{smtInit}\""); return(new BoogieFunction(fnName, new List <BoogieVariable>(), new List <BoogieVariable>() { outVar }, new List <BoogieAttribute>() { smtDefinedAttr })); }
public static BoogieType GetMultiDimBoogieType(TypeName varType) { if (!(varType is Mapping || varType is ArrayTypeName)) { return(TransUtils.GetBoogieTypeFromSolidityTypeName(varType)); } BoogieType resultType = null; if (varType is Mapping map) { BoogieType valType = GetMultiDimBoogieType(map.ValueType); BoogieType keyType = GetMultiDimBoogieType(map.KeyType); resultType = new BoogieMapType(keyType, valType); } else if (varType is ArrayTypeName arr) { BoogieType baseType = GetMultiDimBoogieType(arr.BaseType); resultType = new BoogieMapType(BoogieType.Int, baseType); } return(resultType); }
public override bool Visit(ModifierDefinition modifier) { //if (modifier.Parameters.Length() > 0) //{ // throw new System.Exception("modifiers with parameters not implemented"); //} var modifierInParams = TransUtils.GetDefaultInParams(); foreach (var parameter in modifier.Parameters.Parameters) { string name = null; name = TransUtils.GetCanonicalLocalVariableName(parameter, context); BoogieType type = TransUtils.GetBoogieTypeFromSolidityTypeName(parameter.TypeName); modifierInParams.Add(new BoogieFormalParam(new BoogieTypedIdent(name, type))); } Block body = modifier.Body; bool hasPre = false; bool hasPost = false; List <Statement> postlude = new List <Statement>(); // this list does not include locals introduced during translation List <BoogieLocalVariable> localVarsDeclared = new List <BoogieLocalVariable>(); bool translatingPre = true; foreach (Statement statement in body.Statements) { if (statement is VariableDeclarationStatement varDecls) { foreach (VariableDeclaration varDecl in varDecls.Declarations) { string name = TransUtils.GetCanonicalLocalVariableName(varDecl, context); BoogieType type = TransUtils.GetBoogieTypeFromSolidityTypeName(varDecl.TypeName); // Issue a warning for intXX variables in case /useModularArithemtic option is used: if (context.TranslateFlags.UseModularArithmetic && varDecl.TypeDescriptions.IsInt()) { Console.WriteLine($"Warning: signed integer arithmetic is not handled with /useModularArithmetic option"); } var boogieVariable = new BoogieLocalVariable(new BoogieTypedIdent(name, type)); if (translatingPre) { localVarsDeclared.Add(boogieVariable); // don't add locals after placeholder } } // throw new System.Exception("locals within modifiers not supported"); } if (statement is PlaceholderStatement) { translatingPre = false; // only capture those locals declared in the prefix, these are visible to postlude context.AddPreludeLocalsToModifier(modifier.Name, localVarsDeclared); continue; } if (translatingPre) { hasPre = true; } else { hasPost = true; } } var attributes = new List <BoogieAttribute>(); attributes.Add(new BoogieAttribute("inline", 1)); if (hasPre) { List <BoogieVariable> inParams = new List <BoogieVariable>(modifierInParams); List <BoogieVariable> outParams = new List <BoogieVariable>(); outParams.AddRange(localVarsDeclared.Select(x => new BoogieFormalParam(new BoogieTypedIdent("__out_mod_" + x.Name, x.TypedIdent.Type)))); BoogieProcedure preludeProc = new BoogieProcedure(modifier.Name + "_pre", inParams, outParams, attributes); context.AddModiferToPreProc(modifier.Name, preludeProc); BoogieImplementation preludeImpl = new BoogieImplementation(modifier.Name + "_pre", inParams, outParams, new List <BoogieVariable>(), new BoogieStmtList()); context.AddModiferToPreImpl(modifier.Name, preludeImpl); } if (hasPost) { List <BoogieVariable> inParams = new List <BoogieVariable>(modifierInParams); inParams.AddRange(localVarsDeclared); List <BoogieVariable> outParams = new List <BoogieVariable>(); BoogieProcedure postludeProc = new BoogieProcedure(modifier.Name + "_post", inParams, outParams, attributes); context.AddModiferToPostProc(modifier.Name, postludeProc); BoogieImplementation postludeImpl = new BoogieImplementation(modifier.Name + "_post", inParams, outParams, new List <BoogieVariable>(), new BoogieStmtList()); context.AddModiferToPostImpl(modifier.Name, postludeImpl); } return(false); }
public static BoogieType GetBoogieType(ITypeReference type) { return(BoogieType.GetBoogieTypeTranslator().GetBoogieType(type)); }
// if needed we will check if the variable has been referenced public static BoogieType GetBoogieType(IParameterTypeInformation var) { return(BoogieType.GetBoogieTypeTranslator().GetBoogieType(var)); }
// if needed we will check if the variable has been referenced public static BoogieType GetBoogieType(IFieldReference var) { return(BoogieType.GetBoogieTypeTranslator().GetBoogieType(var)); }
public static BoogieType GetBoogieType(Constant var) { return(BoogieType.GetBoogieTypeTranslator().GetBoogieType(var)); }
// if needed we will check if the variable has been referenced public static BoogieType GetBoogieType(IVariable var) { return(BoogieType.GetBoogieTypeTranslator().GetBoogieType(var)); }