コード例 #1
0
        public static List <Declaration> TransformImplementations(
            CivlTypeChecker civlTypeChecker,
            int layerNum,
            AbsyMap absyMap,
            HashSet <Procedure> yieldingProcs,
            Dictionary <CallCmd, Block> refinementBlocks)
        {
            var linearPermissionInstrumentation =
                new LinearPermissionInstrumentation(civlTypeChecker, layerNum, absyMap);
            var yieldingProcInstrumentation = new YieldingProcInstrumentation(
                civlTypeChecker,
                linearPermissionInstrumentation,
                layerNum,
                absyMap,
                refinementBlocks);

            yieldingProcInstrumentation.AddNoninterferenceCheckers();
            var implToPreconditions = yieldingProcInstrumentation.CreatePreconditions(linearPermissionInstrumentation);

            yieldingProcInstrumentation
            .InlineYieldRequiresAndEnsures(); // inline after creating the preconditions but before transforming the implementations
            yieldingProcInstrumentation.TransformImpls(yieldingProcs, implToPreconditions);

            List <Declaration> decls = new List <Declaration>();

            decls.AddRange(yieldingProcInstrumentation.noninterferenceCheckerDecls);
            decls.AddRange(yieldingProcInstrumentation.parallelCallAggregators.Values);
            decls.AddRange(yieldingProcInstrumentation.PendingAsyncNoninterferenceCheckers());
            decls.Add(yieldingProcInstrumentation.wrapperNoninterferenceCheckerProc);
            decls.Add(yieldingProcInstrumentation.WrapperNoninterferenceCheckerImpl());
            return(decls);
        }
コード例 #2
0
        private Dictionary <CallCmd, Block> refinementBlocks;     // rewritten -> block

        public YieldingProcDuplicator(CivlTypeChecker civlTypeChecker, int layerNum)
        {
            this.civlTypeChecker = civlTypeChecker;
            this.layerNum        = layerNum;
            this.procToDuplicate = new Dictionary <Procedure, Procedure>();
            this.absyMap         = new AbsyMap();
            this.yieldingProcs   = new HashSet <Procedure>();
            this.asyncCallPreconditionCheckers = new Dictionary <string, Procedure>();
            this.refinementBlocks = new Dictionary <CallCmd, Block>();
        }
コード例 #3
0
 public LinearPermissionInstrumentation(
     CivlTypeChecker civlTypeChecker,
     int layerNum,
     AbsyMap absyMap)
 {
     this.civlTypeChecker     = civlTypeChecker;
     this.layerNum            = layerNum;
     this.absyMap             = absyMap;
     this.domainNameToHoleVar = new Dictionary <string, Variable>();
     this.localVarMap         = new Dictionary <Variable, Variable>();
 }
コード例 #4
0
        private YieldingProcInstrumentation(
            CivlTypeChecker civlTypeChecker,
            LinearPermissionInstrumentation linearPermissionInstrumentation,
            int layerNum,
            AbsyMap absyMap,
            Dictionary <CallCmd, Block> refinementBlocks)
        {
            this.civlTypeChecker = civlTypeChecker;
            this.layerNum        = layerNum;
            this.absyMap         = absyMap;
            this.linearPermissionInstrumentation = linearPermissionInstrumentation;
            this.refinementBlocks       = refinementBlocks;
            parallelCallAggregators     = new Dictionary <string, Procedure>();
            noninterferenceCheckerDecls = new List <Declaration>();

            var             linearTypeChecker = civlTypeChecker.linearTypeChecker;
            List <Variable> inputs            = new List <Variable>();

            foreach (string domainName in linearTypeChecker.linearDomains.Keys)
            {
                inputs.Add(linearTypeChecker.LinearDomainInFormal(domainName));
            }

            foreach (Variable g in civlTypeChecker.GlobalVariables)
            {
                inputs.Add(OldGlobalFormal(g));
            }

            wrapperNoninterferenceCheckerProc = new Procedure(Token.NoToken,
                                                              civlTypeChecker.AddNamePrefix($"Wrapper_NoninterferenceChecker_{layerNum}"), new List <TypeVariable>(),
                                                              inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());
            CivlUtil.AddInlineAttribute(wrapperNoninterferenceCheckerProc);

            // initialize globalSnapshotInstrumentation
            globalSnapshotInstrumentation = new GlobalSnapshotInstrumentation(civlTypeChecker);

            // initialize noninterferenceInstrumentation
            if (CommandLineOptions.Clo.TrustNoninterference)
            {
                noninterferenceInstrumentation = new NoneNoninterferenceInstrumentation();
            }
            else
            {
                noninterferenceInstrumentation = new SomeNoninterferenceInstrumentation(
                    civlTypeChecker,
                    linearTypeChecker,
                    linearPermissionInstrumentation,
                    globalSnapshotInstrumentation.OldGlobalMap,
                    wrapperNoninterferenceCheckerProc);
            }
        }
