Browse Source

Fix for Contract and Enum types as external function arguments.

cl-refactor
chriseth 10 years ago
parent
commit
3146a7aeb7
  1. 11
      libsolidity/AST.h
  2. 8
      libsolidity/Types.cpp
  3. 29
      libsolidity/Types.h
  4. 19
      test/libsolidity/SolidityEndToEndTest.cpp

11
libsolidity/AST.h

@ -143,8 +143,8 @@ public:
ASTString const& getName() const { return *m_name; } ASTString const& getName() const { return *m_name; }
Visibility getVisibility() const { return m_visibility == Visibility::Default ? getDefaultVisibility() : m_visibility; } Visibility getVisibility() const { return m_visibility == Visibility::Default ? getDefaultVisibility() : m_visibility; }
bool isPublic() const { return getVisibility() >= Visibility::Public; } bool isPublic() const { return getVisibility() >= Visibility::Public; }
bool isVisibleInContract() const { return getVisibility() != Visibility::External; } virtual bool isVisibleInContract() const { return getVisibility() != Visibility::External; }
virtual bool isVisibleInDerivedContracts() const { return isVisibleInContract() && getVisibility() >= Visibility::Internal; } bool isVisibleInDerivedContracts() const { return isVisibleInContract() && getVisibility() >= Visibility::Internal; }
/// @returns the scope this declaration resides in. Can be nullptr if it is the global scope. /// @returns the scope this declaration resides in. Can be nullptr if it is the global scope.
/// Available only after name and type resolution step. /// Available only after name and type resolution step.
@ -156,7 +156,7 @@ public:
/// contract types. /// contract types.
virtual TypePointer getType(ContractDefinition const* m_currentContract = nullptr) const = 0; virtual TypePointer getType(ContractDefinition const* m_currentContract = nullptr) const = 0;
virtual bool isLValue() const { return false; } virtual bool isLValue() const { return false; }
virtual bool isPartOfExternalInterface() const { return false; }; virtual bool isPartOfExternalInterface() const { return false; }
protected: protected:
virtual Visibility getDefaultVisibility() const { return Visibility::Public; } virtual Visibility getDefaultVisibility() const { return Visibility::Public; }
@ -437,10 +437,9 @@ public:
ASTPointer<ParameterList> const& getReturnParameterList() const { return m_returnParameters; } ASTPointer<ParameterList> const& getReturnParameterList() const { return m_returnParameters; }
Block const& getBody() const { return *m_body; } Block const& getBody() const { return *m_body; }
virtual bool isVisibleInDerivedContracts() const override virtual bool isVisibleInContract() const override
{ {
return !isConstructor() && !getName().empty() && isVisibleInContract() && return Declaration::isVisibleInContract() && !isConstructor() && !getName().empty();
getVisibility() >= Visibility::Internal;
} }
virtual TypePointer getType(ContractDefinition const*) const override; virtual TypePointer getType(ContractDefinition const*) const override;
virtual bool isPartOfExternalInterface() const override { return isPublic() && !m_isConstructor && !getName().empty(); } virtual bool isPartOfExternalInterface() const override { return isPublic() && !m_isConstructor && !getName().empty(); }

8
libsolidity/Types.cpp

