private static void AddToCulpritField(IEnumerable <Field> accessedFields, SafeList <Field> culpritFields) { foreach (var acfield in accessedFields) { if (PexMeFilter.IsTypeSupported(acfield.Type)) { culpritFields.Add(acfield); } } }
/// <summary> /// Handles use of the field /// </summary> private void HandleFieldUse(Field field) { //Check if it is a primitive field if (PexMeFilter.IsPrimitiveType(field.Type)) { this.currSEMethodStore.AddToUsedList(field, this.currOffset); } else { //First a field is added a loaded. Later it is decided whether it is modified or not //based on the method call invoked in this field this.lastLoadedFields.Add(field); } }
public override Term VisitSymbol(TVoid parameter, Term term, ISymbolId key) { if (this.TermManager.TryGetInstanceField(term, out this.lastAccessedField)) { //Currently we are handling only these types if (PexMeFilter.IsTypeSupported(this.lastAccessedField.Type)) { this.Fields.Add(this.lastAccessedField); } } if (key is ISymbolIdWithType) { this.variables.Add((ISymbolIdWithType)key); } //return term; return(base.VisitSymbol(parameter, term, key)); }
/// <summary> /// Handles use of the field /// </summary> private void HandleFieldUse(Field field) { FieldDefUseStore llfs; //Check if it is a primitive field if (PexMeFilter.IsPrimitiveType(field.Type)) { UpdateDUCoverTable(field, out llfs); } else { //If the current method is a getter method, then just update the entry var currMethod = this.GetCurrentMethod(); if (currMethod.ShortName.StartsWith("get_")) { this.UpdateDUCoverTable(field, out llfs); } //Handling non-primitive fields are postponed till the branching decision or function call this.lastLoadedFields.Add(field); } }
/// <summary> /// Collects defs and uses within a method /// </summary> /// <param name="td"></param> /// <param name="ade"></param> /// <param name="constructor"></param> private static void CollectDefsAndUsesInMethod(PexMeStaticDatabase psd, TypeDefinition td, DeclClassEntity ade, Method method, SafeSet <Method> visitedMethods, SideEffectStore ses) { try { if (visitedMethods == null) { visitedMethods = new SafeSet <Method>(); } if (visitedMethods.Contains(method)) { return; } visitedMethods.Add(method); MethodBodyEx body; if (!method.TryGetBody(out body) || !body.HasInstructions) { return; } int offset = 0; Instruction instruction; OpCode prevOpcode = OpCodes.Nop; //Stack for load instructions Field lastAccessedArrayField = null; SafeList <Field> lastAccessedFieldList = new SafeList <Field>(); while (body.TryGetInstruction(offset, out instruction)) { SafeDebug.AssumeNotNull(instruction, "instruction"); OpCode opCode = instruction.OpCode; if (MethodOrFieldAnalyzer.LdcOpCodes.Contains(opCode)) { //topIsConstant = true; } else if (MethodOrFieldAnalyzer.ConvOpCodes.Contains(opCode)) { // do not change topIsConstant } else { if (opCode == OpCodes.Stfld) { SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField"); Field field = instruction.Field; DeclFieldEntity dfe; if (ade.FieldEntities.TryGetValue(field.FullName, out dfe)) { //Found a definition of the field. register the definition dfe.AddToDefList(method, offset); } } else if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldflda) { SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField"); Field accessedField = instruction.Field; if (PexMeFilter.IsPrimitiveType(accessedField.Type)) { DeclFieldEntity dfe; if (ade.FieldEntities.TryGetValue(accessedField.FullName, out dfe)) { //Found an accessor. register the usage dfe.AddToUseList(method, offset); } lastAccessedArrayField = null; } else { if (accessedField.Type.Spec == TypeSpec.SzArray) { lastAccessedArrayField = accessedField; } else { //Any access needs to be registered as use lastAccessedFieldList.Add(accessedField); } } } else if (MethodOrFieldAnalyzer.StElemOpCodes.Contains(opCode)) { if (lastAccessedArrayField != null) { DeclFieldEntity dfe; if (ade.FieldEntities.TryGetValue(lastAccessedArrayField.FullName, out dfe)) { //Found a definition of the field. register the definition dfe.AddToDefList(method, offset); } lastAccessedArrayField = null; } } else if (MethodOrFieldAnalyzer.BranchOpCodes.Contains(opCode)) { if (lastAccessedFieldList.Count > 0) { //A field is loaded and used in conditional statement. We use the offset of conditional statement as the usage point foreach (var field in lastAccessedFieldList) { DeclFieldEntity dfe; if (ade.FieldEntities.TryGetValue(field.FullName, out dfe)) { //Found a definition of the field. register the definition dfe.AddToUseList(method, offset); } } lastAccessedFieldList.Clear(); } if (lastAccessedArrayField != null) { DeclFieldEntity dfe; if (ade.FieldEntities.TryGetValue(lastAccessedArrayField.FullName, out dfe)) { //Found a definition of the field. register the definition dfe.AddToUseList(method, offset); } lastAccessedArrayField = null; } } else if (opCode == OpCodes.Ret) { //A field is accessed and is returned from here if (lastAccessedFieldList.Count > 0) { foreach (var field in lastAccessedFieldList) { DeclFieldEntity dfe; if (ade.FieldEntities.TryGetValue(field.FullName, out dfe)) { //Found a use of the field. register the definition dfe.AddToUseList(method, offset); } } lastAccessedFieldList.Clear(); } } else if (opCode == OpCodes.Call || opCode == OpCodes.Callvirt) { SafeDebug.Assume(opCode.OperandType == OperandType.InlineMethod, "opCode.OperandType == OperandType.InlineMethod"); Method methodinner = instruction.Method; SafeDebug.AssumeNotNull(method, "method"); //If this condition is not satisfied, it could be a local method call, which is dealt separately if (lastAccessedFieldList.Count != 0) { HandleMethodCall(psd, ade, method, offset, lastAccessedFieldList, methodinner, ses); lastAccessedFieldList.Clear(); } else { var shortname = methodinner.ShortName; if (shortname.StartsWith("set_")) { HandleSetterMethod(ade, method, offset, methodinner); } else if (shortname.StartsWith("get_")) { HandleGetterMethod(ade, method, offset, methodinner, lastAccessedFieldList); } } } } prevOpcode = opCode; offset = instruction.NextOffset; } } catch (Exception ex) { logger.ErrorException("Exception thrown with static analysis " + ex.StackTrace, ex); } }