コード例 #5
0
        private static Dictionary <Absy, List <PredicateCmd> > CollectYields(CivlTypeChecker civlTypeChecker,
                                                                             AbsyMap absyMap, int layerNum, Implementation impl)
        {
            var allYieldPredicates = new Dictionary <Absy, List <PredicateCmd> >();
            List <PredicateCmd> yieldPredicates = new List <PredicateCmd>();

            foreach (Block b in impl.Blocks)
            {
                Absy absy          = null;
                var  originalBlock = absyMap.Original(b);
                if (civlTypeChecker.yieldingLoops.ContainsKey(originalBlock) &&
                    civlTypeChecker.yieldingLoops[originalBlock].layers.Contains(layerNum))
                {
                    absy = b;
                }

                foreach (Cmd cmd in b.Cmds)
                {
                    if (absy != null)
                    {
                        if (cmd is PredicateCmd)
                        {
                            yieldPredicates.Add(cmd as PredicateCmd);
                        }
                        else
                        {
                            allYieldPredicates[absy] = yieldPredicates;
                            yieldPredicates          = new List <PredicateCmd>();
                            absy = null;
                        }
                    }

                    if (cmd is YieldCmd ycmd)
                    {
                        absy = ycmd;
                    }
                }

                if (absy != null)
                {
                    allYieldPredicates[absy] = yieldPredicates;
                    yieldPredicates          = new List <PredicateCmd>();
                }
            }

            return(allYieldPredicates);
        }
