From 8cccec20fa6e08cb4e140cc2eefbdafd20b4def0 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sat, 29 Jan 2022 14:29:25 -0500 Subject: [PATCH] Properly throw error on capture specifier in non-lambda allocation --- IDEHelper/Compiler/BfExprEvaluator.cpp | 38 ++++++++++++++------------ IDEHelper/Compiler/BfExprEvaluator.h | 2 +- IDEHelper/Compiler/BfModule.cpp | 2 +- IDEHelper/Compiler/BfModule.h | 3 +- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 42989005..3e850418 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -3760,7 +3760,8 @@ void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolation auto stringType = mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef)->ToTypeInstance(); BfTokenNode* newToken = NULL; - BfAllocTarget allocTarget = ResolveAllocTarget(stringInterpolationExpression->mAllocNode, newToken); + BfAllocTarget allocTarget; + ResolveAllocTarget(allocTarget, stringInterpolationExpression->mAllocNode, newToken); CreateObject(NULL, stringInterpolationExpression->mAllocNode, stringType); BfTypedValue newString = mResult; @@ -11911,7 +11912,8 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) } BfTokenNode* newToken = NULL; - BfAllocTarget allocTarget = ResolveAllocTarget(delegateBindExpr->mNewToken, newToken); + BfAllocTarget allocTarget; + ResolveAllocTarget(allocTarget, delegateBindExpr->mNewToken, newToken); SizedArray typedValueExprs; SizedArray args; @@ -12987,7 +12989,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam auto varMethodState = methodState.mPrevMethodState; bool hasExplicitCaptureNames = false; - for (auto& captureEntry : allocTarget.mCaptureInfo.mCaptures) + for (auto& captureEntry : allocTarget.mCaptureInfo->mCaptures) { if (captureEntry.mNameNode == NULL) { @@ -13029,7 +13031,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam auto varMethodState = methodState.mPrevMethodState; while (varMethodState != NULL) { - for (auto& captureEntry : allocTarget.mCaptureInfo.mCaptures) + for (auto& captureEntry : allocTarget.mCaptureInfo->mCaptures) { if (captureEntry.mNameNode != NULL) { @@ -13134,10 +13136,10 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam auto _GetCaptureType = [&](const StringImpl& str) { - if (allocTarget.mCaptureInfo.mCaptures.IsEmpty()) + if (allocTarget.mCaptureInfo->mCaptures.IsEmpty()) return BfCaptureType_Copy; - for (auto& captureEntry : allocTarget.mCaptureInfo.mCaptures) + for (auto& captureEntry : allocTarget.mCaptureInfo->mCaptures) { if ((captureEntry.mNameNode == NULL) || (captureEntry.mNameNode->Equals(str))) { @@ -13274,7 +13276,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam } } - for (auto& captureEntry : allocTarget.mCaptureInfo.mCaptures) + for (auto& captureEntry : allocTarget.mCaptureInfo->mCaptures) { if ((!captureEntry.mUsed) && (captureEntry.mNameNode != NULL)) mModule->Warn(0, "Capture specifier not used", captureEntry.mNameNode); @@ -13658,7 +13660,10 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr) { BfTokenNode* newToken = NULL; - BfAllocTarget allocTarget = ResolveAllocTarget(lambdaBindExpr->mNewToken, newToken); + BfCaptureInfo captureInfo; + BfAllocTarget allocTarget; + allocTarget.mCaptureInfo = &captureInfo; + ResolveAllocTarget(allocTarget, lambdaBindExpr->mNewToken, newToken); if (mModule->mCurMethodInstance == NULL) mModule->Fail("Invalid use of lambda bind expression", lambdaBindExpr); @@ -13957,7 +13962,8 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs attributeState.mTarget = BfAttributeTargets_Alloc; SetAndRestoreValue prevAttributeState(mModule->mAttributeState, &attributeState); BfTokenNode* newToken = NULL; - BfAllocTarget allocTarget = ResolveAllocTarget(allocNode, newToken, &attributeState.mCustomAttributes); + BfAllocTarget allocTarget; + ResolveAllocTarget(allocTarget, allocNode, newToken, &attributeState.mCustomAttributes); bool isScopeAlloc = newToken->GetToken() == BfToken_Scope; bool isAppendAlloc = newToken->GetToken() == BfToken_Append; @@ -14982,7 +14988,8 @@ void BfExprEvaluator::Visit(BfBoxExpression* boxExpr) }*/ BfTokenNode* newToken = NULL; - BfAllocTarget allocTarget = ResolveAllocTarget(boxExpr->mAllocNode, newToken); + BfAllocTarget allocTarget; + ResolveAllocTarget(allocTarget, boxExpr->mAllocNode, newToken); if ((boxExpr->mAllocNode != NULL) && (boxExpr->mAllocNode->mToken == BfToken_Scope)) { @@ -15048,12 +15055,11 @@ void BfExprEvaluator::Visit(BfBoxExpression* boxExpr) } } -BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenNode*& newToken, BfCustomAttributes** outCustomAttributes) +void BfExprEvaluator::ResolveAllocTarget(BfAllocTarget& allocTarget, BfAstNode* allocNode, BfTokenNode*& newToken, BfCustomAttributes** outCustomAttributes) { auto autoComplete = GetAutoComplete(); BfAttributeDirective* attributeDirective = NULL; - - BfAllocTarget allocTarget; + allocTarget.mRefNode = allocNode; newToken = BfNodeDynCast(allocNode); if (newToken == NULL) @@ -15099,7 +15105,7 @@ BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenN if (attributeDirective != NULL) { - auto customAttrs = mModule->GetCustomAttributes(attributeDirective, BfAttributeTargets_Alloc, BfGetCustomAttributesFlags_AllowNonConstArgs, &allocTarget.mCaptureInfo); + auto customAttrs = mModule->GetCustomAttributes(attributeDirective, BfAttributeTargets_Alloc, BfGetCustomAttributesFlags_AllowNonConstArgs, allocTarget.mCaptureInfo); if (customAttrs != NULL) { for (auto& attrib : customAttrs->mAttributes) @@ -15131,9 +15137,7 @@ BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenN else delete customAttrs; } - } - - return allocTarget; + } } BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedValue target) diff --git a/IDEHelper/Compiler/BfExprEvaluator.h b/IDEHelper/Compiler/BfExprEvaluator.h index 1100f440..93d3a70f 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.h +++ b/IDEHelper/Compiler/BfExprEvaluator.h @@ -418,7 +418,7 @@ public: BfType* ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); void ResolveGenericType(); void ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveArgsFlags flags = BfResolveArgsFlag_None); - BfAllocTarget ResolveAllocTarget(BfAstNode* newNode, BfTokenNode*& newToken, BfCustomAttributes** outCustomAttributes = NULL); + void ResolveAllocTarget(BfAllocTarget& allocTarget, BfAstNode* newNode, BfTokenNode*& newToken, BfCustomAttributes** outCustomAttributes = NULL); BfTypedValue ResolveArgValue(BfResolvedArg& resolvedArg, BfType* wantType, BfTypedValue* receivingValue = NULL, BfParamKind paramKind = BfParamKind_Normal, BfIdentifierNode* paramNameNode = NULL); BfMethodDef* GetPropertyMethodDef(BfPropertyDef* propDef, BfMethodType methodType, BfCheckedKind checkedKind, BfTypedValue propTarget); BfModuleMethodInstance GetPropertyMethodInstance(BfMethodDef* methodDef); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index aac07347..408fc845 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -11362,7 +11362,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri { if (captureInfo == NULL) { - Fail("Capture specifiers can only be used in lambda allocations", attributesDirective); + Fail("Capture specifiers can only be used in lambda allocations", tokenNode); continue; } diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 77ff9ea6..e6e42d4b 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -600,7 +600,7 @@ public: BfTypedValue mCustomAllocator; BfScopedInvocationTarget* mScopedInvocationTarget; int mAlignOverride; - BfCaptureInfo mCaptureInfo; + BfCaptureInfo* mCaptureInfo; bool mIsFriend; public: @@ -612,6 +612,7 @@ public: mScopedInvocationTarget = NULL; mAlignOverride = -1; mIsFriend = false; + mCaptureInfo = NULL; } BfAllocTarget(BfScopeData* scopeData)