Browse Source

Merge pull request #1092 from LefterisJP/sol_BugOverrideFunctionByteArrayParam

Bugfix for functions override
cl-refactor
chriseth 10 years ago
parent
commit
45ab83ce76
  1. 19
      libsolidity/AST.cpp
  2. 2
      libsolidity/AST.h
  3. 8
      libsolidity/NameAndTypeResolver.cpp
  4. 13
      test/SolidityNameAndTypeResolution.cpp

19
libsolidity/AST.cpp

@ -274,15 +274,6 @@ TypePointer FunctionDefinition::getType(ContractDefinition const*) const
void FunctionDefinition::checkTypeRequirements() void FunctionDefinition::checkTypeRequirements()
{ {
// change all byte arrays parameters to point to calldata
if (getVisibility() == Visibility::External)
for (ASTPointer<VariableDeclaration> const& var: getParameters())
{
auto const& type = var->getType();
solAssert(!!type, "");
if (auto const* byteArrayType = dynamic_cast<ByteArrayType const*>(type.get()))
var->setType(byteArrayType->copyForLocation(ByteArrayType::Location::CallData));
}
for (ASTPointer<VariableDeclaration> const& var: getParameters() + getReturnParameters()) for (ASTPointer<VariableDeclaration> const& var: getParameters() + getReturnParameters())
if (!var->getType()->canLiveOutsideStorage()) if (!var->getType()->canLiveOutsideStorage())
BOOST_THROW_EXCEPTION(var->createTypeError("Type is required to live outside storage.")); BOOST_THROW_EXCEPTION(var->createTypeError("Type is required to live outside storage."));
@ -299,16 +290,14 @@ string FunctionDefinition::getCanonicalSignature() const
bool VariableDeclaration::isLValue() const bool VariableDeclaration::isLValue() const
{ {
if (auto const* function = dynamic_cast<FunctionDefinition const*>(getScope())) // External function parameters are Read-Only
if (function->getVisibility() == Declaration::Visibility::External && isFunctionParameter()) return !isExternalFunctionParameter();
return false;
return true;
} }
bool VariableDeclaration::isFunctionParameter() const bool VariableDeclaration::isExternalFunctionParameter() const
{ {
auto const* function = dynamic_cast<FunctionDefinition const*>(getScope()); auto const* function = dynamic_cast<FunctionDefinition const*>(getScope());
if (!function) if (!function || function->getVisibility() != Declaration::Visibility::External)
return false; return false;
for (auto const& variable: function->getParameters()) for (auto const& variable: function->getParameters())
if (variable.get() == this) if (variable.get() == this)

2
libsolidity/AST.h

@ -448,7 +448,7 @@ public:
virtual bool isLValue() const override; virtual bool isLValue() const override;
bool isLocalVariable() const { return !!dynamic_cast<FunctionDefinition const*>(getScope()); } bool isLocalVariable() const { return !!dynamic_cast<FunctionDefinition const*>(getScope()); }
bool isFunctionParameter() const; bool isExternalFunctionParameter() const;
bool isStateVariable() const { return m_isStateVariable; } bool isStateVariable() const { return m_isStateVariable; }
bool isIndexed() const { return m_isIndexed; } bool isIndexed() const { return m_isIndexed; }

8
libsolidity/NameAndTypeResolver.cpp

@ -333,7 +333,13 @@ void ReferencesResolver::endVisit(VariableDeclaration& _variable)
// or mapping // or mapping
if (_variable.getTypeName()) if (_variable.getTypeName())
{ {
_variable.setType(_variable.getTypeName()->toType()); TypePointer type = _variable.getTypeName()->toType();
// All byte array parameter types should point to call data
if (_variable.isExternalFunctionParameter())
if (auto const* byteArrayType = dynamic_cast<ByteArrayType const*>(type.get()))
type = byteArrayType->copyForLocation(ByteArrayType::Location::CallData);
_variable.setType(type);
if (!_variable.getType()) if (!_variable.getType())
BOOST_THROW_EXCEPTION(_variable.getTypeName()->createTypeError("Invalid type name")); BOOST_THROW_EXCEPTION(_variable.getTypeName()->createTypeError("Invalid type name"));
} }

13
test/SolidityNameAndTypeResolution.cpp

@ -1163,6 +1163,19 @@ BOOST_AUTO_TEST_CASE(external_argument_delete)
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
} }
BOOST_AUTO_TEST_CASE(test_for_bug_override_function_with_bytearray_type)
{
char const* sourceCode = R"(
contract Vehicle {
function f(bytes _a) external returns (uint256 r) {r = 1;}
}
contract Bike is Vehicle {
function f(bytes _a) external returns (uint256 r) {r = 42;}
}
)";
BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(sourceCode));
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

Loading…
Cancel
Save