1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-13 22:04:09 +02:00

Fixed issue with multiple Dispose calls on foreach enumerator

This commit is contained in:
Brian Fiete 2021-05-31 07:01:56 -07:00
parent 9236b3e0d2
commit 85462e6d62
2 changed files with 60 additions and 8 deletions

View file

@ -6424,7 +6424,11 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
} }
} }
scopeData.mIsLoop = true; BfScopeData innerScopeData;
innerScopeData.mValueScopeStart = ValueScopeStart();
mCurMethodState->AddScope(&innerScopeData);
NewScopeState(true, false);
innerScopeData.mIsLoop = true;
if ((autoComplete != NULL) && (forEachStmt->mVariableTypeRef != NULL)) if ((autoComplete != NULL) && (forEachStmt->mVariableTypeRef != NULL))
autoComplete->CheckVarResolution(forEachStmt->mVariableTypeRef, varType); autoComplete->CheckVarResolution(forEachStmt->mVariableTypeRef, varType);
@ -6445,7 +6449,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
BfBreakData breakData; BfBreakData breakData;
breakData.mIRContinueBlock = incBB; breakData.mIRContinueBlock = incBB;
breakData.mIRBreakBlock = endBB; breakData.mIRBreakBlock = endBB;
breakData.mScope = &scopeData; breakData.mScope = &innerScopeData;
breakData.mInnerValueScopeStart = valueScopeStartInner; breakData.mInnerValueScopeStart = valueScopeStartInner;
breakData.mPrevBreakData = mCurMethodState->mBreakData; breakData.mPrevBreakData = mCurMethodState->mBreakData;
SetAndRestoreValue<BfBreakData*> prevBreakData(mCurMethodState->mBreakData, &breakData); SetAndRestoreValue<BfBreakData*> prevBreakData(mCurMethodState->mBreakData, &breakData);
@ -6679,6 +6683,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
mCurMethodState->mLeftBlockCond = false; mCurMethodState->mLeftBlockCond = false;
RestoreScopeState(); RestoreScopeState();
RestoreScopeState();
} }
void BfModule::Visit(BfDeferStatement* deferStmt) void BfModule::Visit(BfDeferStatement* deferStmt)

View file

@ -1,6 +1,7 @@
#pragma warning disable 168 #pragma warning disable 168
using System; using System;
using System.Collections;
namespace Tests namespace Tests
{ {
@ -12,6 +13,21 @@ namespace Tests
public int32 mB; public int32 mB;
} }
class EnumeratorTest : IEnumerator<int32>, IDisposable
{
public int mDispCount;
public void Dispose()
{
mDispCount++;
}
public Result<int32> GetNext()
{
return .Err;
}
}
[Test] [Test]
public static void TestBasics() public static void TestBasics()
{ {
@ -26,6 +42,37 @@ namespace Tests
StructA sa = val; StructA sa = val;
int idx = @val; int idx = @val;
} }
var e = scope EnumeratorTest();
for (var val in e)
{
}
Test.Assert(e.mDispCount == 1);
for (var val in e)
{
break;
}
Test.Assert(e.mDispCount == 2);
TestEnumerator1(e);
Test.Assert(e.mDispCount == 3);
TestEnumerator2(e);
Test.Assert(e.mDispCount == 4);
}
public static void TestEnumerator1(EnumeratorTest e)
{
for (var val in e)
{
return;
}
}
public static void TestEnumerator2(EnumeratorTest e)
{
for (var val in e)
{
return;
}
} }
} }
} }