Ejemplo n.º 1
0
        private YieldingProcInstrumentation(
            CivlTypeChecker civlTypeChecker,
            LinearTypeChecker linearTypeChecker,
            int layerNum,
            Dictionary <Absy, Absy> absyMap,
            Dictionary <Implementation, Implementation> implMap,
            HashSet <Procedure> yieldingProcs)
        {
            this.civlTypeChecker            = civlTypeChecker;
            this.linearTypeChecker          = linearTypeChecker;
            this.layerNum                   = layerNum;
            this.absyMap                    = absyMap;
            this.implMap                    = implMap;
            this.yieldingProcs              = yieldingProcs;
            asyncAndParallelCallDesugarings = new Dictionary <string, Procedure>();
            yieldCheckerDecls               = new List <Declaration>();

            List <Variable> inputs = new List <Variable>();

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

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

            yieldProc = new Procedure(Token.NoToken, $"og_yield_{layerNum}", new List <TypeVariable>(),
                                      inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());
            CivlUtil.AddInlineAttribute(yieldProc);
        }
Ejemplo n.º 2
0
        private YieldingProcInstrumentation(
            CivlTypeChecker civlTypeChecker,
            LinearTypeChecker linearTypeChecker,
            LinearPermissionInstrumentation linearPermissionInstrumentation,
            int layerNum,
            Dictionary <Absy, Absy> absyMap,
            Dictionary <CallCmd, Block> refinementBlocks)
        {
            this.civlTypeChecker   = civlTypeChecker;
            this.linearTypeChecker = linearTypeChecker;
            this.layerNum          = layerNum;
            this.absyMap           = absyMap;
            this.linearPermissionInstrumentation = linearPermissionInstrumentation;
            this.refinementBlocks       = refinementBlocks;
            parallelCallAggregators     = new Dictionary <string, Procedure>();
            noninterferenceCheckerDecls = new List <Declaration>();

            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,
                                                              $"Wrapper_NoninterferenceChecker_{layerNum}", new List <TypeVariable>(),
                                                              inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());
            CivlUtil.AddInlineAttribute(wrapperNoninterferenceCheckerProc);
        }
Ejemplo n.º 3
0
        private Implementation WrapperNoninterferenceCheckerImpl()
        {
            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));
            }

            List <Block> blocks      = new List <Block>();
            TransferCmd  transferCmd = new ReturnCmd(Token.NoToken);

            if (noninterferenceCheckerDecls.Count > 0)
            {
                List <Block>  blockTargets = new List <Block>();
                List <String> labelTargets = new List <String>();
                int           labelCount   = 0;
                foreach (Procedure proc in noninterferenceCheckerDecls.OfType <Procedure>())
                {
                    List <Expr> exprSeq = new List <Expr>();
                    foreach (Variable v in inputs)
                    {
                        exprSeq.Add(Expr.Ident(v));
                    }

                    CallCmd callCmd = new CallCmd(Token.NoToken, proc.Name, exprSeq, new List <IdentifierExpr>());
                    callCmd.Proc = proc;
                    string label = $"L_{labelCount++}";
                    Block  block = new Block(Token.NoToken, label, new List <Cmd> {
                        callCmd
                    },
                                             new ReturnCmd(Token.NoToken));
                    labelTargets.Add(label);
                    blockTargets.Add(block);
                    blocks.Add(block);
                }

                transferCmd = new GotoCmd(Token.NoToken, labelTargets, blockTargets);
            }

            blocks.Insert(0, new Block(Token.NoToken, "enter", new List <Cmd>(), transferCmd));

            var yieldImpl = new Implementation(Token.NoToken, wrapperNoninterferenceCheckerProc.Name,
                                               new List <TypeVariable>(), inputs,
                                               new List <Variable>(), new List <Variable>(), blocks);

            yieldImpl.Proc = wrapperNoninterferenceCheckerProc;
            CivlUtil.AddInlineAttribute(yieldImpl);
            return(yieldImpl);
        }
