/// <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); } }