mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #3549 from ethereum/fixmultidim
Properly detect which array and struct types are unsupported by the old ABI encoder.
This commit is contained in:
commit
83dacbf669
@ -22,6 +22,7 @@ Bugfixes:
|
|||||||
* Standalone Assembly: Do not ignore input after closing brace of top level block.
|
* Standalone Assembly: Do not ignore input after closing brace of top level block.
|
||||||
* Standard JSON: Catch errors properly when invalid "sources" are passed.
|
* Standard JSON: Catch errors properly when invalid "sources" are passed.
|
||||||
* Standard JSON: Ensure that library addresses supplied are of correct length and hex prefixed.
|
* Standard JSON: Ensure that library addresses supplied are of correct length and hex prefixed.
|
||||||
|
* Type Checker: Properly detect which array and struct types are unsupported by the old ABI encoder.
|
||||||
* Type Checker: Properly warn when using ``_offset`` and ``_slot`` for constants in inline assembly.
|
* Type Checker: Properly warn when using ``_offset`` and ``_slot`` for constants in inline assembly.
|
||||||
* Commandline interface: throw error if option is unknown
|
* Commandline interface: throw error if option is unknown
|
||||||
|
|
||||||
|
@ -34,6 +34,29 @@ using namespace std;
|
|||||||
using namespace dev;
|
using namespace dev;
|
||||||
using namespace dev::solidity;
|
using namespace dev::solidity;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
bool typeSupportedByOldABIEncoder(Type const& _type)
|
||||||
|
{
|
||||||
|
if (_type.dataStoredIn(DataLocation::Storage))
|
||||||
|
return true;
|
||||||
|
else if (_type.category() == Type::Category::Struct)
|
||||||
|
return false;
|
||||||
|
else if (_type.category() == Type::Category::Array)
|
||||||
|
{
|
||||||
|
auto const& arrayType = dynamic_cast<ArrayType const&>(_type);
|
||||||
|
auto base = arrayType.baseType();
|
||||||
|
if (!typeSupportedByOldABIEncoder(*base))
|
||||||
|
return false;
|
||||||
|
else if (base->category() == Type::Category::Array && base->isDynamicallySized())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool TypeChecker::checkTypeRequirements(ASTNode const& _contract)
|
bool TypeChecker::checkTypeRequirements(ASTNode const& _contract)
|
||||||
{
|
{
|
||||||
@ -561,13 +584,12 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
|
|||||||
m_errorReporter.fatalTypeError(var->location(), "Internal or recursive type is not allowed for public or external functions.");
|
m_errorReporter.fatalTypeError(var->location(), "Internal or recursive type is not allowed for public or external functions.");
|
||||||
if (
|
if (
|
||||||
_function.visibility() > FunctionDefinition::Visibility::Internal &&
|
_function.visibility() > FunctionDefinition::Visibility::Internal &&
|
||||||
type(*var)->category() == Type::Category::Struct &&
|
!_function.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::ABIEncoderV2) &&
|
||||||
!type(*var)->dataStoredIn(DataLocation::Storage) &&
|
!typeSupportedByOldABIEncoder(*type(*var))
|
||||||
!_function.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::ABIEncoderV2)
|
|
||||||
)
|
)
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
var->location(),
|
var->location(),
|
||||||
"Structs are only supported in the new experimental ABI encoder. "
|
"This type is only supported in the new experimental ABI encoder. "
|
||||||
"Use \"pragma experimental ABIEncoderV2;\" to enable the feature."
|
"Use \"pragma experimental ABIEncoderV2;\" to enable the feature."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1589,8 +1589,6 @@ bool ArrayType::canBeUsedExternally(bool _inLibrary) const
|
|||||||
return true;
|
return true;
|
||||||
else if (!m_baseType->canBeUsedExternally(_inLibrary))
|
else if (!m_baseType->canBeUsedExternally(_inLibrary))
|
||||||
return false;
|
return false;
|
||||||
else if (m_baseType->category() == Category::Array && m_baseType->isDynamicallySized())
|
|
||||||
return false;
|
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -978,6 +978,62 @@ BOOST_AUTO_TEST_CASE(functions_with_stucts_of_non_external_types_in_interface_ne
|
|||||||
CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions.");
|
CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(returning_multi_dimensional_arrays_new_abi)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
function f() public pure returns (string[][]) {}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_WARNING(text, "Experimental features");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(returning_multi_dimensional_arrays)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract C {
|
||||||
|
function f() public pure returns (string[][]) {}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_ERROR(text, TypeError, "only supported in the new experimental ABI encoder");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(returning_multi_dimensional_static_arrays)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract C {
|
||||||
|
function f() public pure returns (uint[][2]) {}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_ERROR(text, TypeError, "only supported in the new experimental ABI encoder");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(returning_arrays_in_structs_new_abi)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
struct S { string[] s; }
|
||||||
|
function f() public pure returns (S) {}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_WARNING(text, "Experimental features");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(returning_arrays_in_structs_arrays)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract C {
|
||||||
|
struct S { string[] s; }
|
||||||
|
function f() public pure returns (S x) {}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_ERROR(text, TypeError, "only supported in the new experimental ABI encoder");
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(function_external_call_allowed_conversion)
|
BOOST_AUTO_TEST_CASE(function_external_call_allowed_conversion)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
|
Loading…
Reference in New Issue
Block a user