Browse Source

Fix type checks for storage variable initializer.

cl-refactor
chriseth 10 years ago
parent
commit
77b9fdcfbc
  1. 51
      libsolidity/AST.cpp
  2. 1
      libsolidity/AST.h
  3. 18
      test/SolidityNameAndTypeResolution.cpp

51
libsolidity/AST.cpp

@ -328,8 +328,30 @@ bool VariableDeclaration::isLValue() const
void VariableDeclaration::checkTypeRequirements() void VariableDeclaration::checkTypeRequirements()
{ {
if (m_value) // Variables can be declared without type (with "var"), in which case the first assignment
// sets the type.
// Note that assignments before the first declaration are legal because of the special scoping
// rules inherited from JavaScript.
if (!m_value)
return;
if (m_type)
m_value->expectType(*m_type);
else
{
// no type declared and no previous assignment, infer the type
m_value->checkTypeRequirements(); m_value->checkTypeRequirements();
TypePointer type = m_value->getType();
if (type->getCategory() == Type::Category::IntegerConstant)
{
auto intType = dynamic_pointer_cast<IntegerConstantType const>(type)->getIntegerType();
if (!intType)
BOOST_THROW_EXCEPTION(m_value->createTypeError("Invalid integer constant " + type->toString() + "."));
type = intType;
}
else if (type->getCategory() == Type::Category::Void)
BOOST_THROW_EXCEPTION(createTypeError("Variable cannot have void type."));
m_type = type;
}
} }
bool VariableDeclaration::isExternalFunctionParameter() const bool VariableDeclaration::isExternalFunctionParameter() const
@ -445,32 +467,9 @@ void Return::checkTypeRequirements()
void VariableDeclarationStatement::checkTypeRequirements() void VariableDeclarationStatement::checkTypeRequirements()
{ {
// Variables can be declared without type (with "var"), in which case the first assignment m_variable->checkTypeRequirements();
// sets the type.
// Note that assignments before the first declaration are legal because of the special scoping
// rules inherited from JavaScript.
if (m_variable->getValue())
{
if (m_variable->getType())
m_variable->getValue()->expectType(*m_variable->getType());
else
{
// no type declared and no previous assignment, infer the type
m_variable->getValue()->checkTypeRequirements();
TypePointer type = m_variable->getValue()->getType();
if (type->getCategory() == Type::Category::IntegerConstant)
{
auto intType = dynamic_pointer_cast<IntegerConstantType const>(type)->getIntegerType();
if (!intType)
BOOST_THROW_EXCEPTION(m_variable->getValue()->createTypeError("Invalid integer constant " + type->toString()));
type = intType;
}
else if (type->getCategory() == Type::Category::Void)
BOOST_THROW_EXCEPTION(m_variable->createTypeError("var cannot be void type"));
m_variable->setType(type);
}
}
} }
void Assignment::checkTypeRequirements() void Assignment::checkTypeRequirements()
{ {
m_leftHandSide->checkTypeRequirements(); m_leftHandSide->checkTypeRequirements();

1
libsolidity/AST.h

@ -460,7 +460,6 @@ public:
virtual bool isLValue() const override; virtual bool isLValue() const override;
/// Calls checkTypeRequirments for all state variables.
void checkTypeRequirements(); void checkTypeRequirements();
bool isLocalVariable() const { return !!dynamic_cast<FunctionDefinition const*>(getScope()); } bool isLocalVariable() const { return !!dynamic_cast<FunctionDefinition const*>(getScope()); }
bool isExternalFunctionParameter() const; bool isExternalFunctionParameter() const;

18
test/SolidityNameAndTypeResolution.cpp

@ -1292,6 +1292,24 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_dynamic_static)
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
} }
BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_int)
{
char const* text = R"(
contract c {
uint8 a = 1000;
})";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string)
{
char const* text = R"(
contract c {
uint a = "abc";
})";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

Loading…
Cancel
Save