Пример #1
0
        private IEnumerable <Instruction> Sources(Instruction instruction, CFG cdfg)
        {
            switch (instruction.Operation.OperationCode)
            {
            case OperationCode.Newobj:
                var constructorReference = instruction.Operation.Value as IMethodReference;
                var type = constructorReference.ContainingType;
                if (constructorReference != null && !type.IsCompilerGenerated() && IsDisposableType(type))
                {
                    yield return(instruction);    // produces the source object
                }
                break;

            case OperationCode.Call:
            case OperationCode.Callvirt:
                var methodRef = instruction.Operation.Value as IMethodReference;
                if (methodRef != null)
                {
                    if (methodRef != null && !methodRef.IsGetter())
                    {
                        if (!methodRef.Type.IsCompilerGenerated() && IsDisposableType(methodRef.Type))
                        {
                            yield return(instruction);    // produces the source object
                        }

                        var args = instruction.Operand2 as Instruction[];
                        if (args != null)
                        {
                            foreach (var p in methodRef.Parameters)
                            {
                                if (p.IsByReference && !p.Type.IsCompilerGenerated() && IsDisposableType(p.Type) && p.Index < args.Length)
                                {
                                    var arg = args[p.Index];
                                    if (arg != null)
                                    {
                                        var loc       = cdfg.LocalOrParameter(arg);
                                        var pseudoDef = instruction[loc];
                                        if (pseudoDef != null)
                                        {
                                            yield return(pseudoDef);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                break;
            }
        }
Пример #2
0
        private IEnumerable <Instruction> Sinks(BasicBlock <Instruction> block, Instruction instruction, CFG cdfg)
        {
            switch (instruction.Operation.OperationCode)
            {
            case OperationCode.Call:
            case OperationCode.Callvirt:
            {
                var methodRef = instruction.Operation.Value as IMethodReference;
                if (methodRef != null)
                {
                    if (IsDisposeMethod(methodRef))
                    {
                        var constraint = block.CallConstraint(instruction);
                        if (methodRef.ContainingType.IsValueType || constraint != null && (constraint.IsValueType || constraint is IGenericParameter))
                        {
                            // passing the address, figure out what local
                            var loc       = cdfg.LocalOrParameter(instruction.Operand1);
                            var toDispose = instruction[loc];
                            yield return(toDispose);
                        }
                        else
                        {
                            yield return(instruction.Operand1);        // consumes the "this" parameter
                        }
                    }

                    var args = instruction.Operand2 as Instruction[];
                    if (args != null)
                    {
                        foreach (var p in methodRef.Parameters)
                        {
                            if (p.IsByReference && IsDisposableType(p.Type) && p.Index < args.Length || PassingObligationTo(methodRef, p))
                            {
                                var arg = args[p.Index];
                                if (arg != null)
                                {
                                    yield return(arg);
                                }
                            }
                        }
                    }
                }
                break;
            }

            case OperationCode.Stfld:
                // consider fields escaping
                yield return(instruction.Operand2 as Instruction);

                break;

            case OperationCode.Stsfld:
                // consider fields escaping
                yield return(instruction.Operand1);

                break;

            case OperationCode.Ret:
                if (instruction.Operand1 != null && IsDisposableType(this.currentMethod.Type))
                {
                    yield return(instruction.Operand1);    // consumes the returned value
                }
                // by ref parameters are also sinks
                foreach (var p in this.currentMethod.Parameters)
                {
                    Instruction finalParameterValue;
                    if ((p.IsByReference || p.IsOut) && IsDisposableType(p.Type) && instruction.PostParamDefs != null && instruction.PostParamDefs.TryGetValue(p, out finalParameterValue))
                    {
                        yield return(finalParameterValue);
                    }
                }
                break;
            }
        }