private static Variable ExtractOffsetVar(CallCounterexample err) { var VFV = new VariableFinderVisitor( RaceInstrumentationUtil.MakeOffsetVariableName(QKeyValue.FindStringAttribute(err.FailingRequires.Attributes, "array"), GetAccessType(err))); VFV.Visit(err.FailingRequires.Condition); return(VFV.GetVariable()); }
private IEnumerable <SourceLocationInfo> GetPossibleSourceLocationsForFirstAccessInRace(CallCounterexample CallCex, string ArrayName, AccessType AccessType, string RaceyState) { string AccessHasOccurred = RaceInstrumentationUtil.MakeHasOccurredVariableName(ArrayName, AccessType); string AccessOffset = RaceInstrumentationUtil.MakeOffsetVariableName(ArrayName, AccessType); AssumeCmd ConflictingAction = DetermineConflictingAction(CallCex, RaceyState, AccessHasOccurred, AccessOffset); var ConflictingState = QKeyValue.FindStringAttribute(ConflictingAction.Attributes, "captureState"); if (ConflictingState.Contains("loop_head_state")) { // The state may have been renamed (for example, if k-induction has been employed), // so we need to find the original state name. This can be computed as the substring before the first // occurrence of '$'. This inversion is fragile, and would be a good candidate for making robust string ConflictingStatePrefix; if (ConflictingState.Contains('$')) { ConflictingStatePrefix = ConflictingState.Substring(0, ConflictingState.IndexOf('$')); } else { ConflictingStatePrefix = ConflictingState; } Program originalProgram = GetOriginalProgram(); var blockGraph = originalProgram.ProcessLoops(GetOriginalImplementation(originalProgram)); Block header = FindLoopHeaderWithStateName(ConflictingStatePrefix, blockGraph); Debug.Assert(header != null); HashSet <Block> LoopNodes = new HashSet <Block>( blockGraph.BackEdgeNodes(header).Select(Item => blockGraph.NaturalLoops(header, Item)).SelectMany(Item => Item) ); return(GetSourceLocationsFromBlocks("_CHECK_" + AccessType + "_" + ArrayName, LoopNodes)); } else if (ConflictingState.Contains("call_return_state")) { return(GetSourceLocationsFromCall("_CHECK_" + AccessType + "_" + ArrayName, QKeyValue.FindStringAttribute(ConflictingAction.Attributes, "procedureName"))); } else { Debug.Assert(ConflictingState.Contains("check_state")); return(new HashSet <SourceLocationInfo> { new SourceLocationInfo(ConflictingAction.Attributes, GetSourceFileName(), ConflictingAction.tok) }); } }
private void ShowRaceInstrumentationVariables(Model Model, string CapturedState, Program OriginalProgram) { foreach (var v in OriginalProgram.TopLevelDeclarations.OfType <Variable>().Where(Item => QKeyValue.FindBoolAttribute(Item.Attributes, "race_checking"))) { foreach (var t in AccessType.Types) { if (v.Name.StartsWith("_" + t + "_HAS_OCCURRED_")) { string ArrayName; AccessType Access; GetArrayNameAndAccessTypeFromAccessHasOccurredVariable(v, out ArrayName, out Access); var AccessOffsetVar = OriginalProgram.TopLevelDeclarations.OfType <Variable>().Where(Item => Item.Name == RaceInstrumentationUtil.MakeOffsetVariableName(ArrayName, Access)).ToList()[0]; if (ExtractVariableValueFromCapturedState(v.Name, CapturedState, Model) == "true") { if (GetStateFromModel(CapturedState, Model).TryGet(AccessOffsetVar.Name) is Model.Number) { Console.Error.WriteLine(" " + Access.ToString().ToLower() + " " + Access.Direction() + " " + ArrayOffsetString(Model, CapturedState, v, AccessOffsetVar, ArrayName) + " (" + ThreadDetails(Model, 1, false) + ")"); } else { Console.Error.WriteLine(" " + Access.ToString().ToLower() + " " + Access.Direction() + " " + ArrayName.TrimStart(new char[] { '$' }) + " (unknown offset)" + " (" + ThreadDetails(Model, 1, false) + ")"); } } break; } } } }