Example #1
0
        public void Validate()
        {
            if (this.calledFrom == Common.CalledFrom.ExternalOnly || this.calledFrom == Common.CalledFrom.Both)
            {
                if (string.IsNullOrWhiteSpace(globalID))
                {
                    throw new ValidatorException("The function, which can be called from outside the routine, must have a non-empty GlobalID property. Function: " + this.ID);
                }
            }

            if (BasicBlocks.FindAll(x => x.getSuccessors.Count == 0 && x.getPredecessors.Count > 0 && x.Instructions.Count == 1 && x.Instructions[0].TACtext == "return").Count == 0)
            {
                throw new ValidatorException("Function " + ID + " has no 'fake exit block'.");
            }

            if (BasicBlocks.FindAll(x => x.getSuccessors.Count == 0 && x.getPredecessors.Count > 0 && x.Instructions.Count == 1 && x.Instructions[0].TACtext == "return").Count > 1)
            {
                throw new ValidatorException("Function " + ID + " has more than one 'fake exit block'.");
            }

            foreach (BasicBlock bb in this.BasicBlocks)
            {
                if (bb.parent != this)
                {
                    throw new ValidatorException("Basic block's 'parent' property is incorrect. Basic block: " + bb.ID);
                }
                bb.Validate();
            }

            /* Instructions are unique, so they can be referenced only once within a function */
            List <Instruction> all_instructions = new List <Instruction>();

            BasicBlocks.ForEach(x => all_instructions.AddRange(x.Instructions));
            if (all_instructions.Count != all_instructions.Distinct().Count())
            {
                throw new ValidatorException("Multiple references to the same instruction.");
            }
        }