mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 12:32:20 +02:00
Improved variable assignment detection
This commit is contained in:
parent
a42e0fad60
commit
5277797d73
5 changed files with 206 additions and 55 deletions
|
@ -342,5 +342,79 @@ namespace IDETest
|
||||||
int b3 = b; //FAIL
|
int b3 = b; //FAIL
|
||||||
int c3 = c; //FAIL
|
int c3 = c; //FAIL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<int> Read()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Local8()
|
||||||
|
{
|
||||||
|
int read;
|
||||||
|
loop: repeat
|
||||||
|
{
|
||||||
|
switch (Read())
|
||||||
|
{
|
||||||
|
case .Err: return;
|
||||||
|
case .Ok(let val): read = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (read > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Local9()
|
||||||
|
{
|
||||||
|
int read;
|
||||||
|
loop: repeat
|
||||||
|
{
|
||||||
|
switch (Read())
|
||||||
|
{
|
||||||
|
case .Err: break loop;
|
||||||
|
case .Ok(let val): read = val;
|
||||||
|
}
|
||||||
|
int a = read;
|
||||||
|
}
|
||||||
|
while (read > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Local10()
|
||||||
|
{
|
||||||
|
int read;
|
||||||
|
loop: repeat
|
||||||
|
{
|
||||||
|
switch (Read())
|
||||||
|
{
|
||||||
|
case .Err: break;
|
||||||
|
case .Ok(let val): read = val;
|
||||||
|
}
|
||||||
|
int a = read; //FAIL
|
||||||
|
}
|
||||||
|
while (read > 0); //FAIL
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Local11()
|
||||||
|
{
|
||||||
|
int a = 123;
|
||||||
|
|
||||||
|
int read;
|
||||||
|
Loop: repeat
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (read > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Local12()
|
||||||
|
{
|
||||||
|
int a = 123;
|
||||||
|
|
||||||
|
int read;
|
||||||
|
Loop: repeat
|
||||||
|
{
|
||||||
|
if (a == 123)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (read > 0); //FAIL
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18952,6 +18952,8 @@ void BfExprEvaluator::CheckResultForReading(BfTypedValue& typedValue)
|
||||||
undefinedFieldFlags = 0;
|
undefinedFieldFlags = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (deferredLocalAssignData->mLeftBlockUncond)
|
||||||
|
isAssigned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldIdx == -1)
|
if (fieldIdx == -1)
|
||||||
|
|
|
@ -133,48 +133,61 @@ void BfDeferredLocalAssignData::BreakExtendChain()
|
||||||
void BfDeferredLocalAssignData::SetIntersection(const BfDeferredLocalAssignData& otherLocalAssignData)
|
void BfDeferredLocalAssignData::SetIntersection(const BfDeferredLocalAssignData& otherLocalAssignData)
|
||||||
{
|
{
|
||||||
BreakExtendChain();
|
BreakExtendChain();
|
||||||
|
|
||||||
for (int i = 0; i < (int)mAssignedLocals.size(); )
|
if (otherLocalAssignData.mLeftBlockUncond)
|
||||||
{
|
{
|
||||||
auto& local = mAssignedLocals[i];
|
// Intersection of self and infinity is self
|
||||||
|
}
|
||||||
bool wantRemove = true;
|
else if (mLeftBlockUncond)
|
||||||
bool foundOtherFields = false;
|
{
|
||||||
for (auto& otherLocalAssignData : otherLocalAssignData.mAssignedLocals)
|
// Intersection of infinity and other is other
|
||||||
|
mAssignedLocals = otherLocalAssignData.mAssignedLocals;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (int)mAssignedLocals.size(); )
|
||||||
{
|
{
|
||||||
if (otherLocalAssignData.mLocalVar == local.mLocalVar)
|
auto& local = mAssignedLocals[i];
|
||||||
{
|
|
||||||
if ((otherLocalAssignData.mLocalVarField == local.mLocalVarField) || (otherLocalAssignData.mLocalVarField == -1))
|
|
||||||
{
|
|
||||||
if (otherLocalAssignData.mAssignKind == BfLocalVarAssignKind_Conditional)
|
|
||||||
local.mAssignKind = BfLocalVarAssignKind_Conditional;
|
|
||||||
wantRemove = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
foundOtherFields = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((wantRemove) && (foundOtherFields))
|
bool wantRemove = true;
|
||||||
{
|
bool foundOtherFields = false;
|
||||||
for (auto& otherLocalAssignData : otherLocalAssignData.mAssignedLocals)
|
for (auto& otherLocalAssignData : otherLocalAssignData.mAssignedLocals)
|
||||||
{
|
{
|
||||||
if (otherLocalAssignData.mLocalVar == local.mLocalVar)
|
if (otherLocalAssignData.mLocalVar == local.mLocalVar)
|
||||||
{
|
{
|
||||||
mAssignedLocals.Add(otherLocalAssignData);
|
if ((otherLocalAssignData.mLocalVarField == local.mLocalVarField) || (otherLocalAssignData.mLocalVarField == -1))
|
||||||
|
{
|
||||||
|
if (otherLocalAssignData.mAssignKind == BfLocalVarAssignKind_Conditional)
|
||||||
|
local.mAssignKind = BfLocalVarAssignKind_Conditional;
|
||||||
|
wantRemove = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
foundOtherFields = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wantRemove)
|
if ((wantRemove) && (foundOtherFields))
|
||||||
{
|
{
|
||||||
mAssignedLocals.RemoveAt(i);
|
for (auto& otherLocalAssignData : otherLocalAssignData.mAssignedLocals)
|
||||||
|
{
|
||||||
|
if (otherLocalAssignData.mLocalVar == local.mLocalVar)
|
||||||
|
{
|
||||||
|
mAssignedLocals.Add(otherLocalAssignData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wantRemove)
|
||||||
|
{
|
||||||
|
mAssignedLocals.RemoveAt(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mHadFallthrough = mHadFallthrough && otherLocalAssignData.mHadFallthrough;
|
mHadFallthrough = mHadFallthrough && otherLocalAssignData.mHadFallthrough;
|
||||||
|
mLeftBlockUncond = mLeftBlockUncond && otherLocalAssignData.mLeftBlockUncond;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfDeferredLocalAssignData::Validate() const
|
void BfDeferredLocalAssignData::Validate() const
|
||||||
|
@ -191,7 +204,7 @@ void BfDeferredLocalAssignData::SetUnion(const BfDeferredLocalAssignData& otherL
|
||||||
|
|
||||||
Validate();
|
Validate();
|
||||||
otherLocalAssignData.Validate();
|
otherLocalAssignData.Validate();
|
||||||
|
|
||||||
auto otherItr = otherLocalAssignData.mAssignedLocals.begin();
|
auto otherItr = otherLocalAssignData.mAssignedLocals.begin();
|
||||||
while (otherItr != otherLocalAssignData.mAssignedLocals.end())
|
while (otherItr != otherLocalAssignData.mAssignedLocals.end())
|
||||||
{
|
{
|
||||||
|
@ -200,6 +213,7 @@ void BfDeferredLocalAssignData::SetUnion(const BfDeferredLocalAssignData& otherL
|
||||||
++otherItr;
|
++otherItr;
|
||||||
}
|
}
|
||||||
mHadFallthrough = mHadFallthrough || otherLocalAssignData.mHadFallthrough;
|
mHadFallthrough = mHadFallthrough || otherLocalAssignData.mHadFallthrough;
|
||||||
|
mLeftBlockUncond = mLeftBlockUncond || otherLocalAssignData.mLeftBlockUncond;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfMethodState::~BfMethodState()
|
BfMethodState::~BfMethodState()
|
||||||
|
@ -311,9 +325,36 @@ void BfMethodState::ApplyDeferredLocalAssignData(const BfDeferredLocalAssignData
|
||||||
{
|
{
|
||||||
BF_ASSERT(&deferredLocalAssignData != mDeferredLocalAssignData);
|
BF_ASSERT(&deferredLocalAssignData != mDeferredLocalAssignData);
|
||||||
|
|
||||||
for (auto& assignedLocal : deferredLocalAssignData.mAssignedLocals)
|
if (deferredLocalAssignData.mLeftBlockUncond)
|
||||||
{
|
{
|
||||||
LocalDefined(assignedLocal.mLocalVar, assignedLocal.mLocalVarField, assignedLocal.mAssignKind, true);
|
if (mLeftBlockUncond)
|
||||||
|
{
|
||||||
|
for (int localIdx = 0; localIdx < (int)mLocals.size(); localIdx++)
|
||||||
|
{
|
||||||
|
auto localDef = mLocals[localIdx];
|
||||||
|
if (localDef->mAssignedKind == BfLocalVarAssignKind_None)
|
||||||
|
{
|
||||||
|
bool hadAssignment = false;
|
||||||
|
if (mDeferredLocalAssignData != NULL)
|
||||||
|
{
|
||||||
|
for (auto& entry : mDeferredLocalAssignData->mAssignedLocals)
|
||||||
|
if (entry.mLocalVar == localDef)
|
||||||
|
hadAssignment = true;
|
||||||
|
}
|
||||||
|
if (!hadAssignment)
|
||||||
|
{
|
||||||
|
LocalDefined(localDef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto& assignedLocal : deferredLocalAssignData.mAssignedLocals)
|
||||||
|
{
|
||||||
|
LocalDefined(assignedLocal.mLocalVar, assignedLocal.mLocalVarField, assignedLocal.mAssignKind, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -378,6 +378,7 @@ public:
|
||||||
bool mIsIfCondition;
|
bool mIsIfCondition;
|
||||||
bool mIfMayBeSkipped;
|
bool mIfMayBeSkipped;
|
||||||
bool mLeftBlock;
|
bool mLeftBlock;
|
||||||
|
bool mLeftBlockUncond;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfDeferredLocalAssignData(BfScopeData* scopeData = NULL)
|
BfDeferredLocalAssignData(BfScopeData* scopeData = NULL)
|
||||||
|
@ -393,6 +394,7 @@ public:
|
||||||
mIsIfCondition = false;
|
mIsIfCondition = false;
|
||||||
mIfMayBeSkipped = false;
|
mIfMayBeSkipped = false;
|
||||||
mLeftBlock = false;
|
mLeftBlock = false;
|
||||||
|
mLeftBlockUncond = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Contains(const BfAssignedLocal& val)
|
bool Contains(const BfAssignedLocal& val)
|
||||||
|
@ -448,6 +450,7 @@ public:
|
||||||
bool mInInitBlock;
|
bool mInInitBlock;
|
||||||
bool mSupressNextUnreachable;
|
bool mSupressNextUnreachable;
|
||||||
bool mInConstIgnore;
|
bool mInConstIgnore;
|
||||||
|
bool mIsSharedTempBlock;
|
||||||
BfMixinState* mMixinState;
|
BfMixinState* mMixinState;
|
||||||
BfBlock* mAstBlock;
|
BfBlock* mAstBlock;
|
||||||
BfAstNode* mCloseNode;
|
BfAstNode* mCloseNode;
|
||||||
|
@ -488,6 +491,7 @@ public:
|
||||||
mAllowVariableDeclarations = true;
|
mAllowVariableDeclarations = true;
|
||||||
mInInitBlock = false;
|
mInInitBlock = false;
|
||||||
mInConstIgnore = false;
|
mInConstIgnore = false;
|
||||||
|
mIsSharedTempBlock = false;
|
||||||
mMixinDepth = 0;
|
mMixinDepth = 0;
|
||||||
mScopeDepth = 0;
|
mScopeDepth = 0;
|
||||||
mScopeLocalId = -1;
|
mScopeLocalId = -1;
|
||||||
|
@ -1668,7 +1672,7 @@ public:
|
||||||
void AddBasicBlock(BfIRBlock bb, bool activate = true);
|
void AddBasicBlock(BfIRBlock bb, bool activate = true);
|
||||||
void VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEvaluator = NULL, BfEmbeddedStatementFlags flags = BfEmbeddedStatementFlags_None);
|
void VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEvaluator = NULL, BfEmbeddedStatementFlags flags = BfEmbeddedStatementFlags_None);
|
||||||
void VisitCodeBlock(BfBlock* block);
|
void VisitCodeBlock(BfBlock* block);
|
||||||
void VisitCodeBlock(BfBlock* block, BfIRBlock continueBlock, BfIRBlock breakBlock, BfIRBlock fallthroughBlock, bool defaultBreak, bool* hadReturn = NULL, BfLabelNode* labelNode = NULL, bool closeScope = false);
|
void VisitCodeBlock(BfBlock* block, BfIRBlock continueBlock, BfIRBlock breakBlock, BfIRBlock fallthroughBlock, bool defaultBreak, bool* hadReturn = NULL, BfLabelNode* labelNode = NULL, bool closeScope = false, BfEmbeddedStatementFlags flags = BfEmbeddedStatementFlags_None);
|
||||||
void DoForLess(BfForEachStatement* forEachStmt);
|
void DoForLess(BfForEachStatement* forEachStmt);
|
||||||
|
|
||||||
// Util
|
// Util
|
||||||
|
|
|
@ -3297,7 +3297,7 @@ void BfModule::VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEval
|
||||||
mCurMethodState->mCurScope->mOuterIsConditional = (flags & BfEmbeddedStatementFlags_IsConditional) != 0;
|
mCurMethodState->mCurScope->mOuterIsConditional = (flags & BfEmbeddedStatementFlags_IsConditional) != 0;
|
||||||
mCurMethodState->mCurScope->mIsDeferredBlock = (flags & BfEmbeddedStatementFlags_IsDeferredBlock) != 0;
|
mCurMethodState->mCurScope->mIsDeferredBlock = (flags & BfEmbeddedStatementFlags_IsDeferredBlock) != 0;
|
||||||
mCurMethodState->mCurScope->mExprEvaluator = exprEvaluator;
|
mCurMethodState->mCurScope->mExprEvaluator = exprEvaluator;
|
||||||
|
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<bool> inDeferredBlock(mCurMethodState->mInDeferredBlock, mCurMethodState->mInDeferredBlock || mCurMethodState->mCurScope->mIsDeferredBlock);
|
SetAndRestoreValue<bool> inDeferredBlock(mCurMethodState->mInDeferredBlock, mCurMethodState->mInDeferredBlock || mCurMethodState->mCurScope->mIsDeferredBlock);
|
||||||
|
@ -3345,7 +3345,7 @@ void BfModule::VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEval
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::VisitCodeBlock(BfBlock* block, BfIRBlock continueBlock, BfIRBlock breakBlock, BfIRBlock fallthroughBlock, bool defaultBreak, bool* hadReturn, BfLabelNode* labelNode, bool closeScope)
|
void BfModule::VisitCodeBlock(BfBlock* block, BfIRBlock continueBlock, BfIRBlock breakBlock, BfIRBlock fallthroughBlock, bool defaultBreak, bool* hadReturn, BfLabelNode* labelNode, bool closeScope, BfEmbeddedStatementFlags flags)
|
||||||
{
|
{
|
||||||
BfBreakData breakData;
|
BfBreakData breakData;
|
||||||
breakData.mIRContinueBlock = continueBlock;
|
breakData.mIRContinueBlock = continueBlock;
|
||||||
|
@ -3355,7 +3355,7 @@ void BfModule::VisitCodeBlock(BfBlock* block, BfIRBlock continueBlock, BfIRBlock
|
||||||
breakData.mPrevBreakData = mCurMethodState->mBreakData;
|
breakData.mPrevBreakData = mCurMethodState->mBreakData;
|
||||||
|
|
||||||
SetAndRestoreValue<BfBreakData*> prevBreakData(mCurMethodState->mBreakData, &breakData);
|
SetAndRestoreValue<BfBreakData*> prevBreakData(mCurMethodState->mBreakData, &breakData);
|
||||||
Visit(block);
|
VisitEmbeddedStatement(block, NULL, flags);
|
||||||
|
|
||||||
if (closeScope)
|
if (closeScope)
|
||||||
RestoreScopeState();
|
RestoreScopeState();
|
||||||
|
@ -3843,7 +3843,8 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i
|
||||||
ignoredLastBlock = false;
|
ignoredLastBlock = false;
|
||||||
VisitEmbeddedStatement(ifStmt->mTrueStatement);
|
VisitEmbeddedStatement(ifStmt->mTrueStatement);
|
||||||
}
|
}
|
||||||
prevDLA.Restore();
|
prevDLA.Restore();
|
||||||
|
|
||||||
if (mCurMethodState->mDeferredLocalAssignData != NULL)
|
if (mCurMethodState->mDeferredLocalAssignData != NULL)
|
||||||
mCurMethodState->mDeferredLocalAssignData->mHadBreak |= deferredLocalAssignData.mHadBreak;
|
mCurMethodState->mDeferredLocalAssignData->mHadBreak |= deferredLocalAssignData.mHadBreak;
|
||||||
|
|
||||||
|
@ -3858,7 +3859,10 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i
|
||||||
mBfIRBuilder->CreateBr_NoCollapse(contBB);
|
mBfIRBuilder->CreateBr_NoCollapse(contBB);
|
||||||
|
|
||||||
if (mCurMethodState->mLeftBlockUncond)
|
if (mCurMethodState->mLeftBlockUncond)
|
||||||
|
{
|
||||||
|
deferredLocalAssignData.mLeftBlockUncond = true;
|
||||||
mCurMethodState->mLeftBlockCond = true;
|
mCurMethodState->mLeftBlockCond = true;
|
||||||
|
}
|
||||||
|
|
||||||
mCurMethodState->mLeftBlockUncond = false;
|
mCurMethodState->mLeftBlockUncond = false;
|
||||||
mCurMethodState->SetHadReturn(false);
|
mCurMethodState->SetHadReturn(false);
|
||||||
|
@ -3908,7 +3912,10 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i
|
||||||
}
|
}
|
||||||
falseHadReturn = mCurMethodState->mHadReturn;
|
falseHadReturn = mCurMethodState->mHadReturn;
|
||||||
if (mCurMethodState->mLeftBlockUncond)
|
if (mCurMethodState->mLeftBlockUncond)
|
||||||
|
{
|
||||||
|
falseDeferredLocalAssignData.mLeftBlockUncond = true;
|
||||||
mCurMethodState->mLeftBlockCond = true;
|
mCurMethodState->mLeftBlockCond = true;
|
||||||
|
}
|
||||||
mCurMethodState->mLeftBlockUncond = false;
|
mCurMethodState->mLeftBlockUncond = false;
|
||||||
mCurMethodState->SetHadReturn(false);
|
mCurMethodState->SetHadReturn(false);
|
||||||
|
|
||||||
|
@ -4633,6 +4640,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt)
|
||||||
openedScope = true;
|
openedScope = true;
|
||||||
|
|
||||||
caseScopeData.mOuterIsConditional = true;
|
caseScopeData.mOuterIsConditional = true;
|
||||||
|
caseScopeData.mIsSharedTempBlock = true;
|
||||||
mCurMethodState->AddScope(&caseScopeData);
|
mCurMethodState->AddScope(&caseScopeData);
|
||||||
NewScopeState();
|
NewScopeState();
|
||||||
UpdateSrcPos(caseExpr);
|
UpdateSrcPos(caseExpr);
|
||||||
|
@ -4915,7 +4923,8 @@ void BfModule::Visit(BfSwitchStatement* switchStmt)
|
||||||
{
|
{
|
||||||
UpdateSrcPos(switchCase->mCodeBlock);
|
UpdateSrcPos(switchCase->mCodeBlock);
|
||||||
|
|
||||||
VisitCodeBlock(switchCase->mCodeBlock, BfIRBlock(), endBlock, fallthroughBlock, true, &hadReturn, switchStmt->mLabelNode, openedScope);
|
VisitCodeBlock(switchCase->mCodeBlock, BfIRBlock(), endBlock, fallthroughBlock, true, &hadReturn, switchStmt->mLabelNode, openedScope /*, BfEmbeddedStatementFlags_RescopeDLA*/);
|
||||||
|
|
||||||
openedScope = false;
|
openedScope = false;
|
||||||
deferredLocalAssignDataVec[blockIdx].mHadReturn = hadReturn;
|
deferredLocalAssignDataVec[blockIdx].mHadReturn = hadReturn;
|
||||||
caseCount++;
|
caseCount++;
|
||||||
|
@ -4953,7 +4962,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt)
|
||||||
|
|
||||||
mBfIRBuilder->SetInsertPoint(prevInsertBlock);
|
mBfIRBuilder->SetInsertPoint(prevInsertBlock);
|
||||||
|
|
||||||
prevHadFallthrough = mCurMethodState->mDeferredLocalAssignData->mHadFallthrough;
|
prevHadFallthrough = mCurMethodState->mDeferredLocalAssignData->mHadFallthrough;
|
||||||
|
|
||||||
blockIdx++;
|
blockIdx++;
|
||||||
}
|
}
|
||||||
|
@ -5053,7 +5062,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt)
|
||||||
mCurMethodState->mDeferredLocalAssignData->mVarIdBarrier = startingLocalVarId;
|
mCurMethodState->mDeferredLocalAssignData->mVarIdBarrier = startingLocalVarId;
|
||||||
|
|
||||||
bool hadReturn = false;
|
bool hadReturn = false;
|
||||||
VisitCodeBlock(switchCase->mCodeBlock, BfIRBlock(), endBlock, BfIRBlock(), true, &hadReturn, switchStmt->mLabelNode);
|
VisitCodeBlock(switchCase->mCodeBlock, BfIRBlock(), endBlock, BfIRBlock(), true, &hadReturn, switchStmt->mLabelNode);
|
||||||
deferredLocalAssignDataVec[blockIdx].mHadReturn = hadReturn;
|
deferredLocalAssignDataVec[blockIdx].mHadReturn = hadReturn;
|
||||||
caseCount++;
|
caseCount++;
|
||||||
if (!hadReturn)
|
if (!hadReturn)
|
||||||
|
@ -5381,18 +5390,7 @@ void BfModule::Visit(BfBreakStatement* breakStmt)
|
||||||
checkScope = checkScope->mPrevScope;
|
checkScope = checkScope->mPrevScope;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto checkLocalAssignData = mCurMethodState->mDeferredLocalAssignData;
|
|
||||||
while (checkLocalAssignData != NULL)
|
|
||||||
{
|
|
||||||
if ((checkLocalAssignData->mScopeData != NULL) && (checkLocalAssignData->mScopeData->mScopeDepth >= breakData->mScope->mScopeDepth))
|
|
||||||
{
|
|
||||||
checkLocalAssignData->mLeftBlock = true;
|
|
||||||
checkLocalAssignData->mHadBreak = true;
|
|
||||||
}
|
|
||||||
checkLocalAssignData = checkLocalAssignData->mChainedAssignData;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasDeferredScopeCalls(breakData->mScope))
|
if (HasDeferredScopeCalls(breakData->mScope))
|
||||||
{
|
{
|
||||||
EmitDeferredScopeCalls(true, breakData->mScope, breakData->mIRBreakBlock);
|
EmitDeferredScopeCalls(true, breakData->mScope, breakData->mIRBreakBlock);
|
||||||
|
@ -5403,16 +5401,41 @@ void BfModule::Visit(BfBreakStatement* breakStmt)
|
||||||
}
|
}
|
||||||
mCurMethodState->mLeftBlockUncond = true;
|
mCurMethodState->mLeftBlockUncond = true;
|
||||||
|
|
||||||
|
bool isCond = false;
|
||||||
|
int uncondScopeDepth = 0;
|
||||||
|
if (mCurMethodState->mCurScope != NULL)
|
||||||
|
uncondScopeDepth = mCurMethodState->mCurScope->mScopeDepth + 1;
|
||||||
|
|
||||||
BfIRValue earliestValueScopeStart;
|
BfIRValue earliestValueScopeStart;
|
||||||
auto checkScope = mCurMethodState->mCurScope;
|
auto checkScope = mCurMethodState->mCurScope;
|
||||||
while (checkScope != NULL)
|
while (checkScope != NULL)
|
||||||
{
|
{
|
||||||
|
if (!isCond)
|
||||||
|
uncondScopeDepth = checkScope->mScopeDepth;
|
||||||
|
if ((checkScope->mOuterIsConditional) && (!checkScope->mIsSharedTempBlock))
|
||||||
|
isCond = true;
|
||||||
|
|
||||||
if (checkScope->mValueScopeStart)
|
if (checkScope->mValueScopeStart)
|
||||||
earliestValueScopeStart = checkScope->mValueScopeStart;
|
earliestValueScopeStart = checkScope->mValueScopeStart;
|
||||||
if (checkScope == breakData->mScope)
|
if (checkScope == breakData->mScope)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
checkScope = checkScope->mPrevScope;
|
checkScope = checkScope->mPrevScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto checkLocalAssignData = mCurMethodState->mDeferredLocalAssignData;
|
||||||
|
while (checkLocalAssignData != NULL)
|
||||||
|
{
|
||||||
|
if ((checkLocalAssignData->mScopeData != NULL) && (checkLocalAssignData->mScopeData->mScopeDepth >= breakData->mScope->mScopeDepth))
|
||||||
|
{
|
||||||
|
if (checkLocalAssignData->mScopeData->mScopeDepth >= uncondScopeDepth)
|
||||||
|
checkLocalAssignData->mLeftBlockUncond = true;
|
||||||
|
checkLocalAssignData->mLeftBlock = true;
|
||||||
|
checkLocalAssignData->mHadBreak = true;
|
||||||
|
}
|
||||||
|
checkLocalAssignData = checkLocalAssignData->mChainedAssignData;
|
||||||
|
}
|
||||||
|
|
||||||
MarkScopeLeft(breakData->mScope);
|
MarkScopeLeft(breakData->mScope);
|
||||||
ValueScopeEnd(earliestValueScopeStart);
|
ValueScopeEnd(earliestValueScopeStart);
|
||||||
|
|
||||||
|
@ -5734,11 +5757,18 @@ void BfModule::Visit(BfRepeatStatement* repeatStmt)
|
||||||
|
|
||||||
mBfIRBuilder->CreateBr(bodyBB);
|
mBfIRBuilder->CreateBr(bodyBB);
|
||||||
mBfIRBuilder->SetInsertPoint(bodyBB);
|
mBfIRBuilder->SetInsertPoint(bodyBB);
|
||||||
scopeData.mIsLoop = true;
|
scopeData.mIsLoop = true;
|
||||||
VisitEmbeddedStatement(repeatStmt->mEmbeddedStatement);
|
|
||||||
|
BfDeferredLocalAssignData deferredLocalAssignData(mCurMethodState->mCurScope);
|
||||||
|
deferredLocalAssignData.ExtendFrom(mCurMethodState->mDeferredLocalAssignData, false);
|
||||||
|
deferredLocalAssignData.mVarIdBarrier = mCurMethodState->GetRootMethodState()->mCurLocalVarId;
|
||||||
|
SetAndRestoreValue<BfDeferredLocalAssignData*> prevDLA(mCurMethodState->mDeferredLocalAssignData, &deferredLocalAssignData);
|
||||||
|
|
||||||
|
VisitEmbeddedStatement(repeatStmt->mEmbeddedStatement);
|
||||||
|
|
||||||
if (!mCurMethodState->mLeftBlockUncond)
|
if (!mCurMethodState->mLeftBlockUncond)
|
||||||
mBfIRBuilder->CreateBr(condBB);
|
mBfIRBuilder->CreateBr(condBB);
|
||||||
mCurMethodState->SetHadReturn(false);
|
mCurMethodState->SetHadReturn(false);
|
||||||
mCurMethodState->mLeftBlockUncond = false;
|
mCurMethodState->mLeftBlockUncond = false;
|
||||||
mCurMethodState->mLeftBlockCond = false;
|
mCurMethodState->mLeftBlockCond = false;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue