From 965e2e2930dc52def93c21ad4118a015262642d8 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 21 Sep 2020 17:53:22 -0700 Subject: [PATCH] Moved scope of 'if (Call(var X))' arguments into the if parent's scope --- IDE/Tests/CompileFail001/src/LocalVars.bf | 58 +++++++++++++++++++++++ IDEHelper/Compiler/BfExprEvaluator.cpp | 9 ++++ IDEHelper/Compiler/BfModule.h | 9 ++++ IDEHelper/Compiler/BfStmtEvaluator.cpp | 3 ++ 4 files changed, 79 insertions(+) diff --git a/IDE/Tests/CompileFail001/src/LocalVars.bf b/IDE/Tests/CompileFail001/src/LocalVars.bf index dc4e2e56..07713fdd 100644 --- a/IDE/Tests/CompileFail001/src/LocalVars.bf +++ b/IDE/Tests/CompileFail001/src/LocalVars.bf @@ -228,5 +228,63 @@ namespace IDETest int c = b; //FAIL } } + + public bool GetVal(out int a) + { + a = 1; + return true; + } + + public void Local1() + { + if ((GetVal(var a)) && (GetVal(var b))) + { + int c = a; + int d = b; + } + + int e = a; + int f = b; //FAIL + } + + public void Local2() + { + int a; + int b; + if ((GetVal(out a)) && (GetVal(out b))) + { + int c = a; + int d = b; + } + + int e = a; + int f = b; //FAIL + } + + public void Local3() + { + if ((GetVal(var a)) || (GetVal(var b))) //FAIL + { + int c = a; + int d = b; + } + + int e = a; + int f = b; //FAIL + } + + public void Local4() + { + int a; + int b; + if ((GetVal(out a)) || (GetVal(out b))) + { + int c = a; + int d = b; //FAIL + } + + int e = a; + int f = b; //FAIL + } } } diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 32d498a7..1bae81e1 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -6561,6 +6561,13 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType CheckVariableDeclaration(resolvedArg.mExpression, false, false, false); argValue = BfTypedValue(localVar->mAddr, mModule->CreateRefType(variableType, BfRefType::RefKind_Out)); + + auto curScope = mModule->mCurMethodState->mCurScope; + if (curScope->mScopeKind == BfScopeKind_StatementTarget) + { + // Move this variable into the parent scope + curScope->mLocalVarStart = (int)mModule->mCurMethodState->mLocals.size(); + } } return argValue; } @@ -18589,6 +18596,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp { if (mModule->mCurMethodState->mDeferredLocalAssignData != NULL) mModule->mCurMethodState->mDeferredLocalAssignData->BreakExtendChain(); + if (mModule->mCurMethodState->mCurScope->mScopeKind == BfScopeKind_StatementTarget) + mModule->mCurMethodState->mCurScope->mScopeKind = BfScopeKind_StatementTarget_Conditional; bool isAnd = binaryOp == BfBinaryOp_ConditionalAnd; diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 27b4be18..e7931f9c 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -357,12 +357,20 @@ public: void SetUnion(const BfDeferredLocalAssignData& otherLocalAssignData); }; +enum BfScopeKind +{ + BfScopeKind_Normal, + BfScopeKind_StatementTarget, + BfScopeKind_StatementTarget_Conditional, +}; + // "Looped" means this scope will execute zero to many times, "Conditional" means zero or one. // Looped and Conditional are mutually exclusive. "Dyn" means Looped OR Conditional. class BfScopeData { public: BfScopeData* mPrevScope; + BfScopeKind mScopeKind; BfIRMDNode mDIScope; BfIRMDNode mDIInlinedAt; String mLabel; @@ -399,6 +407,7 @@ public: public: BfScopeData() { + mScopeKind = BfScopeKind_Normal; mPrevScope = NULL; mLocalVarStart = 0; mLabelNode = NULL; diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index d329e16c..7520179b 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -3527,6 +3527,7 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i BfScopeData newScope; newScope.mOuterIsConditional = true; + newScope.mScopeKind = BfScopeKind_StatementTarget; if (ifStmt->mLabelNode != NULL) newScope.mLabelNode = ifStmt->mLabelNode->mLabel; mCurMethodState->AddScope(&newScope); @@ -3548,6 +3549,8 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i BfAutoParentNodeEntry autoParentNodeEntry(this, ifStmt); BfTypedValue condValue = CreateValueFromExpression(ifStmt->mCondition, boolType); + newScope.mScopeKind = BfScopeKind_Normal; + deferredLocalAssignData.mIsIfCondition = false; // The "extend chain" is only valid for the conditional -- since that expression may contain unconditionally executed and