Пример #1
0
        internal static bool AreEquivalent(Instruction source, Instruction target)
        {
            if (source.OpCode.Code != target.OpCode.Code)
                return false;

            if (source.OpCode.Code == Code.Ldstr)
                return true;

            //Check the types in ldarg stuff.  Sometimes this scheme
            //could lead us to false positives.  We need an analysis
            //which depends on the context.
            if (source.IsLoadArgument ()) {
                // case where 'ldarg this' is used (p.GetSequence () would be 0)
                if (!Current.HasParameters && !Target.HasParameters)
                    return true;
                return AreEquivalent (source.GetParameter (Current), target.GetParameter (Target));
            }

            // The same for ldloc / stloc
            if (source.IsLoadLocal () || source.IsStoreLocal ())
                return AreEquivalent (source.GetVariable (Current), target.GetVariable (Target));

            //WARNING: Dirty Evil Hack: this should be in the
            //Pattern class
            if (source.OpCode.Code == Code.Ret && source.Previous != null &&
                (source.Previous.OpCode.StackBehaviourPush == StackBehaviour.Pushi ||
                source.Previous.OpCode.Code == Code.Ldnull ||
                source.Previous.OpCode.StackBehaviourPush == StackBehaviour.Push1))
                return false;

            //if (source.Operand != target.Operand)
            if (source.Operand != null && target.Operand != null) {
                // we're sure that target.Operand is of the same type as source.Operand (same OpCode is used)
                Instruction si = (source.Operand as Instruction);
                if (si != null)
                    return (si.Offset == ((Instruction) target.Operand).Offset);
                IMetadataTokenProvider sm = (source.Operand as IMetadataTokenProvider);
                if (sm != null)
                    return sm.Equals (target.Operand as IMetadataTokenProvider);
                if (source.Operand == target.Operand)
                    return true;
                // last chance: we do call ToString
                if (source.Operand.ToString () != target.Operand.ToString ())
                    return false;
            }

            return true;
        }
		private static bool CheckCeqInstruction (Instruction instruction, MethodDefinition method)
		{
			bool problem = false;
			switch (instruction.OpCode.Code) {
			case Code.Conv_R_Un:
			case Code.Conv_R4:
			case Code.Conv_R8:
				return true;
			case Code.Ldc_R4:
				return !CheckFloatConstants ((float) instruction.Operand);
			case Code.Ldc_R8:
				return !CheckDoubleConstants ((double) instruction.Operand);
			case Code.Ldelem_R4:
			case Code.Ldelem_R8:
				return true;
			case Code.Ldloc_0:
			case Code.Ldloc_1:
			case Code.Ldloc_2:
			case Code.Ldloc_3:
			case Code.Ldloc_S:
			case Code.Ldloc:
			case Code.Ldloca:
			case Code.Ldloca_S:
				return instruction.GetVariable (method).VariableType.IsFloatingPoint ();
			case Code.Ldarg_0:
			case Code.Ldarg_1:
			case Code.Ldarg_2:
			case Code.Ldarg_3:
			case Code.Ldarg:
			case Code.Ldarg_S:
			case Code.Ldarga:
			case Code.Ldarga_S:
				ParameterDefinition parameter = instruction.GetParameter (method);
				// handle 'this'
				if (parameter == null)
					return method.DeclaringType.IsFloatingPoint ();
				return parameter.ParameterType.IsFloatingPoint ();
			case Code.Call:
			case Code.Callvirt:
				MethodReference call = instruction.Operand as MethodReference;
				return call.ReturnType.IsFloatingPoint ();
			case Code.Ldfld:
			case Code.Ldflda:
			case Code.Ldsfld:
			case Code.Ldsflda:
				FieldReference field = instruction.Operand as FieldReference;
				return field.FieldType.IsFloatingPoint ();
			}
			return problem;
		}
		private static Instruction StoreLoadLocal (MethodDefinition method, Instruction ins)
		{
			// check for a STLOC followed by a LDLOC
			if (!ins.IsLoadLocal () || !ins.Previous.IsStoreLocal ())
				return null;
			// make sure it's about the same local variable
			if (ins.GetVariable (method) != ins.Previous.GetVariable (method))
				return null;
			return ins.Previous.Previous;
		}
		private static bool AreMirrorInstructions (Instruction ld, Instruction st, MethodDefinition method)
		{
			return (ld.GetVariable (method).Index == st.GetVariable (method).Index);
		}
		// true == handled
		// false == unhandled
		bool CheckIfStored (Instruction afterLdstr)
		{
			switch (afterLdstr.OpCode.Code) {
			case Code.Stfld: // store into field
			case Code.Stsfld:
				CheckIdentifier ((afterLdstr.Operand as FieldReference).Name);
				break;
			default:
				if (afterLdstr.IsStoreLocal ())
					CheckIdentifier (afterLdstr.GetVariable (method_body.Method).Name);
				else
					return false;
				break;
			}

			return true; // handled
		}
		static string CheckDoubleAssignementOnInstanceFields (MethodDefinition method, Instruction ins, Instruction next)
		{
			// for an instance fiels the pattern is more complex because we must check that we're assigning to the same instance
			// first we go forward: DUP, STLOC, STFLD, LDLOC, STFLD

			Instruction load = next.Next;
			if ((load == null) || !load.IsLoadLocal ())
				return String.Empty;

			// check that this is the same variable
			VariableDefinition vd1 = ins.GetVariable (method);
			VariableDefinition vd2 = load.GetVariable (method);
			if (vd1.Index != vd2.Index)
				return String.Empty;

			Instruction stfld = load.Next;
			if ((stfld == null) || (stfld.OpCode.Code != Code.Stfld))
				return String.Empty;

			// check that we're assigning the same field twice
			FieldReference fd1 = (next.Operand as FieldReference);
			FieldReference fd2 = (stfld.Operand as FieldReference);
			if (fd1.MetadataToken.RID != fd2.MetadataToken.RID)
				return String.Empty;

			// backward: DUP, (possible CONV), LD (value to be duplicated), LD instance, LD instance
			if (stfld.TraceBack (method).GetOperand (method) != next.TraceBack (method).GetOperand (method))
				return String.Empty;

			return String.Format ("Instance field '{0}' on same variable '{1}'.", fd1.Name, vd1.Name);
		}
		static string CheckDoubleAssignement (MethodDefinition method, Instruction ins, Instruction next)
		{
			// for a static field the pattern is
			// DUP, STSFLD, STSFLD
			if (ins.OpCode.Code == Code.Stsfld) {
				if (next.OpCode.Code != Code.Stsfld)
					return String.Empty;

				// check that we're assigning the same field twice
				FieldDefinition fd1 = ins.GetField ();
				FieldDefinition fd2 = next.GetField ();
				if (fd1.MetadataToken.RID != fd2.MetadataToken.RID)
					return String.Empty;

				return String.Format ("Static field '{0}'.", fd1.Name);
			} else if (ins.IsStoreLocal ()) {
				// for a local variable the pattern is
				// DUP, STLOC, STLOC
				VariableDefinition vd2 = next.GetVariable (method);
				// check that we're assigning the same variable twice
				if (vd2 != null) {
					VariableDefinition vd1 = ins.GetVariable (method);
					if (vd1.Index != vd2.Index)
						return String.Empty;

					return String.Format ("Local variable '{0}'.", vd1.Name);
				} else if (next.OpCode.Code == Code.Stfld) {
					// instance fields are a bit more complex...
					return CheckDoubleAssignementOnInstanceFields (method, ins, next);
				}
			}
			return String.Empty;
		}
		void CheckReassignment (MethodDefinition method, Instruction ins)
		{
			VariableDefinition v = ins.GetVariable (method);
			ulong index = (ulong) v.Index;
			if (locals.Get (index)) {
				string msg = String.Format (CultureInfo.InvariantCulture,
					"Local {0}is not disposed before being re-assigned.",
					GetFriendlyNameOrEmpty (v));
				Runner.Report (method, ins, Severity.High, Confidence.Normal, msg);
			} else {
				locals.Set (index);
			}
		}
		void Clear (MethodDefinition method, Instruction ins)
		{
			VariableDefinition v = ins.GetVariable (method);
			if (v != null)
				locals.Clear ((ulong) v.Index);
		}
Пример #10
0
		Instruction FindRelatedSuspectLocal (MethodDefinition method, Instruction ins)
		{
			ins = LocalTraceBack (method, ins);
			if (null == ins)
				return null;

			int index = ins.GetVariable (method).Index;
			foreach (var local in suspectLocals) {
				if (local.GetVariable (method).Index == index)
					return local;
			}
			return null;
		}