in Sources/SolToBoogie/ProcedureTranslator.cs [978:1082]
private void GenerateDefaultConstructor(ContractDefinition contract)
{
// generate the internal one without base constructors
string procName = contract.Name + "_" + contract.Name + "_NoBaseCtor";
currentBoogieProc = procName;
if (!boogieToLocalVarsMap.ContainsKey(currentBoogieProc))
{
boogieToLocalVarsMap[currentBoogieProc] = new List<BoogieVariable>();
}
List<BoogieVariable> inParams = TransUtils.GetDefaultInParams();
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);
BoogieStmtList procBody = GenerateInitializationStmts(contract);
List<BoogieVariable> localVars = boogieToLocalVarsMap[currentBoogieProc];
BoogieImplementation implementation = new BoogieImplementation(procName, inParams, outParams, localVars, procBody);
context.Program.AddDeclaration(implementation);
// generate the actual one with base constructors
string ctorName = contract.Name + "_" + contract.Name;
BoogieProcedure ctorWithBaseCalls = new BoogieProcedure(ctorName, inParams, outParams, attributes);
context.Program.AddDeclaration(ctorWithBaseCalls);
List<BoogieVariable> ctorLocalVars = new List<BoogieVariable>();
BoogieStmtList ctorBody = new BoogieStmtList();
// add the printing for argument
// Print function argument values to corral.txt for counterexample:
PrintArguments(null, inParams, ctorBody);
// print sourcefile, and line of the contract start for
// forcing Corral to print values consistently
if (!context.TranslateFlags.NoSourceLineInfoFlag)
ctorBody.AddStatement(InstrumentSourceFileAndLineInfo(contract));
List<int> baseContractIds = new List<int>(contract.LinearizedBaseContracts);
baseContractIds.Reverse();
foreach (int id in baseContractIds)
{
ContractDefinition baseContract = context.GetASTNodeById(id) as ContractDefinition;
VeriSolAssert(baseContract != null);
string callee = TransUtils.GetCanonicalConstructorName(baseContract);
if (baseContract.Name == contract.Name)
{
// for current contract, call the body that does not have the base calls
// for base contracts, call the wrapper constructor
callee += "_NoBaseCtor";
}
List<BoogieExpr> inputs = new List<BoogieExpr>();
List<BoogieIdentifierExpr> outputs = new List<BoogieIdentifierExpr>();
InheritanceSpecifier inheritanceSpecifier = GetInheritanceSpecifieWithArgsOfBase(contract, baseContract);
if (inheritanceSpecifier != null)
{
inputs.Add(new BoogieIdentifierExpr("this"));
inputs.Add(new BoogieIdentifierExpr("msgsender_MSG"));
inputs.Add(new BoogieIdentifierExpr("msgvalue_MSG"));
foreach (Expression argument in inheritanceSpecifier.Arguments)
{
inputs.Add(TranslateExpr(argument));
}
}
else // no argument for this base constructor
{
if (baseContract.Name == contract.Name)
{
// only do this for the derived contract
foreach (BoogieVariable param in inParams)
{
inputs.Add(new BoogieIdentifierExpr(param.TypedIdent.Name));
}
}
else
{
// Do we call the constructor or assume that it is invoked in teh base contract?
// since it needs argument, we cannot invoke it here (Issue #101)
var baseCtr = context.IsConstructorDefined(baseContract) ? context.GetConstructorByContract(baseContract) : null;
if (baseCtr != null && baseCtr.Parameters.Length() > 0)
{
continue;
} else if (!currentContract.BaseContracts.Any(x => x.BaseName.Name.Equals(baseContract.Name)))
{
Console.WriteLine($"Warning!!: Invoking base constructor { callee} that is not explicitly in inheritance list of {currentContract.Name}...");
}
inputs.Add(new BoogieIdentifierExpr("this"));
inputs.Add(new BoogieIdentifierExpr("msgsender_MSG"));
inputs.Add(new BoogieIdentifierExpr("msgvalue_MSG"));
}
}
BoogieCallCmd callCmd = new BoogieCallCmd(callee, inputs, outputs);
ctorBody.AddStatement(callCmd);
}
BoogieImplementation ctorImpl = new BoogieImplementation(ctorName, inParams, outParams, ctorLocalVars, ctorBody);
context.Program.AddDeclaration(ctorImpl);
}