/// <summary> /// Gets whether 'inst' is a possible store for use as a compound store. /// </summary> bool IsCompoundStore(ILInstruction inst, out IType storeType, out ILInstruction value) { value = null; storeType = null; if (inst is StObj stobj) { storeType = stobj.Type; value = stobj.Value; return(SemanticHelper.IsPure(stobj.Target.Flags)); } else if (inst is CallInstruction call && (call.OpCode == OpCode.Call || call.OpCode == OpCode.CallVirt)) { if (call.Method.Parameters.Count == 0) { return(false); } foreach (var arg in call.Arguments.SkipLast(1)) { if (!SemanticHelper.IsPure(arg.Flags)) { return(false); } } storeType = call.Method.Parameters.Last().Type; value = call.Arguments.Last(); return(IsSameMember(call.Method, (call.Method.AccessorOwner as IProperty)?.Setter)); }
/// <summary> /// Lift a C# comparison. /// /// The output instructions should evaluate to <c>false</c> when any of the <c>nullableVars</c> is <c>null</c>. /// Otherwise, the output instruction should evaluate to the same value as the input instruction. /// The output instruction should have the same side-effects (incl. exceptions being thrown) as the input instruction. /// This means unlike LiftNormal(), we cannot rely on the input instruction not being evaluated if /// a variable is <c>null</c>. /// </summary> Comp LiftCSharpComparison(Comp comp, ComparisonKind newComparisonKind) { var(left, leftBits) = DoLift(comp.Left); var(right, rightBits) = DoLift(comp.Right); if (left != null && right == null && SemanticHelper.IsPure(comp.Right.Flags)) { // Embed non-nullable pure expression in lifted expression. right = comp.Right.Clone(); } if (left == null && right != null && SemanticHelper.IsPure(comp.Left.Flags)) { // Embed non-nullable pure expression in lifted expression. left = comp.Left.Clone(); } // due to the restrictions on side effects, we only allow instructions that are pure after lifting. // (we can't check this before lifting due to the calls to GetValueOrDefault()) if (left != null && right != null && SemanticHelper.IsPure(left.Flags) && SemanticHelper.IsPure(right.Flags)) { var bits = leftBits ?? rightBits; if (rightBits != null) { bits.UnionWith(rightBits); } if (!bits.All(0, nullableVars.Count)) { // don't lift if a nullableVar doesn't contribute to the result return(null); } context.Step("NullableLiftingTransform: C# comparison", comp); return(new Comp(newComparisonKind, ComparisonLiftingKind.CSharp, comp.InputType, comp.Sign, left, right)); } return(null); }
public void Run(ILFunction function, ILTransformContext context) { foreach (var container in function.Descendants.OfType <BlockContainer>()) { context.CancellationToken.ThrowIfCancellationRequested(); SplitBlocksAtWritesToPinnedLocals(container); DetectNullSafeArrayToPointer(container); foreach (var block in container.Blocks) { CreatePinnedRegion(block); } container.Blocks.RemoveAll(b => b.Instructions.Count == 0); // remove dummy blocks } // Sometimes there's leftover writes to the original pinned locals foreach (var block in function.Descendants.OfType <Block>()) { context.CancellationToken.ThrowIfCancellationRequested(); for (int i = 0; i < block.Instructions.Count; i++) { var stloc = block.Instructions[i] as StLoc; if (stloc != null && stloc.Variable.Kind == VariableKind.PinnedLocal && stloc.Variable.LoadCount == 0 && stloc.Variable.AddressCount == 0) { if (SemanticHelper.IsPure(stloc.Value.Flags)) { block.Instructions.RemoveAt(i--); } else { stloc.ReplaceWith(stloc.Value); } } } } }
public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node) { var symbol = SemanticHelper.GetSemanticSymbol(node, _semanticModel, _preportSemanticModel); var identifierNameSyntax = (IdentifierNameSyntax)base.VisitIdentifierName(node); if (symbol != null) { var nodeKey = symbol.OriginalDefinition != null?symbol.OriginalDefinition.ToString() : symbol.ToString(); foreach (var action in _allActions.OfType <IdentifierNameAction>()) { if (nodeKey == action.Key && identifierNameTypes.Contains(identifierNameSyntax.Parent?.GetType())) { var actionExecution = new GenericActionExecution(action, _filePath) { TimesRun = 1 }; try { identifierNameSyntax = action.IdentifierNameActionFunc(_syntaxGenerator, identifierNameSyntax); LogHelper.LogInformation(string.Format("{0}: {1}", node.SpanStart, action.Description)); } catch (Exception ex) { var actionExecutionException = new ActionExecutionException(action.Name, action.Key, ex); actionExecution.InvalidExecutions = 1; LogHelper.LogError(actionExecutionException); } allExecutedActions.Add(actionExecution); } } } return(identifierNameSyntax); }
static void RunOnBlock(Block block, ILTransformContext context, HashSet <ILVariable> splitVariables = null) { for (int i = 0; i < block.Instructions.Count; i++) { if (block.Instructions[i].MatchStLoc(out ILVariable v, out ILInstruction copiedExpr)) { if (v.IsSingleDefinition && v.LoadCount == 0 && v.Kind == VariableKind.StackSlot) { // dead store to stack if (SemanticHelper.IsPure(copiedExpr.Flags)) { // no-op -> delete context.Step("remove dead store to stack: no-op -> delete", block.Instructions[i]); block.Instructions.RemoveAt(i); // This can open up new inlining opportunities: int c = ILInlining.InlineInto(block, i, InliningOptions.None, context: context); i -= c + 1; } else { // evaluate the value for its side-effects context.Step("remove dead store to stack: evaluate the value for its side-effects", block.Instructions[i]); copiedExpr.AddILRange(block.Instructions[i]); block.Instructions[i] = copiedExpr; } } else if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr, splitVariables)) { DoPropagate(v, copiedExpr, block, ref i, context); } } } }
/// <summary> /// newobj Delegate..ctor(target, ldvirtftn TargetMethod(target)) /// => /// ldvirtdelegate System.Delegate TargetMethod(target) /// </summary> bool TransformDelegateCtorLdVirtFtnToLdVirtDelegate(NewObj inst, out LdVirtDelegate ldVirtDelegate) { ldVirtDelegate = null; if (inst.Method.DeclaringType.Kind != TypeKind.Delegate) { return(false); } if (inst.Arguments.Count != 2) { return(false); } if (!(inst.Arguments[1] is LdVirtFtn ldVirtFtn)) { return(false); } if (!SemanticHelper.IsPure(inst.Arguments[0].Flags)) { return(false); } if (!inst.Arguments[0].Match(ldVirtFtn.Argument).Success) { return(false); } ldVirtDelegate = new LdVirtDelegate(inst.Arguments[0], inst.Method.DeclaringType, ldVirtFtn.Method) .WithILRange(inst).WithILRange(ldVirtFtn).WithILRange(ldVirtFtn.Argument); return(true); }
void IILTransform.Run(ILFunction function, ILTransformContext context) { var instructionsToFix = new List <IsInst>(); foreach (var isInst in function.Descendants.OfType <IsInst>()) { if (isInst.Type.IsReferenceType == true) { continue; // reference-type isinst is always supported } if (SemanticHelper.IsPure(isInst.Argument.Flags)) { continue; // emulated via "expr is T ? (T)expr : null" } if (isInst.Parent is UnboxAny unboxAny && ExpressionBuilder.IsUnboxAnyWithIsInst(unboxAny, isInst)) { continue; // supported pattern "expr as T?" } if (isInst.Parent.MatchCompEqualsNull(out _) || isInst.Parent.MatchCompNotEqualsNull(out _)) { continue; // supported pattern "expr is T" } if (isInst.Parent is Block { Kind: BlockKind.ControlFlow })
internal static void TransformDynamicSetMemberInstruction(DynamicSetMemberInstruction inst, StatementTransformContext context) { if (!inst.BinderFlags.HasFlag(CSharpBinderFlags.ValueFromCompoundAssignment)) { return; } if (!(inst.Value is DynamicBinaryOperatorInstruction binaryOp)) { return; } if (!(binaryOp.Left is DynamicGetMemberInstruction dynamicGetMember)) { return; } if (!dynamicGetMember.Target.Match(inst.Target).Success) { return; } if (!SemanticHelper.IsPure(dynamicGetMember.Target.Flags)) { return; } if (inst.Name != dynamicGetMember.Name || !DynamicCompoundAssign.IsExpressionTypeSupported(binaryOp.Operation)) { return; } context.Step("dynamic.setmember.compound -> dynamic.compound.op", inst); inst.ReplaceWith(new DynamicCompoundAssign(binaryOp.Operation, binaryOp.BinderFlags, binaryOp.Left, binaryOp.LeftArgumentInfo, binaryOp.Right, binaryOp.RightArgumentInfo)); }
private void RemoveDeadStackStores(Block block, bool aggressive) { // Previously copy propagation did this; // ideally the ILReader would already do this, // for now do this here (even though it's not control-flow related). for (int i = block.Instructions.Count - 1; i >= 0; i--) { if (block.Instructions[i] is StLoc stloc && stloc.Variable.IsSingleDefinition && stloc.Variable.LoadCount == 0 && stloc.Variable.Kind == VariableKind.StackSlot) { if (aggressive ? SemanticHelper.IsPure(stloc.Value.Flags) : IsSimple(stloc.Value)) { Debug.Assert(SemanticHelper.IsPure(stloc.Value.Flags)); block.Instructions.RemoveAt(i++); } else { stloc.Value.AddILRange(stloc); stloc.ReplaceWith(stloc.Value); } } } bool IsSimple(ILInstruction inst) { switch (inst.OpCode) { case OpCode.LdLoc: case OpCode.LdStr: // C# 1.0 compiler sometimes emits redundant ldstr in switch-on-string pattern return(true); default: return(false); } } }
protected internal override void VisitBinaryNumericInstruction(BinaryNumericInstruction inst) { base.VisitBinaryNumericInstruction(inst); switch (inst.Operator) { case BinaryNumericOperator.ShiftLeft: case BinaryNumericOperator.ShiftRight: if (inst.Right.MatchBinaryNumericInstruction(BinaryNumericOperator.BitAnd, out var lhs, out var rhs) && rhs.MatchLdcI4(inst.ResultType == StackType.I8 ? 63 : 31)) { // a << (b & 31) => a << b context.Step("Combine bit.and into shift", inst); inst.Right = lhs; } break; case BinaryNumericOperator.BitAnd: if (inst.Left.InferType(context.TypeSystem).IsKnownType(KnownTypeCode.Boolean) && inst.Right.InferType(context.TypeSystem).IsKnownType(KnownTypeCode.Boolean)) { if (new NullableLiftingTransform(context).Run(inst)) { // e.g. "(a.GetValueOrDefault() == b.GetValueOrDefault()) & (a.HasValue & b.HasValue)" } else if (SemanticHelper.IsPure(inst.Right.Flags)) { context.Step("Replace bit.and with logic.and", inst); var expr = IfInstruction.LogicAnd(inst.Left, inst.Right); inst.ReplaceWith(expr); expr.AcceptVisitor(this); } } break; } }
public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { var symbol = SemanticHelper.GetSemanticSymbol(node, _semanticModel, _preportSemanticModel); var newNode = base.VisitMemberAccessExpression(node); if (symbol != null) { var nodeKey = $"{symbol.ContainingType}.{node.Name}"; foreach (var action in _allActions.OfType <MemberAccessAction>()) { if (nodeKey == action.Key) { var actionExecution = new GenericActionExecution(action, _filePath) { TimesRun = 1 }; try { newNode = action.MemberAccessActionFunc(_syntaxGenerator, newNode); LogHelper.LogInformation(string.Format("{0}: {1}", node.SpanStart, action.Description)); } catch (Exception ex) { var actionExecutionException = new ActionExecutionException(action.Name, action.Key, ex); actionExecution.InvalidExecutions = 1; LogHelper.LogError(actionExecutionException); } allExecutedActions.Add(actionExecution); } } } return(newNode); }
static bool MatchingGetterAndSetterCalls(CallInstruction getterCall, CallInstruction setterCall) { if (getterCall == null || setterCall == null || !IsSameMember(getterCall.Method.AccessorOwner, setterCall.Method.AccessorOwner)) { return(false); } var owner = getterCall.Method.AccessorOwner as IProperty; if (owner == null || !IsSameMember(getterCall.Method, owner.Getter) || !IsSameMember(setterCall.Method, owner.Setter)) { return(false); } if (setterCall.Arguments.Count != getterCall.Arguments.Count + 1) { return(false); } // Ensure that same arguments are passed to getterCall and setterCall: for (int j = 0; j < getterCall.Arguments.Count; j++) { if (!SemanticHelper.IsPure(getterCall.Arguments[j].Flags)) { return(false); } if (!getterCall.Arguments[j].Match(setterCall.Arguments[j]).Success) { return(false); } } return(true); }
public void Run(Block block, BlockTransformContext context) { for (int i = 0; i < block.Instructions.Count; i++) { ILVariable v; ILInstruction copiedExpr; if (block.Instructions[i].MatchStLoc(out v, out copiedExpr)) { if (v.IsSingleDefinition && v.LoadCount == 0 && v.Kind == VariableKind.StackSlot) { // dead store to stack if (SemanticHelper.IsPure(copiedExpr.Flags)) { // no-op -> delete context.Step("remove dead store to stack: no-op -> delete", block.Instructions[i]); block.Instructions.RemoveAt(i--); } else { // evaluate the value for its side-effects context.Step("remove dead store to stack: evaluate the value for its side-effects", block.Instructions[i]); copiedExpr.AddILRange(block.Instructions[i].ILRange); block.Instructions[i] = copiedExpr; } } else if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr)) { DoPropagate(v, copiedExpr, block, ref i, context); } } } }
public override SyntaxNode VisitInterfaceDeclaration(InterfaceDeclarationSyntax node) { var classSymbol = SemanticHelper.GetDeclaredSymbol(node, _semanticModel, _preportSemanticModel); InterfaceDeclarationSyntax newNode = (InterfaceDeclarationSyntax)base.VisitInterfaceDeclaration(node); foreach (var action in _allActions.OfType <InterfaceDeclarationAction>()) { if (action.Key == node.Identifier.Text.Trim()) { var actionExecution = new GenericActionExecution(action, _filePath) { TimesRun = 1 }; try { newNode = action.InterfaceDeclarationActionFunc(_syntaxGenerator, newNode); LogHelper.LogInformation(string.Format("{0}: {1}", node.SpanStart, action.Description)); } catch (Exception ex) { var actionExecutionException = new ActionExecutionException(action.Name, action.Key, ex); actionExecution.InvalidExecutions = 1; LogHelper.LogError(actionExecutionException); } allExecutedActions.Add(actionExecution); } } return(newNode); }
/// <summary> /// Unwraps a nested BlockContainer, if container contains only a single block, /// and that single block contains only a BlockContainer followed by a Leave instruction. /// If the leave instruction is a return that carries a value, the container is unwrapped only /// if the value has no side-effects. /// Otherwise returns the unmodified container. /// </summary> /// <param name="optionalReturnInst">If the leave is a return and has no side-effects, we can move the return out of the using-block and put it after the loop, otherwise returns null.</param> BlockContainer UnwrapNestedContainerIfPossible(BlockContainer container, out Leave optionalReturnInst) { optionalReturnInst = null; // Check block structure: if (container.Blocks.Count != 1) { return(container); } var nestedBlock = container.Blocks[0]; if (nestedBlock.Instructions.Count != 2 || !(nestedBlock.Instructions[0] is BlockContainer nestedContainer) || !(nestedBlock.Instructions[1] is Leave leave)) { return(container); } // If the leave has no value, just unwrap the BlockContainer. if (leave.MatchLeave(container)) { return(nestedContainer); } // If the leave is a return, we can move the return out of the using-block and put it after the loop // (but only if the value doesn't have side-effects) if (leave.IsLeavingFunction && SemanticHelper.IsPure(leave.Value.Flags)) { optionalReturnInst = leave; return(nestedContainer); } return(container); }
protected internal override void VisitBinaryNumericInstruction(BinaryNumericInstruction inst) { base.VisitBinaryNumericInstruction(inst); switch (inst.Operator) { case BinaryNumericOperator.ShiftLeft: case BinaryNumericOperator.ShiftRight: if (inst.Right.MatchBinaryNumericInstruction(BinaryNumericOperator.BitAnd, out var lhs, out var rhs) && rhs.MatchLdcI4(inst.ResultType == StackType.I8 ? 63 : 31)) { // a << (b & 31) => a << b context.Step("Combine bit.and into shift", inst); inst.Right = lhs; } break; case BinaryNumericOperator.BitAnd: if (IsBoolean(inst.Left) && IsBoolean(inst.Right) && SemanticHelper.IsPure(inst.Right.Flags)) { context.Step("Replace bit.and with logic.and", inst); var expr = IfInstruction.LogicAnd(inst.Left, inst.Right); inst.ReplaceWith(expr); expr.AcceptVisitor(this); } break; } }
public override SyntaxNode VisitObjectCreationExpression(ObjectCreationExpressionSyntax node) { var symbol = SemanticHelper.GetSemanticSymbol(node, _semanticModel, _preportSemanticModel); ExpressionSyntax newNode = node; bool skipChildren = false; // This is here to skip actions on children node when the main identifier was changed. Just use new expression for the subsequent children actions. foreach (var action in _allActions.OfType <ObjectCreationExpressionAction>()) { if (newNode.ToString() == action.Key || symbol?.OriginalDefinition.ToDisplayString() == action.Key) { var actionExecution = new GenericActionExecution(action, _filePath) { TimesRun = 1 }; try { skipChildren = true; newNode = action.ObjectCreationExpressionGenericActionFunc(_syntaxGenerator, (ObjectCreationExpressionSyntax)newNode); allExecutedActions.Add(actionExecution); LogHelper.LogInformation(string.Format("{0}", action.Description)); } catch (Exception ex) { var actionExecutionException = new ActionExecutionException(action.Name, action.Key, ex); actionExecution.InvalidExecutions = 1; LogHelper.LogError(actionExecutionException); } } } if (!skipChildren) { newNode = (ObjectCreationExpressionSyntax)base.VisitObjectCreationExpression(node); } return(newNode); }
public void SetCredentialsTest() { SemanticHelper target = new SemanticHelper(); // TODO: Initialize to an appropriate value ClientCredentials credentials = null; // TODO: Initialize to an appropriate value target.SetCredentials(credentials); Assert.Inconclusive("A method that does not return a value cannot be verified."); }
Comp LiftCSharpEqualityComparison(Comp valueComp, ComparisonKind newComparisonKind, ILInstruction hasValueTest) { Debug.Assert(newComparisonKind.IsEqualityOrInequality()); bool hasValueTestNegated = false; while (hasValueTest.MatchLogicNot(out var arg)) { hasValueTest = arg; hasValueTestNegated = !hasValueTestNegated; } // The HasValue comparison must be the same operator as the Value comparison. if (hasValueTest is Comp hasValueComp) { // Comparing two nullables: HasValue comparison must be the same operator as the Value comparison if ((hasValueTestNegated ? hasValueComp.Kind.Negate() : hasValueComp.Kind) != newComparisonKind) { return(null); } if (!MatchHasValueCall(hasValueComp.Left, out var leftVar)) { return(null); } if (!MatchHasValueCall(hasValueComp.Right, out var rightVar)) { return(null); } nullableVars = new List <ILVariable> { leftVar }; var(left, leftBits) = DoLift(valueComp.Left); nullableVars[0] = rightVar; var(right, rightBits) = DoLift(valueComp.Right); if (left != null && right != null && leftBits[0] && rightBits[0] && SemanticHelper.IsPure(left.Flags) && SemanticHelper.IsPure(right.Flags) ) { context.Step("NullableLiftingTransform: C# (in)equality comparison", valueComp); return(new Comp(newComparisonKind, ComparisonLiftingKind.CSharp, valueComp.InputType, valueComp.Sign, left, right)); } } else if (newComparisonKind == ComparisonKind.Equality && !hasValueTestNegated && MatchHasValueCall(hasValueTest, out var v)) { // Comparing nullable with non-nullable -> we can fall back to the normal comparison code. nullableVars = new List <ILVariable> { v }; return(LiftCSharpComparison(valueComp, newComparisonKind)); } else if (newComparisonKind == ComparisonKind.Inequality && hasValueTestNegated && MatchHasValueCall(hasValueTest, out v)) { // Comparing nullable with non-nullable -> we can fall back to the normal comparison code. nullableVars = new List <ILVariable> { v }; return(LiftCSharpComparison(valueComp, newComparisonKind)); } return(null); }
private void btnSave_Click(object sender, RoutedEventArgs e) { SemanticHelper helper = new SemanticHelper(); helper.UpdateRelations(m_Link); m_Link.ParentWord.Reviewed = true; helper.UpdateWordStatus(m_Link.ParentWord, m_Link.ParentWord.Status); DialogResult = true; Close(); }
public void CreateWordFormsChannelTest() { SemanticHelper target = new SemanticHelper(); // TODO: Initialize to an appropriate value Ilib5 expected = null; // TODO: Initialize to an appropriate value Ilib5 actual; actual = target.CreateWordFormsChannel(); Assert.AreEqual(expected, actual); Assert.Inconclusive("Verify the correctness of this test method."); }
public void CheckCredentialsTest() { SemanticHelper target = new SemanticHelper(); // TODO: Initialize to an appropriate value bool expected = false; // TODO: Initialize to an appropriate value bool actual; actual = target.CheckCredentials(); Assert.AreEqual(expected, actual); Assert.Inconclusive("Verify the correctness of this test method."); }
public void GetSemanticLinkFromDBTest() { SemanticHelper target = new SemanticHelper(); // TODO: Initialize to an appropriate value string sWord = string.Empty; // TODO: Initialize to an appropriate value WordSemanticBranch expected = null; // TODO: Initialize to an appropriate value WordSemanticBranch actual; actual = target.GetSemanticLinkFromDB(sWord); Assert.AreEqual(expected, actual); Assert.Inconclusive("Verify the correctness of this test method."); }
public void UpdateWordStatusTest() { SemanticHelper target = new SemanticHelper(); // TODO: Initialize to an appropriate value RegistryWord aWord = null; // TODO: Initialize to an appropriate value WordStatus eStatus = new WordStatus(); // TODO: Initialize to an appropriate value RegistryWord expected = null; // TODO: Initialize to an appropriate value RegistryWord actual; actual = target.UpdateWordStatus(aWord, eStatus); Assert.AreEqual(expected, actual); Assert.Inconclusive("Verify the correctness of this test method."); }
public void Run(ILFunction function, ILTransformContext context) { var visitor = new DefiniteAssignmentVisitor(function, context.CancellationToken); function.Body.AcceptVisitor(visitor); foreach (var v in function.Variables) { if (v.Kind != VariableKind.Parameter && !visitor.IsPotentiallyUsedUninitialized(v)) { v.HasInitialValue = false; } } // Remove dead stores to variables that are never read from. // If the stored value has some side-effect, the value is unwrapped. // This is necessary to remove useless stores generated by some compilers, e.g., the F# compiler. // In yield return + async, the C# compiler tends to store null/default(T) to variables // when the variable goes out of scope. if (function.IsAsync || function.IsIterator || context.Settings.RemoveDeadCode) { var variableQueue = new Queue <ILVariable>(function.Variables); while (variableQueue.Count > 0) { var v = variableQueue.Dequeue(); if (v.Kind != VariableKind.Local && v.Kind != VariableKind.StackSlot) { continue; } if (v.LoadCount != 0 || v.AddressCount != 0) { continue; } foreach (var stloc in v.StoreInstructions.OfType <StLoc>().ToArray()) { if (stloc.Parent is Block block) { if (SemanticHelper.IsPure(stloc.Value.Flags)) { block.Instructions.Remove(stloc); } else { stloc.ReplaceWith(stloc.Value); } if (stloc.Value is LdLoc ldloc) { variableQueue.Enqueue(ldloc.Variable); } } } } } }
/// <summary> Drops the result value. The result expression is still executed, though. </summary> public StatementBlock AsVoid() { if (IsVoid) { return(this); } else if (SemanticHelper.IsPure(Instruction.Flags)) { return(new StatementBlock(Statements)); } else { return(new StatementBlock(Statements.Add(new ExpressionStatement(Instr())))); } }
/// <summary> /// Lift a C# comparison. /// This method cannot be used for (in)equality comparisons where both sides are nullable /// (these special cases are handled in LiftCSharpEqualityComparison instead). /// /// The output instructions should evaluate to <c>false</c> when any of the <c>nullableVars</c> is <c>null</c> /// (except for newComparisonKind==Inequality, where this case should evaluate to <c>true</c> instead). /// Otherwise, the output instruction should evaluate to the same value as the input instruction. /// The output instruction should have the same side-effects (incl. exceptions being thrown) as the input instruction. /// This means unlike LiftNormal(), we cannot rely on the input instruction not being evaluated if /// a variable is <c>null</c>. /// </summary> Comp LiftCSharpComparison(Comp comp, ComparisonKind newComparisonKind) { var(left, right, bits) = DoLiftBinary(comp.Left, comp.Right); // due to the restrictions on side effects, we only allow instructions that are pure after lifting. // (we can't check this before lifting due to the calls to GetValueOrDefault()) if (left != null && right != null && SemanticHelper.IsPure(left.Flags) && SemanticHelper.IsPure(right.Flags)) { if (!bits.All(0, nullableVars.Count)) { // don't lift if a nullableVar doesn't contribute to the result return(null); } context.Step("NullableLiftingTransform: C# comparison", comp); return(new Comp(newComparisonKind, ComparisonLiftingKind.CSharp, comp.InputType, comp.Sign, left, right)); } return(null); }
public override SyntaxNode VisitExpressionStatement(ExpressionStatementSyntax node) { var newNode = base.VisitExpressionStatement(node); SyntaxNode modifiedNode = newNode; var invocationExpressionNodes = node.DescendantNodes().OfType <InvocationExpressionSyntax>().ToList(); if (invocationExpressionNodes.Count <= 0) { return(newNode); } var invocationExpressionNode = invocationExpressionNodes.First(); var symbol = SemanticHelper.GetSemanticSymbol(invocationExpressionNode, _semanticModel, _preportSemanticModel); if (symbol == null) { return(newNode); } var nodeKey = symbol.OriginalDefinition.ToString(); foreach (var action in _allActions.OfType <ExpressionAction>()) { if (nodeKey == action.Key) { var actionExecution = new GenericActionExecution(action, _filePath) { TimesRun = 1 }; try { modifiedNode = action.ExpressionActionFunc(_syntaxGenerator, newNode); LogHelper.LogInformation(string.Format("{0}: {1}", node.SpanStart, action.Description)); } catch (Exception ex) { var actionExecutionException = new ActionExecutionException(action.Name, action.Key, ex); actionExecution.InvalidExecutions = 1; LogHelper.LogError(actionExecutionException); } allExecutedActions.Add(actionExecution); } } return(modifiedNode); }
/// <summary> /// stobj(target, binary.op(ldobj(target), ...)) /// where target is pure /// => compound.op(target, ...) /// </summary> /// <remarks> /// Called by ExpressionTransforms. /// </remarks> internal static bool HandleStObjCompoundAssign(StObj inst, ILTransformContext context) { if (!(UnwrapSmallIntegerConv(inst.Value, out var conv) is BinaryNumericInstruction binary)) { return(false); } if (!(binary.Left is LdObj ldobj)) { return(false); } if (!inst.Target.Match(ldobj.Target).Success) { return(false); } if (!SemanticHelper.IsPure(ldobj.Target.Flags)) { return(false); } // ldobj.Type may just be 'int' (due to ldind.i4) when we're actually operating on a 'ref MyEnum'. // Try to determine the real type of the object we're modifying: IType targetType = ldobj.Target.InferType(); if (targetType.Kind == TypeKind.Pointer || targetType.Kind == TypeKind.ByReference) { targetType = ((TypeWithElementType)targetType).ElementType; if (targetType.Kind == TypeKind.Unknown || targetType.GetSize() != ldobj.Type.GetSize()) { targetType = ldobj.Type; } } else { targetType = ldobj.Type; } if (!ValidateCompoundAssign(binary, conv, targetType)) { return(false); } context.Step("compound assignment", inst); inst.ReplaceWith(new CompoundAssignmentInstruction( binary, binary.Left, binary.Right, targetType, CompoundAssignmentType.EvaluatesToNewValue)); return(true); }
public void CreateChannelTest() { SemanticHelper target = new SemanticHelper(); // TODO: Initialize to an appropriate value ClientCredentials cred = new ClientCredentials(); cred.UserName.UserName = string.Empty; cred.UserName.Password = string.Empty; target.SetCredentials(cred); IExplDic actual; actual = target.CreateChannel(); Assert.IsNotNull(actual); int n1 = actual.GetRowCount("КОС", true, new int[] { 1, 1000 }, false, 1); // ExplGetVolumes(1); int nQaunt = 0; int n2 = actual.Search(out nQaunt, "КОРЧОМ", true, string.Empty, true, new int[] { 1, 1000 }, false, 1); // ExplGetVolumes(1); int n = actual.ExplCheckReestr("КО#СА", 0, 1); n = actual.ExplCheckReestr("КО#СА", 1, 1); n = actual.ExplCheckReestr("КОСА", 0, 1); n = actual.ExplCheckReestr("КОСА", 1, 1); n = actual.ExplCheckReestr("КОСА#", 0, 1); n = actual.ExplCheckReestr("КОСА#", 1, 1); SemanticLinkHelper.ExplDictService.elList[] page1 = null; SemanticLinkHelper.ExplDictService.elList[] page2 = null; SemanticLinkHelper.ExplDictService.elList[] page3 = null; if (n != -1) { page1 = actual.SupplyPageOfData(n, 10, true, string.Empty, true, new int[] { 1 }, false, 1); page2 = actual.SupplyPageOfData(n, 10, true, string.Empty, false, new int[] { 1, 1000 }, false, 1); page3 = actual.SupplyPageOfData(1000, 10, true, string.Empty, false, new int[] { 1000, 5000 }, false, 1); page3 = actual.SupplyPageOfData(n2, 10, true, string.Empty, false, new int[] { 1000, 5000 }, false, 1); int a = 1; } n = actual.ExplCheckReestr("КОСА#", 2, 1); n = actual.ExplCheckReestr("КОСА#", 3, 1); n = actual.ExplCheckReestr("КОСА#", 4, 1); n = actual.ExplCheckReestr("КОСА#", 5, 1); Assert.Inconclusive("Verify the correctness of this test method."); }