void AssumeFalseDirectVarUse(DirectVarUse directVarUse, MemoryContext memoryContext, SnapshotBase flowOutputSet) { memoryContext.AssignFalseEvaluable(directVarUse.VarName, directVarUse); }
/// <summary> /// Makes the assumption for case like <value>a < b</value>. /// </summary> /// <param name="left">The left side of the expression.</param> /// <param name="right">The right side of the expression.</param> /// <param name="equal">if set to <c>true</c> lesser or equals is assumed.</param> /// <param name="memoryContext">The memory context of the code block and it's variables.</param> /// <param name="flowOutputSet">The Output set of a program point.</param> void AssumeLesserThan(LangElement left, LangElement right, bool equal, MemoryContext memoryContext, SnapshotBase flowOutputSet) { if (right is DirectVarUse && !(left is DirectVarUse)) { AssumeGreaterThan(right, left, equal, memoryContext, flowOutputSet); } else if (left is DirectVarUse) { var leftVar = (DirectVarUse)left; //this is probably not necessary{ if (right is StringLiteral) { memoryContext.IntersectionAssign(leftVar.VarName, leftVar, memoryContext.AnyStringValue); } else if (right is DoubleLiteral) { var rigthValue = (DoubleLiteral)right; double bound = (double)rigthValue.Value; if (!equal) { bound -= double.Epsilon; } memoryContext.IntersectionAssign(leftVar.VarName, leftVar, memoryContext.CreateFloatInterval(double.MinValue, bound)); } else if (right is IntLiteral) { var rigthValue = (IntLiteral)right; int bound = (int)rigthValue.Value; if (!equal) { bound--; } memoryContext.IntersectionAssign(leftVar.VarName, leftVar, memoryContext.CreateIntegerInterval(int.MinValue, bound)); } else if (right is LongIntLiteral) { var rigthValue = (LongIntLiteral)right; long bound = (long)rigthValue.Value; if (!equal) { bound--; } memoryContext.IntersectionAssign(leftVar.VarName, leftVar, memoryContext.CreateLongintInterval(long.MinValue, bound)); } //} else { var snapshotEntry = log.ReadSnapshotEntry(right); if (snapshotEntry != null) { //get upper bound of right and intersect with left int? maxInt; long? maxLong; double?maxDouble; ValueHelper.TryGetMaximumValue(snapshotEntry.ReadMemory(flowOutputSet).PossibleValues, out maxInt, out maxLong, out maxDouble); if (maxInt.HasValue) { if (!equal) { maxInt--; } memoryContext.IntersectionAssign(leftVar.VarName, leftVar, memoryContext.CreateIntegerInterval(int.MinValue, maxInt.Value)); } else if (maxLong.HasValue) { if (!equal) { maxLong--; } memoryContext.IntersectionAssign(leftVar.VarName, leftVar, memoryContext.CreateLongintInterval(long.MinValue, maxLong.Value)); } else if (maxDouble.HasValue) { if (!equal) { maxDouble -= double.Epsilon; } memoryContext.IntersectionAssign(leftVar.VarName, leftVar, memoryContext.CreateFloatInterval(double.MinValue, maxDouble.Value)); } } } } }
/// <summary> /// Makes the assumption in case of <c>true</c> as a condition result. /// </summary> /// <param name="langElement">The language element to assume.</param> /// <param name="memoryContext">The memory context of the code block and it's variables.</param> /// <param name="flowOutputSet">The Output set of a program point.</param> void AssumeTrue(LangElement langElement, MemoryContext memoryContext, FlowOutputSet flowOutputSet) { if (langElement is BinaryEx) { BinaryEx binaryExpression = (BinaryEx)langElement; if (binaryExpression.PublicOperation == Operations.Equal) { AssumeEquals(binaryExpression.LeftExpr, binaryExpression.RightExpr, memoryContext, flowOutputSet.Snapshot); } else if (binaryExpression.PublicOperation == Operations.NotEqual) { AssumeNotEquals(binaryExpression.LeftExpr, binaryExpression.RightExpr, memoryContext); } else if (binaryExpression.PublicOperation == Operations.GreaterThan) { AssumeGreaterThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, false, memoryContext, flowOutputSet.Snapshot); } else if (binaryExpression.PublicOperation == Operations.GreaterThanOrEqual) { AssumeGreaterThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, true, memoryContext, flowOutputSet.Snapshot); } else if (binaryExpression.PublicOperation == Operations.LessThan) { AssumeLesserThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, false, memoryContext, flowOutputSet.Snapshot); } else if (binaryExpression.PublicOperation == Operations.LessThanOrEqual) { AssumeLesserThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, true, memoryContext, flowOutputSet.Snapshot); } else if (binaryExpression.PublicOperation == Operations.And || binaryExpression.PublicOperation == Operations.Or || binaryExpression.PublicOperation == Operations.Xor) { ConditionForm conditionForm = ConditionForm.All; if (binaryExpression.PublicOperation == Operations.Or) { conditionForm = ConditionForm.Some; } else if (binaryExpression.PublicOperation == Operations.Xor) { conditionForm = ConditionForm.ExactlyOne; } MemoryContext currentMemoryContext = new MemoryContext(log, flowOutputSet); ConditionParts condition = new Weverca.Analysis.FlowResolver.Deprecated.ConditionParts(conditionForm, flowOutputSet, log, binaryExpression.LeftExpr, binaryExpression.RightExpr); condition.MakeAssumption(currentMemoryContext); memoryContext.UnionMerge(currentMemoryContext); } } else if (langElement is UnaryEx) { UnaryEx unaryExpression = (UnaryEx)langElement; if (unaryExpression.PublicOperation == Operations.LogicNegation) { AssumeFalse(unaryExpression.Expr, memoryContext, flowOutputSet); } } else if (langElement is DirectVarUse) { DirectVarUse directVarUse = (DirectVarUse)langElement; AssumeTrueDirectVarUse(directVarUse, memoryContext, flowOutputSet.Snapshot); } else if (langElement is IssetEx) { IssetEx issetEx = (IssetEx)langElement; AssumeIsset(issetEx, memoryContext, flowOutputSet.Snapshot, true); } }
/// <summary> /// Makes the assumption in case of <c>false</c> as a condition result. /// </summary> /// <param name="langElement">The language element to assume.</param> /// <param name="memoryContext">The memory context of the code block and it's variables.</param> /// <param name="flowOutputSet">The Output set of a program point.</param> void AssumeFalse(LangElement langElement, MemoryContext memoryContext, FlowOutputSet flowOutputSet) { if (langElement is BinaryEx) { BinaryEx binaryExpression = (BinaryEx)langElement; if (binaryExpression.PublicOperation == Operations.Equal) { AssumeNotEquals(binaryExpression.LeftExpr, binaryExpression.RightExpr, memoryContext); } else if (binaryExpression.PublicOperation == Operations.NotEqual) { AssumeEquals(binaryExpression.LeftExpr, binaryExpression.RightExpr, memoryContext, flowOutputSet.Snapshot); } else if (binaryExpression.PublicOperation == Operations.GreaterThan) { AssumeLesserThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, true, memoryContext, flowOutputSet.Snapshot); } else if (binaryExpression.PublicOperation == Operations.GreaterThanOrEqual) { AssumeLesserThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, false, memoryContext, flowOutputSet.Snapshot); } else if (binaryExpression.PublicOperation == Operations.LessThan) { AssumeGreaterThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, true, memoryContext, flowOutputSet.Snapshot); } else if (binaryExpression.PublicOperation == Operations.LessThanOrEqual) { AssumeGreaterThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, false, memoryContext, flowOutputSet.Snapshot); } else if (binaryExpression.PublicOperation == Operations.And || binaryExpression.PublicOperation == Operations.Or || binaryExpression.PublicOperation == Operations.Xor) { ConditionForm conditionForm = ConditionForm.SomeNot; // !(a AND b) --> !a OR !b if (binaryExpression.PublicOperation == Operations.Or) { conditionForm = ConditionForm.None; // !(a OR b) --> !a AND !b } else if (binaryExpression.PublicOperation == Operations.Xor) { conditionForm = ConditionForm.NotExactlyOne; //!(a XOR b) --> !((a OR b) AND !(a AND b)) --> (!a AND !b) OR (a AND b) } MemoryContext currentMemoryContext = new MemoryContext(log, flowOutputSet); ConditionParts condition = new ConditionParts(conditionForm, flowOutputSet, log, binaryExpression.LeftExpr, binaryExpression.RightExpr); condition.MakeAssumption(currentMemoryContext); memoryContext.UnionMerge(currentMemoryContext); } } else if (langElement is UnaryEx) { UnaryEx unaryExpression = (UnaryEx)langElement; if (unaryExpression.PublicOperation == Operations.LogicNegation) { AssumeTrue(unaryExpression.Expr, memoryContext, flowOutputSet); } } else if (langElement is DirectVarUse) { DirectVarUse directVarUse = (DirectVarUse)langElement; AssumeFalseDirectVarUse(directVarUse, memoryContext, flowOutputSet.Snapshot); } else if (langElement is IssetEx) { IssetEx issetEx = (IssetEx)langElement; AssumeIsset(issetEx, memoryContext, flowOutputSet.Snapshot, false); } }
/// <summary> /// Tries to confirm the assumption and setup the environment inside of the assumed block. /// </summary> /// <param name="outputMemoryContext"> /// If set to <c>null</c>, output will be written to flowOutputSet given provided while constracting this instance; /// otherwise output will be written into this parameter. /// </param> /// <returns> /// <c>false</c> is returned if the assumption can be proved to be wrong; otherwise <c>true</c> is returned. /// </returns> public bool MakeAssumption(MemoryContext outputMemoryContext) { bool willAssume; switch (conditionForm) { case ConditionForm.All: willAssume = FalsePartsCount == 0; break; case ConditionForm.None: willAssume = TruePartsCount == 0; break; case ConditionForm.Some: willAssume = TruePartsCount > 0 || UnknownPartsCount > 0; break; case ConditionForm.SomeNot: willAssume = FalsePartsCount > 0 || UnknownPartsCount > 0; break; case ConditionForm.ExactlyOne: willAssume = TruePartsCount == 1 || UnknownPartsCount > 0; break; case ConditionForm.NotExactlyOne: willAssume = TruePartsCount != 1 || UnknownPartsCount > 0; break; default: throw new NotSupportedException(string.Format("Condition form \"{0}\" is not supported", conditionForm)); } if (willAssume) { MemoryContext memoryContext = outputMemoryContext ?? new MemoryContext(log, flowOutputSet); bool intersectionMerge = conditionForm == ConditionForm.All || conditionForm == ConditionForm.None || conditionForm == ConditionForm.ExactlyOne ? true : false; foreach (var conditionPart in conditionParts) { MemoryContext currentMemoryContext = new MemoryContext(log, flowOutputSet); conditionPart.AssumeCondition(conditionForm, currentMemoryContext, flowOutputSet); if (intersectionMerge) { memoryContext.IntersectionMerge(currentMemoryContext); } else { memoryContext.UnionMerge(currentMemoryContext); } } //If this condition is false, then we are in recursion. Made by splitting 1 condition with logic operator into two. if (outputMemoryContext == null) { memoryContext.AssignToSnapshot(flowOutputSet.Snapshot); } } return(willAssume); }