mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fixing ICE on calling externally a function that returns calldata pointers
Co-authored-by: chriseth <chris@ethereum.org>
This commit is contained in:
parent
d2e9b4e946
commit
e73fe17277
@ -2,15 +2,13 @@
|
|||||||
|
|
||||||
Language Features:
|
Language Features:
|
||||||
|
|
||||||
|
|
||||||
Compiler Features:
|
Compiler Features:
|
||||||
* Yul: Raise warning for switch statements that only have a default and no other cases.
|
* Yul: Raise warning for switch statements that only have a default and no other cases.
|
||||||
|
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
* SMTChecker: Fix internal error when encoding tuples of tuples.
|
* SMTChecker: Fix internal error when encoding tuples of tuples.
|
||||||
* SMTChecker: Fix aliasing soundness after pushing to an array pointer.
|
* SMTChecker: Fix aliasing soundness after pushing to an array pointer.
|
||||||
|
* Type system: Fix internal compiler error on calling externally a function that returns variables with calldata location.
|
||||||
|
|
||||||
### 0.6.9 (2020-06-04)
|
### 0.6.9 (2020-06-04)
|
||||||
|
|
||||||
|
@ -112,14 +112,22 @@ public:
|
|||||||
/// @returns a copy of @a _type having the same location as this (and is not a pointer type)
|
/// @returns a copy of @a _type having the same location as this (and is not a pointer type)
|
||||||
/// if _type is a reference type and an unmodified copy of _type otherwise.
|
/// if _type is a reference type and an unmodified copy of _type otherwise.
|
||||||
/// This function is mostly useful to modify inner types appropriately.
|
/// This function is mostly useful to modify inner types appropriately.
|
||||||
static Type const* withLocationIfReference(DataLocation _location, Type const* _type)
|
static Type const* withLocationIfReference(DataLocation _location, Type const* _type, bool _isPointer = false)
|
||||||
{
|
{
|
||||||
if (auto refType = dynamic_cast<ReferenceType const*>(_type))
|
if (auto refType = dynamic_cast<ReferenceType const*>(_type))
|
||||||
return withLocation(refType, _location, false);
|
return withLocation(refType, _location, _isPointer);
|
||||||
|
|
||||||
return _type;
|
return _type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isReferenceWithLocation(Type const* _type, DataLocation _location)
|
||||||
|
{
|
||||||
|
if (auto const* refType = dynamic_cast<ReferenceType const*>(_type))
|
||||||
|
if (refType->location() == _location)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// @returns the internally-facing or externally-facing type of a function or the type of a function declaration.
|
/// @returns the internally-facing or externally-facing type of a function or the type of a function declaration.
|
||||||
static FunctionType const* function(FunctionDefinition const& _function, FunctionType::Kind _kind = FunctionType::Kind::Declaration);
|
static FunctionType const* function(FunctionDefinition const& _function, FunctionType::Kind _kind = FunctionType::Kind::Declaration);
|
||||||
|
|
||||||
|
@ -3445,13 +3445,21 @@ FunctionTypePointer FunctionType::asExternallyCallableFunction(bool _inLibrary,
|
|||||||
|
|
||||||
TypePointers parameterTypes;
|
TypePointers parameterTypes;
|
||||||
for (auto const& t: m_parameterTypes)
|
for (auto const& t: m_parameterTypes)
|
||||||
{
|
if (TypeProvider::isReferenceWithLocation(t, DataLocation::CallData))
|
||||||
auto refType = dynamic_cast<ReferenceType const*>(t);
|
parameterTypes.push_back(
|
||||||
if (refType && refType->location() == DataLocation::CallData)
|
TypeProvider::withLocationIfReference(DataLocation::Memory, t, true)
|
||||||
parameterTypes.push_back(TypeProvider::withLocation(refType, DataLocation::Memory, true));
|
);
|
||||||
else
|
else
|
||||||
parameterTypes.push_back(t);
|
parameterTypes.push_back(t);
|
||||||
}
|
|
||||||
|
TypePointers returnParameterTypes;
|
||||||
|
for (auto const& returnParamType: m_returnParameterTypes)
|
||||||
|
if (TypeProvider::isReferenceWithLocation(returnParamType, DataLocation::CallData))
|
||||||
|
returnParameterTypes.push_back(
|
||||||
|
TypeProvider::withLocationIfReference(DataLocation::Memory, returnParamType, true)
|
||||||
|
);
|
||||||
|
else
|
||||||
|
returnParameterTypes.push_back(returnParamType);
|
||||||
|
|
||||||
Kind kind = m_kind;
|
Kind kind = m_kind;
|
||||||
if (_inLibrary)
|
if (_inLibrary)
|
||||||
@ -3465,7 +3473,7 @@ FunctionTypePointer FunctionType::asExternallyCallableFunction(bool _inLibrary,
|
|||||||
|
|
||||||
return TypeProvider::function(
|
return TypeProvider::function(
|
||||||
parameterTypes,
|
parameterTypes,
|
||||||
m_returnParameterTypes,
|
returnParameterTypes,
|
||||||
m_parameterNames,
|
m_parameterNames,
|
||||||
m_returnParameterNames,
|
m_returnParameterNames,
|
||||||
kind,
|
kind,
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
contract CalldataTest {
|
||||||
|
function test(bytes calldata x) public returns (bytes calldata) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
function tester(bytes calldata x) public returns (byte) {
|
||||||
|
return this.test(x)[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// EVMVersion: >=byzantium
|
||||||
|
// ----
|
||||||
|
// tester(bytes): 0x20, 0x08, "abcdefgh" -> "c"
|
Loading…
Reference in New Issue
Block a user