mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Const lhs handling of ??, cond var assignment in CreateConditionalScope
This commit is contained in:
parent
4c499cc498
commit
ae53196e74
5 changed files with 65 additions and 11 deletions
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue