protected override InstructionFlags ComputeFlags() { var sectionFlags = defaultBody.Flags; foreach (var section in Sections) { sectionFlags = SemanticHelper.CombineBranches(sectionFlags, section.Flags); } return(value.Flags | InstructionFlags.ControlFlow | sectionFlags); }
protected override InstructionFlags ComputeFlags() { var flags = TryBlock.Flags; foreach (var handler in Handlers) { flags = SemanticHelper.CombineBranches(flags, handler.Flags); } return(flags | InstructionFlags.ControlFlow); }
protected override InstructionFlags ComputeFlags() { var sectionFlags = InstructionFlags.EndPointUnreachable; // neutral element for CombineBranches() foreach (var section in Sections) { sectionFlags = SemanticHelper.CombineBranches(sectionFlags, section.Flags); } return(value.Flags | InstructionFlags.ControlFlow | sectionFlags); }
/// <summary> /// called as part of CheckInvariant() /// </summary> void CheckTargetSlot() { switch (this.Target.OpCode) { case OpCode.LdElema: case OpCode.LdFlda: if (this.Target.HasDirectFlag(InstructionFlags.MayThrow)) { Debug.Assert(SemanticHelper.IsPure(this.Value.Flags)); } break; } }
/// <summary> /// For a store to a field or array element, C# will only throw NullReferenceException/IndexOfBoundsException /// after the value-to-be-stored has been computed. /// This means a LdFlda/LdElema used as target for StObj must have DelayExceptions==true to allow a translation to C# /// without changing the program semantics. See https://github.com/icsharpcode/ILSpy/issues/2050 /// </summary> public bool CanInlineIntoTargetSlot(ILInstruction inst) { switch (inst.OpCode) { case OpCode.LdElema: case OpCode.LdFlda: Debug.Assert(inst.HasDirectFlag(InstructionFlags.MayThrow)); // If the ldelema/ldflda may throw a non-delayed exception, inlining will cause it // to turn into a delayed exception after the translation to C#. // This is only valid if the value computation doesn't involve any side effects. return(SemanticHelper.IsPure(this.Value.Flags)); // Note that after inlining such a ldelema/ldflda, the normal inlining rules will // prevent us from inlining an effectful instruction into the value slot. default: return(true); } }
protected override InstructionFlags ComputeFlags() { return(InstructionFlags.ControlFlow | condition.Flags | SemanticHelper.CombineBranches(trueInst.Flags, falseInst.Flags)); }
protected override InstructionFlags ComputeFlags() { // left is always executed; right only sometimes return(DirectFlags | left.Flags | SemanticHelper.CombineBranches(InstructionFlags.None, right.Flags)); }
protected override InstructionFlags ComputeFlags() { // valueInst is always executed; fallbackInst only sometimes return(InstructionFlags.ControlFlow | valueInst.Flags | SemanticHelper.CombineBranches(InstructionFlags.None, fallbackInst.Flags)); }
protected override InstructionFlags ComputeFlags() { return(InstructionFlags.ControlFlow | SemanticHelper.CombineBranches(valueInst.Flags, fallbackInst.Flags)); }