@ -1109,7 +1109,7 @@ unsigned FunctionType::getSizeOnStack() const
return size; return size;
} }
TypePointer FunctionType::externalType() const FunctionTypePointer FunctionType::externalFunctionType() const
{ {
TypePointers paramTypes; TypePointers paramTypes;
TypePointers retParamTypes; TypePointers retParamTypes;
@ -1117,13 +1117,13 @@ TypePointer FunctionType::externalType() const
for (auto type: m_parameterTypes) for (auto type: m_parameterTypes)
{ {
if (!type->externalType()) if (!type->externalType())
return TypePointer(); return FunctionTypePointer();
paramTypes.push_back(type->externalType()); paramTypes.push_back(type->externalType());
} }
for (auto type: m_returnParameterTypes) for (auto type: m_returnParameterTypes)
{ {
if (!type->externalType()) if (!type->externalType())
return TypePointer(); return FunctionTypePointer();
retParamTypes.push_back(type->externalType()); retParamTypes.push_back(type->externalType());
} }
return make_shared<FunctionType>(paramTypes, retParamTypes, m_location, m_arbitraryParameters); return make_shared<FunctionType>(paramTypes, retParamTypes, m_location, m_arbitraryParameters);
@ -1168,7 +1168,7 @@ string FunctionType::externalSignature(std::string const& _name) const
} }
string ret = funcName + "("; string ret = funcName + "(";
TypePointers externalParameterTypes = dynamic_cast<FunctionType const&>(*externalType()).getParameterTypes(); TypePointers externalParameterTypes = externalFunctionType()->getParameterTypes();
for (auto it = externalParameterTypes.cbegin(); it != externalParameterTypes.cend(); ++it) for (auto it = externalParameterTypes.cbegin(); it != externalParameterTypes.cend(); ++it)
{ {
solAssert(!!(*it), "Parameter should have external type"); solAssert(!!(*it), "Parameter should have external type");

29
libsolidity/Types.h

@ -404,12 +404,20 @@ public:
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
virtual bool operator==(Type const& _other) const override; virtual bool operator==(Type const& _other) const override;
virtual unsigned getCalldataEncodedSize(bool _padded = true) const override
{
return externalType()->getCalldataEncodedSize(_padded);
}
virtual unsigned getStorageBytes() const override { return 20; } virtual unsigned getStorageBytes() const override { return 20; }
virtual bool canLiveOutsideStorage() const override { return true; }
virtual bool isValueType() const override { return true; } virtual bool isValueType() const override { return true; }
virtual std::string toString() const override; virtual std::string toString() const override;
virtual MemberList const& getMembers() const override; virtual MemberList const& getMembers() const override;
virtual TypePointer externalType() const override { return std::make_shared<IntegerType>(160, IntegerType::Modifier::Address); } virtual TypePointer externalType() const override
{
return std::make_shared<IntegerType>(160, IntegerType::Modifier::Address);
}
bool isSuper() const { return m_super; } bool isSuper() const { return m_super; }
ContractDefinition const& getContractDefinition() const { return m_contract; } ContractDefinition const& getContractDefinition() const { return m_contract; }
@ -472,13 +480,21 @@ public:
explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {} explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {}
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
virtual bool operator==(Type const& _other) const override; virtual bool operator==(Type const& _other) const override;
virtual unsigned getCalldataEncodedSize(bool _padded = true) const override
{
return externalType()->getCalldataEncodedSize(_padded);
}
virtual unsigned getSizeOnStack() const override { return 1; } virtual unsigned getSizeOnStack() const override { return 1; }
virtual unsigned getStorageBytes() const override; virtual unsigned getStorageBytes() const override;
virtual bool canLiveOutsideStorage() const override { return true; }
virtual std::string toString() const override; virtual std::string toString() const override;
virtual bool isValueType() const override { return true; } virtual bool isValueType() const override { return true; }
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
virtual TypePointer externalType() const override { return std::make_shared<IntegerType>(8 * int(getStorageBytes())); } virtual TypePointer externalType() const override
{
return std::make_shared<IntegerType>(8 * int(getStorageBytes()));
}
EnumDefinition const& getEnumDefinition() const { return m_enum; } EnumDefinition const& getEnumDefinition() const { return m_enum; }
/// @returns the value that the string has in the Enum /// @returns the value that the string has in the Enum
@ -512,9 +528,12 @@ public:
virtual Category getCategory() const override { return Category::Function; } virtual Category getCategory() const override { return Category::Function; }
/// @returns TypePointer of a new FunctionType object. All input/return parameters are an appropriate external types of input/return parameters of current function. /// @returns TypePointer of a new FunctionType object. All input/return parameters are an
/// Returns an empty shared pointer if one of the input/return parameters does not have an externaltype. /// appropriate external types of input/return parameters of current function.
virtual TypePointer externalType() const override; /// Returns an empty shared pointer if one of the input/return parameters does not have an
/// external type.
virtual FunctionTypePointer externalFunctionType() const;
virtual TypePointer externalType() const override { return externalFunctionType(); }
explicit FunctionType(FunctionDefinition const& _function, bool _isInternal = true); explicit FunctionType(FunctionDefinition const& _function, bool _isInternal = true);
explicit FunctionType(VariableDeclaration const& _varDecl); explicit FunctionType(VariableDeclaration const& _varDecl);

19
test/libsolidity/SolidityEndToEndTest.cpp

@ -3699,6 +3699,25 @@ BOOST_AUTO_TEST_CASE(packed_storage_signed)
BOOST_CHECK( callContractFunction("test()") == encodeArgs(u256(-2), u256(4), u256(-112), u256(0))); BOOST_CHECK( callContractFunction("test()") == encodeArgs(u256(-2), u256(4), u256(-112), u256(0)));
} }
BOOST_AUTO_TEST_CASE(external_types_in_calls)
{
char const* sourceCode = R"(
contract C1 { C1 public bla; function C1(C1 x) { bla = x; } }
contract C {
function test() returns (C1 x, C1 y) {
C1 c = new C1(C1(9));
x = c.bla();
y = this.t1(C1(7));
}
function t1(C1 a) returns (C1) { return a; }
function() returns (C1) { return C1(9); }
}
)";
compileAndRun(sourceCode, 0, "C");
BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(9), u256(7)));
BOOST_CHECK(callContractFunction("nonexisting") == encodeArgs(u256(9)));
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

Loading…
Cancel
Save