| 20320 | } |
| 20321 | |
| 20322 | bool BfExprEvaluator::CheckModifyResult(BfTypedValue& typedVal, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut, bool emitWarning, bool skipCopyOnMutate) |
| 20323 | { |
| 20324 | if (typedVal.mType->IsVar()) |
| 20325 | { |
| 20326 | // Allow without error |
| 20327 | return true; |
| 20328 | } |
| 20329 | |
| 20330 | BfLocalVariable* localVar = NULL; |
| 20331 | bool isCapturedLocal = false; |
| 20332 | if (mResultLocalVar != NULL) |
| 20333 | { |
| 20334 | localVar = mResultLocalVar; |
| 20335 | localVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++; |
| 20336 | } |
| 20337 | else if (typedVal.IsThis()) |
| 20338 | { |
| 20339 | localVar = mModule->GetThisVariable(); |
| 20340 | } |
| 20341 | else if (typedVal.IsSplat()) |
| 20342 | { |
| 20343 | for (auto checkLocal : mModule->mCurMethodState->mLocals) |
| 20344 | { |
| 20345 | if (checkLocal->mAddr == typedVal.mValue) |
| 20346 | { |
| 20347 | localVar = checkLocal; |
| 20348 | break; |
| 20349 | } |
| 20350 | } |
| 20351 | } |
| 20352 | else if (typedVal.mValue.IsArg()) |
| 20353 | { |
| 20354 | auto methodState = mModule->mCurMethodState->GetNonCaptureState(); |
| 20355 | localVar = methodState->mLocals[typedVal.mValue.mId]; |
| 20356 | } |
| 20357 | |
| 20358 | if ((typedVal.mKind == BfTypedValueKind_MutableValue) && (onlyNeedsMut)) |
| 20359 | { |
| 20360 | return true; |
| 20361 | } |
| 20362 | |
| 20363 | bool canModify = typedVal.CanModify(); |
| 20364 | if (((typedVal.mKind == BfTypedValueKind_TempAddr) || (typedVal.mKind == BfTypedValueKind_CopyOnMutateAddr_Derived)) && |
| 20365 | (strcmp(modifyType, "assign to") == 0)) |
| 20366 | mModule->Warn(0, "Assigning to temporary copy of a value. Consider using 'ref' in value source declaration.", refNode); |
| 20367 | |
| 20368 | auto _Fail = [&](const StringImpl& error, BfAstNode* refNode) |
| 20369 | { |
| 20370 | if (emitWarning) |
| 20371 | return mModule->Warn(BfWarning_BF4204_AddressOfReadOnly, error, refNode); |
| 20372 | else |
| 20373 | return mModule->Fail(error, refNode); |
| 20374 | }; |
| 20375 | |
| 20376 | if (localVar != NULL) |
| 20377 | { |
| 20378 | if (!canModify) |
| 20379 | { |
nothing calls this directly
no test coverage detected