mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix accessing memory reference types in yul codegen and clean up on memory reads.
This commit is contained in:
parent
4c1e821e01
commit
c25a3eba14
@ -2245,7 +2245,6 @@ string YulUtilFunctions::readFromMemoryOrCalldata(Type const& _type, bool _fromC
|
|||||||
}
|
}
|
||||||
|
|
||||||
solAssert(_type.isValueType(), "");
|
solAssert(_type.isValueType(), "");
|
||||||
|
|
||||||
if (auto const* funType = dynamic_cast<FunctionType const*>(&_type))
|
if (auto const* funType = dynamic_cast<FunctionType const*>(&_type))
|
||||||
if (funType->kind() == FunctionType::Kind::External)
|
if (funType->kind() == FunctionType::Kind::External)
|
||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
@ -2259,18 +2258,23 @@ string YulUtilFunctions::readFromMemoryOrCalldata(Type const& _type, bool _fromC
|
|||||||
("splitFunction", splitExternalFunctionIdFunction())
|
("splitFunction", splitExternalFunctionIdFunction())
|
||||||
.render();
|
.render();
|
||||||
|
|
||||||
|
|
||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(memPtr) -> value {
|
function <functionName>(ptr) -> value {
|
||||||
value := <load>(memPtr)
|
<?fromCalldata>
|
||||||
<?needsValidation>
|
value := calldataload(ptr)
|
||||||
<validate>(value)
|
<validate>(value)
|
||||||
</needsValidation>
|
<!fromCalldata>
|
||||||
|
value := <cleanup>(mload(ptr))
|
||||||
|
</fromCalldata>
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("load", _fromCalldata ? "calldataload" : "mload")
|
("fromCalldata", _fromCalldata)
|
||||||
("needsValidation", _fromCalldata)
|
("validate", validatorFunction(_type))
|
||||||
("validate", _fromCalldata ? validatorFunction(_type) : "")
|
// Byte array elements generally need cleanup.
|
||||||
|
// Other types are cleaned as well to account for dirty memory e.g. due to inline assembly.
|
||||||
|
("cleanup", cleanupFunction(_type))
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ public:
|
|||||||
std::string readFromStorage(Type const& _type, size_t _offset, bool _splitFunctionTypes);
|
std::string readFromStorage(Type const& _type, size_t _offset, bool _splitFunctionTypes);
|
||||||
std::string readFromStorageDynamic(Type const& _type, bool _splitFunctionTypes);
|
std::string readFromStorageDynamic(Type const& _type, bool _splitFunctionTypes);
|
||||||
|
|
||||||
/// @returns a function that reads a value type from memory.
|
/// @returns a function that reads a value type from memory. Performs cleanup.
|
||||||
/// signature: (addr) -> value
|
/// signature: (addr) -> value
|
||||||
std::string readFromMemory(Type const& _type);
|
std::string readFromMemory(Type const& _type);
|
||||||
/// @returns a function that reads a value type from calldata.
|
/// @returns a function that reads a value type from calldata.
|
||||||
|
@ -117,10 +117,12 @@ struct CopyTranslate: public yul::ASTCopier
|
|||||||
reference.isOffset == false && reference.isSlot == false,
|
reference.isOffset == false && reference.isSlot == false,
|
||||||
"Should not be called for offset/slot"
|
"Should not be called for offset/slot"
|
||||||
);
|
);
|
||||||
|
auto const& var = m_context.localVariable(*varDecl);
|
||||||
|
solAssert(var.type().sizeOnStack() == 1, "");
|
||||||
|
|
||||||
return yul::Identifier{
|
return yul::Identifier{
|
||||||
_identifier.location,
|
_identifier.location,
|
||||||
yul::YulString{m_context.localVariable(*varDecl).name()}
|
yul::YulString{var.commaSeparatedList()}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2060,13 +2062,7 @@ IRVariable IRGeneratorForStatements::readFromLValue(IRLValue const& _lvalue)
|
|||||||
")\n";
|
")\n";
|
||||||
},
|
},
|
||||||
[&](IRLValue::Memory const& _memory) {
|
[&](IRLValue::Memory const& _memory) {
|
||||||
if (_memory.byteArrayElement)
|
if (_lvalue.type.isValueType())
|
||||||
define(result) <<
|
|
||||||
m_utils.cleanupFunction(_lvalue.type) <<
|
|
||||||
"(mload(" <<
|
|
||||||
_memory.address <<
|
|
||||||
"))\n";
|
|
||||||
else if (_lvalue.type.isValueType())
|
|
||||||
define(result) <<
|
define(result) <<
|
||||||
m_utils.readFromMemory(_lvalue.type) <<
|
m_utils.readFromMemory(_lvalue.type) <<
|
||||||
"(" <<
|
"(" <<
|
||||||
|
15
test/libsolidity/semanticTests/viaYul/dirty_memory_read.sol
Normal file
15
test/libsolidity/semanticTests/viaYul/dirty_memory_read.sol
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
contract C {
|
||||||
|
function f() public pure returns (uint8 x, bool a, bool b) {
|
||||||
|
uint8[1] memory m;
|
||||||
|
assembly {
|
||||||
|
mstore(m, 257)
|
||||||
|
}
|
||||||
|
x = m[0];
|
||||||
|
a = (m[0] == 0x01);
|
||||||
|
b = (m[0] == 0x0101);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
|
// ----
|
||||||
|
// f() -> 1, true, false
|
Loading…
Reference in New Issue
Block a user