コード例 #6
0
        public static List <Declaration> CreateNoninterferenceCheckers(
            CivlTypeChecker civlTypeChecker,
            int layerNum,
            AbsyMap absyMap,
            DeclWithFormals decl,
            List <Variable> declLocalVariables)
        {
            var linearTypeChecker = civlTypeChecker.linearTypeChecker;
            Dictionary <string, Variable>   domainNameToHoleVar = new Dictionary <string, Variable>();
            Dictionary <Variable, Variable> localVarMap         = new Dictionary <Variable, Variable>();
            Dictionary <Variable, Expr>     map = new Dictionary <Variable, Expr>();
            List <Variable> locals = new List <Variable>();
            List <Variable> inputs = new List <Variable>();

            foreach (var domainName in linearTypeChecker.linearDomains.Keys)
            {
                var inParam = linearTypeChecker.LinearDomainInFormal(domainName);
                inputs.Add(inParam);
                domainNameToHoleVar[domainName] = inParam;
            }

            foreach (Variable local in declLocalVariables.Union(decl.InParams).Union(decl.OutParams))
            {
                var copy = CopyLocal(local);
                locals.Add(copy);
                localVarMap[local] = copy;
                map[local]         = Expr.Ident(copy);
            }

            Dictionary <Variable, Expr> oldLocalMap = new Dictionary <Variable, Expr>();
            Dictionary <Variable, Expr> assumeMap   = new Dictionary <Variable, Expr>(map);

            foreach (Variable g in civlTypeChecker.GlobalVariables)
            {
                var copy = OldGlobalLocal(civlTypeChecker, g);
                locals.Add(copy);
                oldLocalMap[g] = Expr.Ident(copy);
                Formal f = SnapshotGlobalFormal(civlTypeChecker, g);
                inputs.Add(f);
                assumeMap[g] = Expr.Ident(f);
            }

            var linearPermissionInstrumentation = new LinearPermissionInstrumentation(civlTypeChecker,
                                                                                      layerNum, absyMap, domainNameToHoleVar, localVarMap);
            List <YieldInfo> yieldInfos = null;
            string           noninterferenceCheckerName = null;

            if (decl is Implementation impl)
            {
                noninterferenceCheckerName = $"impl_{absyMap.Original(impl).Name}_{layerNum}";
                yieldInfos = CollectYields(civlTypeChecker, absyMap, layerNum, impl).Select(kv =>
                                                                                            new YieldInfo(linearPermissionInstrumentation.DisjointnessAssumeCmds(kv.Key, false), kv.Value)).ToList();
            }
            else if (decl is Procedure proc)
            {
                yieldInfos = new List <YieldInfo>();
                if (civlTypeChecker.procToYieldInvariant.ContainsKey(proc))
                {
                    noninterferenceCheckerName = $"yield_{proc.Name}";
                    if (proc.Requires.Count > 0)
                    {
                        var disjointnessCmds = linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, true);
                        var yieldPredicates  = proc.Requires.Select(requires =>
                                                                    requires.Free
                ? (PredicateCmd) new AssumeCmd(requires.tok, requires.Condition)
                : (PredicateCmd) new AssertCmd(requires.tok, requires.Condition)).ToList();
                        yieldInfos.Add(new YieldInfo(disjointnessCmds, yieldPredicates));
                    }
                }
                else
                {
                    noninterferenceCheckerName = $"proc_{absyMap.Original(proc).Name}_{layerNum}";
                    if (proc.Requires.Count > 0)
                    {
                        var entryDisjointnessCmds =
                            linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, true);
                        var entryYieldPredicates = proc.Requires.Select(requires =>
                                                                        requires.Free
                ? (PredicateCmd) new AssumeCmd(requires.tok, requires.Condition)
                : (PredicateCmd) new AssertCmd(requires.tok, requires.Condition)).ToList();
                        yieldInfos.Add(new YieldInfo(entryDisjointnessCmds, entryYieldPredicates));
                    }

                    if (proc.Ensures.Count > 0)
                    {
                        var exitDisjointnessCmds =
                            linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, false);
                        var exitYieldPredicates = proc.Ensures.Select(ensures =>
                                                                      ensures.Free
                ? (PredicateCmd) new AssumeCmd(ensures.tok, ensures.Condition)
                : (PredicateCmd) new AssertCmd(ensures.tok, ensures.Condition)).ToList();
                        yieldInfos.Add(new YieldInfo(exitDisjointnessCmds, exitYieldPredicates));
                    }
                }
            }
            else
            {
                Debug.Assert(false);
            }

            var filteredYieldInfos = yieldInfos.Where(info =>
                                                      info.invariantCmds.Any(predCmd => new GlobalAccessChecker().AccessesGlobal(predCmd.Expr)));

            if (filteredYieldInfos.Count() == 0)
            {
                return(new List <Declaration>());
            }

            Substitution assumeSubst = Substituter.SubstitutionFromDictionary(assumeMap);
            Substitution oldSubst    = Substituter.SubstitutionFromDictionary(oldLocalMap);
            Substitution subst       = Substituter.SubstitutionFromDictionary(map);
            List <Block> noninterferenceCheckerBlocks = new List <Block>();
            List <Block> labelTargets = new List <Block>();
            Block        noninterferenceCheckerBlock = BlockHelper.Block("exit", new List <Cmd>());

            labelTargets.Add(noninterferenceCheckerBlock);
            noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock);
            int yieldCount = 0;

            foreach (var kv in filteredYieldInfos)
            {
                var newCmds = new List <Cmd>(kv.disjointnessCmds);
                foreach (var predCmd in kv.invariantCmds)
                {
                    var newExpr = Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr);
                    newCmds.Add(new AssumeCmd(predCmd.tok, newExpr));
                }

                foreach (var predCmd in kv.invariantCmds)
                {
                    if (predCmd is AssertCmd)
                    {
                        var       newExpr   = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr);
                        AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes);
                        assertCmd.ErrorData = "Non-interference check failed";
                        newCmds.Add(assertCmd);
                    }
                }

                newCmds.Add(CmdHelper.AssumeCmd(Expr.False));
                noninterferenceCheckerBlock = BlockHelper.Block("L" + yieldCount++, newCmds);
                labelTargets.Add(noninterferenceCheckerBlock);
                noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock);
            }

            noninterferenceCheckerBlocks.Insert(0, BlockHelper.Block("enter", new List <Cmd>(), labelTargets));

            // Create the yield checker procedure
            noninterferenceCheckerName = civlTypeChecker.AddNamePrefix($"NoninterferenceChecker_{noninterferenceCheckerName}");
            var noninterferenceCheckerProc = DeclHelper.Procedure(noninterferenceCheckerName,
                                                                  inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            CivlUtil.AddInlineAttribute(noninterferenceCheckerProc);

            // Create the yield checker implementation
            var noninterferenceCheckerImpl = DeclHelper.Implementation(noninterferenceCheckerProc,
                                                                       inputs, new List <Variable>(), locals, noninterferenceCheckerBlocks);

            CivlUtil.AddInlineAttribute(noninterferenceCheckerImpl);
            return(new List <Declaration> {
                noninterferenceCheckerProc, noninterferenceCheckerImpl
            });
        }