Ejemplo n.º 4
0
        public List <Declaration> CreateYieldCheckerProcImpl(
            Implementation impl,
            IEnumerable <List <PredicateCmd> > yields)
        {
            Dictionary <Variable, Expr> map    = new Dictionary <Variable, Expr>();
            List <Variable>             locals = new List <Variable>();
            List <Variable>             inputs = new List <Variable>();

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

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

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

            foreach (Variable g in civlTypeChecker.sharedVariables)
            {
                var copy = OldLocalLocal(g);
                locals.Add(copy);
                oldLocalMap[g] = Expr.Ident(copy);
                Formal f = OldGlobalFormal(g);
                inputs.Add(f);
                assumeMap[g] = Expr.Ident(f);
            }

            Substitution  assumeSubst        = Substituter.SubstitutionFromHashtable(assumeMap);
            Substitution  oldSubst           = Substituter.SubstitutionFromHashtable(oldLocalMap);
            Substitution  subst              = Substituter.SubstitutionFromHashtable(map);
            List <Block>  yieldCheckerBlocks = new List <Block>();
            List <String> labels             = new List <String>();
            List <Block>  labelTargets       = new List <Block>();
            Block         yieldCheckerBlock  = new Block(Token.NoToken, "exit", new List <Cmd>(), new ReturnCmd(Token.NoToken));

            labels.Add(yieldCheckerBlock.Label);
            labelTargets.Add(yieldCheckerBlock);
            yieldCheckerBlocks.Add(yieldCheckerBlock);
            int yieldCount = 0;

            foreach (var cs in yields)
            {
                List <Cmd> newCmds = new List <Cmd>();
                foreach (var predCmd in cs)
                {
                    var newExpr = Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr);
                    newCmds.Add(new AssumeCmd(Token.NoToken, newExpr));
                }

                foreach (var predCmd in cs)
                {
                    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);
                    }

                    /*
                     * Disjointness assumes injected by LinearTypeChecker are dropped now because the
                     * previous loop has already substituted the old global state in these assumes.
                     * It would be unsound to have these assumes on the current global state.
                     */
                }

                newCmds.Add(new AssumeCmd(Token.NoToken, Expr.False));
                yieldCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken));
                labels.Add(yieldCheckerBlock.Label);
                labelTargets.Add(yieldCheckerBlock);
                yieldCheckerBlocks.Add(yieldCheckerBlock);
            }

            yieldCheckerBlocks.Insert(0,
                                      new Block(Token.NoToken, "enter", new List <Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets)));

            // Create the yield checker procedure
            var yieldCheckerName = $"Impl_YieldChecker_{impl.Name}";
            var yieldCheckerProc = new Procedure(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs,
                                                 new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            CivlUtil.AddInlineAttribute(yieldCheckerProc);

            // Create the yield checker implementation
            var yieldCheckerImpl = new Implementation(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs,
                                                      new List <Variable>(), locals, yieldCheckerBlocks);

            yieldCheckerImpl.Proc = yieldCheckerProc;
            CivlUtil.AddInlineAttribute(yieldCheckerImpl);
            return(new List <Declaration> {
                yieldCheckerProc, yieldCheckerImpl
            });
        }
Ejemplo n.º 5
0
        public static List <Declaration> CreateNoninterferenceCheckers(
            CivlTypeChecker civlTypeChecker,
            LinearTypeChecker linearTypeChecker,
            int layerNum,
            Dictionary <Absy, Absy> absyMap,
            DeclWithFormals decl,
            List <Variable> declLocalVariables)
        {
            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 = OldLocalLocal(g);
                locals.Add(copy);
                oldLocalMap[g] = Expr.Ident(copy);
                Formal f = OldGlobalFormal(g);
                inputs.Add(f);
                assumeMap[g] = Expr.Ident(f);
            }

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

            if (decl is Implementation impl)
            {
                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))
                {
                    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
                {
                    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.SubstitutionFromHashtable(assumeMap);
            Substitution  oldSubst    = Substituter.SubstitutionFromHashtable(oldLocalMap);
            Substitution  subst       = Substituter.SubstitutionFromHashtable(map);
            List <Block>  noninterferenceCheckerBlocks = new List <Block>();
            List <String> labels       = new List <String>();
            List <Block>  labelTargets = new List <Block>();
            Block         noninterferenceCheckerBlock =
                new Block(Token.NoToken, "exit", new List <Cmd>(), new ReturnCmd(Token.NoToken));

            labels.Add(noninterferenceCheckerBlock.Label);
            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(Token.NoToken, 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(new AssumeCmd(Token.NoToken, Expr.False));
                noninterferenceCheckerBlock =
                    new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken));
                labels.Add(noninterferenceCheckerBlock.Label);
                labelTargets.Add(noninterferenceCheckerBlock);
                noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock);
            }

            noninterferenceCheckerBlocks.Insert(0,
                                                new Block(Token.NoToken, "enter", new List <Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets)));

            // Create the yield checker procedure
            var noninterferenceCheckerName = decl is Procedure
        ? $"NoninterferenceChecker_proc_{decl.Name}"
        : $"NoninterferenceChecker_impl_{decl.Name}";
            var noninterferenceCheckerProc = new Procedure(Token.NoToken, noninterferenceCheckerName, decl.TypeParameters,
                                                           inputs,
                                                           new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            CivlUtil.AddInlineAttribute(noninterferenceCheckerProc);

            // Create the yield checker implementation
            var noninterferenceCheckerImpl = new Implementation(Token.NoToken, noninterferenceCheckerName,
                                                                decl.TypeParameters, inputs,
                                                                new List <Variable>(), locals, noninterferenceCheckerBlocks);

            noninterferenceCheckerImpl.Proc = noninterferenceCheckerProc;
            CivlUtil.AddInlineAttribute(noninterferenceCheckerImpl);
            return(new List <Declaration> {
                noninterferenceCheckerProc, noninterferenceCheckerImpl
            });
        }
