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 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); }
private void GenerateGlobalProcedureAllocMany() { if (context.TranslateFlags.LazyNestedAlloc) { return; } // generate the internal one without base constructors string procName = "HavocAllocMany"; List <BoogieVariable> inParams = new List <BoogieVariable>(); List <BoogieVariable> outParams = new List <BoogieVariable>(); List <BoogieAttribute> attributes = new List <BoogieAttribute>(); if (context.TranslateFlags.GenerateInlineAttributes) { attributes.Add(new BoogieAttribute("inline", 1)); } ; BoogieProcedure procedure = new BoogieProcedure(procName, inParams, outParams, attributes); context.Program.AddDeclaration(procedure); var oldAlloc = new BoogieLocalVariable(new BoogieTypedIdent("oldAlloc", new BoogieMapType(BoogieType.Ref, BoogieType.Bool))); List <BoogieVariable> localVars = new List <BoogieVariable>() { oldAlloc }; BoogieStmtList procBody = new BoogieStmtList(); BoogieIdentifierExpr oldAllocIdentExpr = new BoogieIdentifierExpr("oldAlloc"); BoogieIdentifierExpr allocIdentExpr = new BoogieIdentifierExpr("Alloc"); // oldAlloc = Alloc procBody.AddStatement(new BoogieAssignCmd(oldAllocIdentExpr, allocIdentExpr)); // havoc Alloc procBody.AddStatement(new BoogieHavocCmd(allocIdentExpr)); // assume forall i:ref oldAlloc[i] ==> alloc[i] var qVar = QVarGenerator.NewQVar(0, 0); BoogieMapSelect allocMapSelect = new BoogieMapSelect(allocIdentExpr, qVar); BoogieMapSelect oldAllocMapSelect = new BoogieMapSelect(oldAllocIdentExpr, qVar); BoogieExpr allocAssumeExpr = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.IMP, oldAllocMapSelect, allocMapSelect); procBody.AddStatement(new BoogieAssumeCmd(new BoogieQuantifiedExpr(true, new List <BoogieIdentifierExpr>() { qVar }, new List <BoogieType>() { BoogieType.Ref }, allocAssumeExpr))); BoogieImplementation implementation = new BoogieImplementation(procName, inParams, outParams, localVars, procBody); context.Program.AddDeclaration(implementation); }
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 List <BoogieVariable> CollectLocalVars(List <ContractDefinition> contracts, TranslatorContext context) { Debug.Assert(contracts.Count > 0, "Internal exception: expecting at least one contract here"); 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" }; foreach (var contract in contracts) { if (contract.ContractKind != EnumContractKind.CONTRACT) { continue; } // 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); }