private static void InjectCode(Implementation impl, int anyParamsPosition, QKeyValue anyParamsAttributes, int anyParamsPositionOut, QKeyValue anyParamsAttributesOut, Implementation procSig, InsertAtBeginningRule rule, Dictionary <Declaration, Expr> paramSubstitution) { //TODO handle anyParams in the OutParam case var doesAnyParamOccurInRhs = false; if (anyParamsPosition != int.MaxValue) { var anyParam = procSig.InParams[anyParamsPosition]; var oiv = new OccursInVisitor(anyParam); oiv.VisitCmdSeq(rule.ProcedureToMatchToInsertion[procSig]); doesAnyParamOccurInRhs = oiv.Success; } if (doesAnyParamOccurInRhs) { for (int i = anyParamsPosition; i < impl.InParams.Count; i++) { var p = impl.InParams[i]; // If attributes for the ##anyparams in the toMatch are given, we only insert code for those parameters of impl // with matching (subset) attributes // we look both in the implementation's and the procedure declaration's signature if (anyParamsAttributes == null || ExprMatchVisitor.AreAttributesASubset(anyParamsAttributes, impl.Proc.InParams[i].Attributes)) { if (!procSig.InParams[anyParamsPosition].TypedIdent.Type.Equals(p.TypedIdent.Type)) { continue; //skip parameters that don't match type } var id = new IdentifierExpr(Token.NoToken, p.Name, p.TypedIdent.Type, true); var substitution = new Dictionary <Declaration, Expr> { { procSig.InParams[anyParamsPosition], id } }; foreach (var kvp in paramSubstitution) { substitution.Add(kvp.Key, kvp.Value); } var sv = new SubstitionVisitor(substitution); var newCmds = sv.VisitCmdSeq(rule.ProcedureToMatchToInsertion[procSig]); if (impl.Blocks.Count > 0 && !QKeyValue.FindBoolAttribute(procSig.Attributes, ExprMatchVisitor.BoogieKeyWords.ReplaceImplementation)) { impl.Blocks.Insert(0, BoogieAstFactory.MkBlock(newCmds, BoogieAstFactory.MkGotoCmd(impl.Blocks.First().Label))); } else { impl.Blocks = new List <Block>(); impl.Blocks.Add( BoogieAstFactory.MkBlock(newCmds)); } } } } else { var sv = new SubstitionVisitor(paramSubstitution); var newCmds = sv.VisitCmdSeq(rule.ProcedureToMatchToInsertion[procSig]); if (impl.Blocks.Count > 0 && !QKeyValue.FindBoolAttribute(procSig.Attributes, ExprMatchVisitor.BoogieKeyWords.ReplaceImplementation)) { impl.Blocks.Insert(0, BoogieAstFactory.MkBlock(newCmds, BoogieAstFactory.MkGotoCmd(impl.Blocks.First().Label))); } else { impl.Blocks = new List <Block>(); impl.Blocks.Add( BoogieAstFactory.MkBlock(newCmds)); } } }
private List <Cmd> ProcessCmd(Cmd cmd) { foreach (var rule in _rules) { foreach (var toMatch in rule.CmdsToMatch) { if (!(toMatch.GetType() == cmd.GetType())) { continue; } List <Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> > > substitutions = null; var match = false; if (cmd is CallCmd) { match = MatchCallCmd((CallCmd)cmd, rule, (CallCmd)toMatch, out substitutions); } else if (cmd is AssignCmd) { match = MatchAssignCmd((AssignCmd)cmd, (AssignCmd)toMatch, out substitutions); } else if (cmd is AssumeCmd) { match = MatchPredicateCmd((AssumeCmd)cmd, (AssumeCmd)toMatch, out substitutions); } else if (cmd is AssertCmd) { match = MatchPredicateCmd((AssertCmd)cmd, (AssertCmd)toMatch, out substitutions); } else { // no match } if (match) { var ret = new List <Cmd>(); if (substitutions.Count == 0) { var sv = new SubstitionVisitor(new Dictionary <Declaration, Expr>(), new Dictionary <string, IAppliable>(), cmd); ret.AddRange(sv.VisitCmdSeq(rule.InsertionTemplate)); } else { // overfit useafterfree example // only instantiate #this once //foreach (var templateCmd in rule.InsertionTemplate) //{ // if (templateCmd is CallCmd && (templateCmd as CallCmd).Proc.Name.Equals("#this")) // ret.AddRange(new List<Cmd> { cmd }); // else // { // foreach (var subsPair in substitutions) // { // var sv = new SubstitionVisitor(subsPair.Item1, subsPair.Item2, cmd); // //ret.AddRange(sv.VisitCmdSeq(rule.InsertionTemplate)); // ret.AddRange(sv.VisitCmdSeq(new List<Cmd> { templateCmd })); // } // } //} // refactor substitutions var visitCmdIndex = 0; List <Cmd> visitCmds = new List <Cmd>(); while (visitCmdIndex < rule.InsertionTemplate.Count) { var visitCmd = rule.InsertionTemplate[visitCmdIndex]; if (visitCmd is CallCmd && (visitCmd as CallCmd).Proc.Name.Equals("#this")) { foreach (var subsPair in substitutions) { var sv = new SubstitionVisitor(subsPair.Item1, subsPair.Item2, cmd); //ret.AddRange(sv.VisitCmdSeq(rule.InsertionTemplate)); ret.AddRange(sv.VisitCmdSeq(new List <Cmd>(visitCmds))); } ret.AddRange(new List <Cmd> { cmd }); visitCmds.Clear(); } else { visitCmds.Add(visitCmd); } visitCmdIndex++; } foreach (var subsPair in substitutions) { var sv = new SubstitionVisitor(subsPair.Item1, subsPair.Item2, cmd); ret.AddRange(sv.VisitCmdSeq(new List <Cmd>(visitCmds))); } } //the rule yielded a match --> done Stats.count("Times " + PropertyKeyWords.CmdRule + " injected code"); return(ret); } } } return(new List <Cmd>() { cmd }); }
private List <Cmd> ProcessCmd(Cmd cmd) { foreach (var rule in _rules) { foreach (var toMatch in rule.CmdsToMatch) { if (!(toMatch.GetType() == cmd.GetType())) { continue; } List <Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> > > substitutions = null; var match = false; if (cmd is CallCmd) { match = MatchCallCmd((CallCmd)cmd, rule, (CallCmd)toMatch, out substitutions); } else if (cmd is AssignCmd) { match = MatchAssignCmd((AssignCmd)cmd, (AssignCmd)toMatch, out substitutions); } else if (cmd is AssumeCmd) { match = MatchPredicateCmd((AssumeCmd)cmd, (AssumeCmd)toMatch, out substitutions); } else if (cmd is AssertCmd) { match = MatchPredicateCmd((AssertCmd)cmd, (AssertCmd)toMatch, out substitutions); } else { // no match } if (match) { var ret = new List <Cmd>(); if (substitutions.Count == 0) { var sv = new SubstitionVisitor(new Dictionary <Declaration, Expr>(), new Dictionary <string, IAppliable>(), cmd); ret.AddRange(sv.VisitCmdSeq(rule.InsertionTemplate)); } else { foreach (var subsPair in substitutions) { var sv = new SubstitionVisitor(subsPair.Item1, subsPair.Item2, cmd); ret.AddRange(sv.VisitCmdSeq(rule.InsertionTemplate)); } } //the rule yielded a match --> done Stats.count("Times " + PropertyKeyWords.CmdRule + " injected code"); return(ret); } } } return(new List <Cmd>() { cmd }); }