| 4341 | } |
| 4342 | |
| 4343 | void TypeChecker::requireLValue(Expression const& _expression) |
| 4344 | { |
| 4345 | _expression.annotation().willBeWrittenTo = true; |
| 4346 | _expression.accept(*this); |
| 4347 | |
| 4348 | if (*_expression.annotation().isLValue) |
| 4349 | return; |
| 4350 | |
| 4351 | auto [errorId, description] = [&]() -> std::tuple<ErrorId, std::string> { |
| 4352 | if (*_expression.annotation().isConstant) |
| 4353 | return { 6520_error, "Cannot assign to a constant variable." }; |
| 4354 | |
| 4355 | if (auto indexAccess = dynamic_cast<IndexAccess const*>(&_expression)) |
| 4356 | { |
| 4357 | if (type(indexAccess->baseExpression())->category() == Type::Category::FixedBytes) |
| 4358 | return { 4360_error, "Single bytes in fixed bytes arrays cannot be modified." }; |
| 4359 | else if (auto arrayType = dynamic_cast<ArrayType const*>(type(indexAccess->baseExpression()))) |
| 4360 | if (arrayType->dataStoredIn(DataLocation::CallData)) |
| 4361 | return { 6182_error, "Calldata arrays are read-only." }; |
| 4362 | } |
| 4363 | |
| 4364 | if (auto memberAccess = dynamic_cast<MemberAccess const*>(&_expression)) |
| 4365 | { |
| 4366 | if (auto structType = dynamic_cast<StructType const*>(type(memberAccess->expression()))) |
| 4367 | { |
| 4368 | if (structType->dataStoredIn(DataLocation::CallData)) |
| 4369 | return { 4156_error, "Calldata structs are read-only." }; |
| 4370 | } |
| 4371 | else if (dynamic_cast<ArrayType const*>(type(memberAccess->expression()))) |
| 4372 | if (memberAccess->memberName() == "length") |
| 4373 | return { 7567_error, "Member \"length\" is read-only and cannot be used to resize arrays." }; |
| 4374 | } |
| 4375 | |
| 4376 | if (auto identifier = dynamic_cast<Identifier const*>(&_expression)) |
| 4377 | if (auto varDecl = dynamic_cast<VariableDeclaration const*>(identifier->annotation().referencedDeclaration)) |
| 4378 | if (varDecl->isExternalCallableParameter() && dynamic_cast<ReferenceType const*>(identifier->annotation().type)) |
| 4379 | return { 7128_error, "External function arguments of reference type are read-only." }; |
| 4380 | |
| 4381 | return { 4247_error, "Expression has to be an lvalue." }; |
| 4382 | }(); |
| 4383 | |
| 4384 | m_errorReporter.typeError(errorId, _expression.location(), description); |
| 4385 | } |
| 4386 | |
| 4387 | bool TypeChecker::useABICoderV2() const |
| 4388 | { |
nothing calls this directly
no test coverage detected