From 207bfde593b47b62bce749b19846d8a810cb39fe Mon Sep 17 00:00:00 2001 From: Ivan Bondarev Date: Sun, 20 Aug 2023 11:09:34 +0200 Subject: [PATCH] #2916 --- NETGenerator/NETGenegratorTools.cs | 1 + NETGenerator/NETGenerator.cs | 7 +++++-- TestSuite/foreach12.pas | 31 ++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 TestSuite/foreach12.pas diff --git a/NETGenerator/NETGenegratorTools.cs b/NETGenerator/NETGenegratorTools.cs index 6cdda587d..c18b02d15 100644 --- a/NETGenerator/NETGenegratorTools.cs +++ b/NETGenerator/NETGenegratorTools.cs @@ -50,6 +50,7 @@ namespace PascalABCCompiler.NETGenerator public static Type ValueType = typeof(ValueType); public static Type IEnumerableType = typeof(System.Collections.IEnumerable); public static Type IEnumeratorType = typeof(System.Collections.IEnumerator); + public static Type IDisposableType = typeof(IDisposable); public static Type IEnumerableGenericType = typeof(System.Collections.Generic.IEnumerable<>); public static Type IEnumeratorGenericType = typeof(System.Collections.Generic.IEnumerator<>); diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index 44105e667..7003df4f7 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -11620,8 +11620,11 @@ namespace PascalABCCompiler.NETGenerator //il.Emit(OpCodes.Leave, leave_label); il.BeginFinallyBlock(); //il.MarkLabel(br_lbl); - il.Emit(OpCodes.Ldnull); - il.Emit(OpCodes.Stloc, lb); + if (lb.LocalType.IsValueType) + il.Emit(OpCodes.Ldloca, lb); + else + il.Emit(OpCodes.Ldloc, lb); + il.Emit(OpCodes.Callvirt, TypeFactory.IDisposableType.GetMethod("Dispose", BindingFlags.Instance | BindingFlags.Public)); il.EndExceptionBlock(); il.MarkLabel(leave_label); diff --git a/TestSuite/foreach12.pas b/TestSuite/foreach12.pas new file mode 100644 index 000000000..81154459b --- /dev/null +++ b/TestSuite/foreach12.pas @@ -0,0 +1,31 @@ +var c := 0; + +type + t1 = class(IEnumerable, IEnumerator) + + public function GetEnumerator: IEnumerator := self; + function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := self; + + public function MoveNext := false; + + public property Current: byte read 0; + property System.Collections.IEnumerator.Current: object read 0; + + public procedure Reset := exit; + + public procedure Dispose := c += 1; + + end; + +function f1: sequence of byte; +begin + yield sequence new t1; + foreach var x in new t1 do + yield x; + foreach var x in new t1 do ; +end; + +begin + foreach var x in new t1 do ; + Assert(c = 1); +end. \ No newline at end of file