1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 12:32:20 +02:00

Const lhs handling of ??, cond var assignment in CreateConditionalScope

This commit is contained in:
Brian Fiete 2022-02-16 08:28:05 -05:00
parent 4c499cc498
commit ae53196e74
5 changed files with 65 additions and 11 deletions

View file

@ -324,5 +324,23 @@ namespace IDETest
}
}
public void Local7()
{
int a = 1;
int b;
int c;
int d;
if ((a == 1) && ({b = 2; if (a == 1) {c = 1;} a == 1}))
{
int a2 = a;
int b2 = b;
int c2 = c; //FAIL
}
int a3 = a;
int b3 = b; //FAIL
int c3 = c; //FAIL
}
}
}

View file

@ -21360,13 +21360,10 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
auto rhsBB = mModule->mBfIRBuilder->CreateBlock("land.rhs");
auto endBB = mModule->mBfIRBuilder->CreateBlock("land.end");
// This makes any 'scope' allocs be dyn since we aren't sure if this will be short-circuited
SetAndRestoreValue<bool> prevIsConditional(mModule->mCurMethodState->mCurScope->mIsConditional, true);
mModule->mBfIRBuilder->CreateCondBr(leftValue.mValue, rhsBB, endBB);
mModule->AddBasicBlock(rhsBB);
rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_CreateConditionalScope));
mModule->mBfIRBuilder->CreateBr(endBB);
auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
@ -21472,6 +21469,22 @@ bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken,
{
leftValue = mModule->LoadValue(leftValue);
if (leftValue.mValue.IsConst())
{
auto constant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
if (constant->IsNull())
{
mResult = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
return true;
}
// Already have a value, we don't need the right side
SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_CreateConditionalScope));
mResult = leftValue;
return true;
}
auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
auto rhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.rhs");
auto endBB = mModule->mBfIRBuilder->CreateBlock("nullc.end");
@ -21488,10 +21501,12 @@ bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken,
mModule->AddBasicBlock(rhsBB);
BfTypedValue rightValue;
if (assignTo != NULL)
rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags)));
rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_CreateConditionalScope));
else
rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_CreateConditionalScope));
if (!rightValue)
{

View file

@ -8621,8 +8621,19 @@ BfTypedValue BfModule::FlushNullConditional(BfTypedValue result, bool ignoreNull
return result;
}
BF_NOINLINE void BfModule::EvaluateWithNewScope(BfExprEvaluator& exprEvaluator, BfExpression* expr, BfEvalExprFlags flags)
BF_NOINLINE void BfModule::EvaluateWithNewConditionalScope(BfExprEvaluator& exprEvaluator, BfExpression* expr, BfEvalExprFlags flags)
{
BfDeferredLocalAssignData deferredLocalAssignData(mCurMethodState->mCurScope);
SetAndRestoreValue<BfDeferredLocalAssignData*> prevDLA(mCurMethodState->mDeferredLocalAssignData);
if (mCurMethodState != NULL)
{
deferredLocalAssignData.mIsIfCondition = true;
deferredLocalAssignData.mIfMayBeSkipped = true;
deferredLocalAssignData.ExtendFrom(mCurMethodState->mDeferredLocalAssignData, false);
deferredLocalAssignData.mVarIdBarrier = mCurMethodState->GetRootMethodState()->mCurLocalVarId;
mCurMethodState->mDeferredLocalAssignData = &deferredLocalAssignData;
}
BfScopeData newScope;
newScope.mOuterIsConditional = true;
newScope.mAllowTargeting = false;
@ -8630,9 +8641,11 @@ BF_NOINLINE void BfModule::EvaluateWithNewScope(BfExprEvaluator& exprEvaluator,
{
mCurMethodState->AddScope(&newScope);
NewScopeState(true, false);
}
}
exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | flags);
exprEvaluator.Evaluate(expr, (flags & BfEvalExprFlags_PropogateNullConditional) != 0, (flags & BfEvalExprFlags_IgnoreNullConditional) != 0, (flags & BfEvalExprFlags_AllowSplat) != 0);
if (mCurMethodState != NULL)
RestoreScopeState();
}
@ -8669,7 +8682,15 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator,
if ((flags & BfEvalExprFlags_CreateConditionalScope) != 0)
{
EvaluateWithNewScope(exprEvaluator, expr, flags);
if ((mCurMethodState == NULL) || (mCurMethodState->mCurScope->mScopeKind != BfScopeKind_StatementTarget_Conditional))
{
EvaluateWithNewConditionalScope(exprEvaluator, expr, flags);
}
else
{
SetAndRestoreValue<bool> prevIsConditional(mCurMethodState->mCurScope->mIsConditional, true);
exprEvaluator.Evaluate(expr, (flags & BfEvalExprFlags_PropogateNullConditional) != 0, (flags & BfEvalExprFlags_IgnoreNullConditional) != 0, true);
}
}
else
exprEvaluator.Evaluate(expr, (flags & BfEvalExprFlags_PropogateNullConditional) != 0, (flags & BfEvalExprFlags_IgnoreNullConditional) != 0, true);

View file

@ -1942,7 +1942,7 @@ public:
BfIRFunction GetIntrinsic(BfMethodInstance* methodInstance, bool reportFailure = false);
BfIRFunction GetBuiltInFunc(BfBuiltInFuncType funcType);
BfIRValue CreateFunctionFrom(BfMethodInstance* methodInstance, bool tryExisting, bool isInlined);
void EvaluateWithNewScope(BfExprEvaluator& exprEvaluator, BfExpression* expr, BfEvalExprFlags flags);
void EvaluateWithNewConditionalScope(BfExprEvaluator& exprEvaluator, BfExpression* expr, BfEvalExprFlags flags);
BfTypedValue CreateValueFromExpression(BfExprEvaluator& exprEvaluator, BfExpression* expr, BfType* wantTypeRef = NULL, BfEvalExprFlags flags = BfEvalExprFlags_None, BfType** outOrigType = NULL);
BfTypedValue CreateValueFromExpression(BfExpression* expr, BfType* wantTypeRef = NULL, BfEvalExprFlags flags = BfEvalExprFlags_None, BfType** outOrigType = NULL);
BfTypedValue GetOrCreateVarAddr(BfExpression* expr);

View file

@ -3667,7 +3667,7 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i
UpdateSrcPos(ifStmt);
BfScopeData newScope;
newScope.mOuterIsConditional = true;
newScope.mOuterIsConditional = true;
newScope.mScopeKind = BfScopeKind_StatementTarget;
if (ifStmt->mLabelNode != NULL)
newScope.mLabelNode = ifStmt->mLabelNode->mLabel;