Ejemplo n.º 6
0
        public static List <Declaration> CreateNoninterferenceCheckers(
            CivlTypeChecker civlTypeChecker,
            LinearTypeChecker linearTypeChecker,
            int layerNum,
            Dictionary <Absy, Absy> absyMap,
            Implementation impl,
            Dictionary <YieldCmd, List <PredicateCmd> > yields)
        {
            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 impl.LocVars.Union(impl.InParams).Union(impl.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 = OldLocalLocal(g);
                locals.Add(copy);
                oldLocalMap[g] = Expr.Ident(copy);
                Formal f = OldGlobalFormal(g);
                inputs.Add(f);
                assumeMap[g] = Expr.Ident(f);
            }

            var           linearPermissionInstrumentation = new LinearPermissionInstrumentation(civlTypeChecker, linearTypeChecker, layerNum, absyMap, domainNameToHoleVar, localVarMap);
            Substitution  assumeSubst = Substituter.SubstitutionFromHashtable(assumeMap);
            Substitution  oldSubst    = Substituter.SubstitutionFromHashtable(oldLocalMap);
            Substitution  subst       = Substituter.SubstitutionFromHashtable(map);
            List <Block>  noninterferenceCheckerBlocks = new List <Block>();
            List <String> labels       = new List <String>();
            List <Block>  labelTargets = new List <Block>();
            Block         noninterferenceCheckerBlock = new Block(Token.NoToken, "exit", new List <Cmd>(), new ReturnCmd(Token.NoToken));

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

            foreach (var kv in yields)
            {
                var        yieldCmd        = kv.Key;
                var        yieldPredicates = kv.Value;
                List <Cmd> newCmds         = linearPermissionInstrumentation.DisjointnessAssumeCmds(yieldCmd, false);
                foreach (var predCmd in yieldPredicates)
                {
                    var newExpr = Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr);
                    newCmds.Add(new AssumeCmd(Token.NoToken, newExpr));
                }

                foreach (var predCmd in yieldPredicates)
                {
                    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(new AssumeCmd(Token.NoToken, Expr.False));
                noninterferenceCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken));
                labels.Add(noninterferenceCheckerBlock.Label);
                labelTargets.Add(noninterferenceCheckerBlock);
                noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock);
            }

            noninterferenceCheckerBlocks.Insert(0,
                                                new Block(Token.NoToken, "enter", new List <Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets)));

            // Create the yield checker procedure
            var noninterferenceCheckerName = $"NoninterferenceChecker_{impl.Name}";
            var noninterferenceCheckerProc = new Procedure(Token.NoToken, noninterferenceCheckerName, impl.TypeParameters, inputs,
                                                           new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            CivlUtil.AddInlineAttribute(noninterferenceCheckerProc);

            // Create the yield checker implementation
            var noninterferenceCheckerImpl = new Implementation(Token.NoToken, noninterferenceCheckerName, impl.TypeParameters, inputs,
                                                                new List <Variable>(), locals, noninterferenceCheckerBlocks);

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