mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Support empty strings.
This commit is contained in:
parent
8b54d1afb2
commit
a735228079
2
AST.cpp
2
AST.cpp
@ -339,7 +339,7 @@ void Literal::checkTypeRequirements()
|
|||||||
{
|
{
|
||||||
m_type = Type::forLiteral(*this);
|
m_type = Type::forLiteral(*this);
|
||||||
if (!m_type)
|
if (!m_type)
|
||||||
BOOST_THROW_EXCEPTION(createTypeError("Literal value too large or too small."));
|
BOOST_THROW_EXCEPTION(createTypeError("Literal value too large."));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ unsigned Compiler::appendCalldataUnpacker(FunctionDefinition const& _function, b
|
|||||||
for (ASTPointer<VariableDeclaration> const& var: _function.getParameters())
|
for (ASTPointer<VariableDeclaration> const& var: _function.getParameters())
|
||||||
{
|
{
|
||||||
unsigned const numBytes = var->getType()->getCalldataEncodedSize();
|
unsigned const numBytes = var->getType()->getCalldataEncodedSize();
|
||||||
if (numBytes == 0 || numBytes > 32)
|
if (numBytes > 32)
|
||||||
BOOST_THROW_EXCEPTION(CompilerError()
|
BOOST_THROW_EXCEPTION(CompilerError()
|
||||||
<< errinfo_sourceLocation(var->getLocation())
|
<< errinfo_sourceLocation(var->getLocation())
|
||||||
<< errinfo_comment("Type " + var->getType()->toString() + " not yet supported."));
|
<< errinfo_comment("Type " + var->getType()->toString() + " not yet supported."));
|
||||||
@ -156,7 +156,7 @@ void Compiler::appendReturnValuePacker(FunctionDefinition const& _function)
|
|||||||
{
|
{
|
||||||
Type const& paramType = *parameters[i]->getType();
|
Type const& paramType = *parameters[i]->getType();
|
||||||
unsigned numBytes = paramType.getCalldataEncodedSize();
|
unsigned numBytes = paramType.getCalldataEncodedSize();
|
||||||
if (numBytes == 0 || numBytes > 32)
|
if (numBytes > 32)
|
||||||
BOOST_THROW_EXCEPTION(CompilerError()
|
BOOST_THROW_EXCEPTION(CompilerError()
|
||||||
<< errinfo_sourceLocation(parameters[i]->getLocation())
|
<< errinfo_sourceLocation(parameters[i]->getLocation())
|
||||||
<< errinfo_comment("Type " + paramType.toString() + " not yet supported."));
|
<< errinfo_comment("Type " + paramType.toString() + " not yet supported."));
|
||||||
|
@ -33,9 +33,14 @@ namespace solidity
|
|||||||
|
|
||||||
void CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _leftAligned, bool _fromCalldata)
|
void CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _leftAligned, bool _fromCalldata)
|
||||||
{
|
{
|
||||||
|
if (_bytes == 0)
|
||||||
|
{
|
||||||
|
m_context << u256(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
eth::Instruction load = _fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD;
|
eth::Instruction load = _fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD;
|
||||||
if (asserts(0 < _bytes && _bytes <= 32))
|
if (asserts(_bytes <= 32))
|
||||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory load of 0 or more than 32 bytes requested."));
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory load of more than 32 bytes requested."));
|
||||||
if (_bytes == 32)
|
if (_bytes == 32)
|
||||||
m_context << u256(_offset) << load;
|
m_context << u256(_offset) << load;
|
||||||
else
|
else
|
||||||
@ -53,8 +58,13 @@ void CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _left
|
|||||||
|
|
||||||
void CompilerUtils::storeInMemory(unsigned _offset, unsigned _bytes, bool _leftAligned)
|
void CompilerUtils::storeInMemory(unsigned _offset, unsigned _bytes, bool _leftAligned)
|
||||||
{
|
{
|
||||||
if (asserts(0 < _bytes && _bytes <= 32))
|
if (_bytes == 0)
|
||||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory store of 0 or more than 32 bytes requested."));
|
{
|
||||||
|
m_context << eth::Instruction::POP;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (asserts(_bytes <= 32))
|
||||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory store of more than 32 bytes requested."));
|
||||||
if (_bytes != 32 && !_leftAligned)
|
if (_bytes != 32 && !_leftAligned)
|
||||||
// shift the value accordingly before storing
|
// shift the value accordingly before storing
|
||||||
m_context << (u256(1) << ((32 - _bytes) * 8)) << eth::Instruction::MUL;
|
m_context << (u256(1) << ((32 - _bytes) * 8)) << eth::Instruction::MUL;
|
||||||
|
1
Token.h
1
Token.h
@ -269,6 +269,7 @@ namespace solidity
|
|||||||
K(ADDRESS, "address", 0) \
|
K(ADDRESS, "address", 0) \
|
||||||
K(BOOL, "bool", 0) \
|
K(BOOL, "bool", 0) \
|
||||||
K(STRING_TYPE, "string", 0) \
|
K(STRING_TYPE, "string", 0) \
|
||||||
|
K(STRING0, "string0", 0) \
|
||||||
K(STRING1, "string1", 0) \
|
K(STRING1, "string1", 0) \
|
||||||
K(STRING2, "string2", 0) \
|
K(STRING2, "string2", 0) \
|
||||||
K(STRING3, "string3", 0) \
|
K(STRING3, "string3", 0) \
|
||||||
|
@ -53,8 +53,8 @@ shared_ptr<Type const> Type::fromElementaryTypeName(Token::Value _typeToken)
|
|||||||
return make_shared<IntegerType const>(0, IntegerType::Modifier::ADDRESS);
|
return make_shared<IntegerType const>(0, IntegerType::Modifier::ADDRESS);
|
||||||
else if (_typeToken == Token::BOOL)
|
else if (_typeToken == Token::BOOL)
|
||||||
return make_shared<BoolType const>();
|
return make_shared<BoolType const>();
|
||||||
else if (Token::STRING1 <= _typeToken && _typeToken <= Token::STRING32)
|
else if (Token::STRING0 <= _typeToken && _typeToken <= Token::STRING32)
|
||||||
return make_shared<StaticStringType const>(int(_typeToken) - int(Token::STRING1) + 1);
|
return make_shared<StaticStringType const>(int(_typeToken) - int(Token::STRING0));
|
||||||
else
|
else
|
||||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to convert elementary typename " +
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to convert elementary typename " +
|
||||||
std::string(Token::toString(_typeToken)) + " to type."));
|
std::string(Token::toString(_typeToken)) + " to type."));
|
||||||
@ -199,14 +199,14 @@ const MemberList IntegerType::AddressMemberList =
|
|||||||
|
|
||||||
shared_ptr<StaticStringType> StaticStringType::smallestTypeForLiteral(string const& _literal)
|
shared_ptr<StaticStringType> StaticStringType::smallestTypeForLiteral(string const& _literal)
|
||||||
{
|
{
|
||||||
if (0 < _literal.length() && _literal.length() <= 32)
|
if (_literal.length() <= 32)
|
||||||
return make_shared<StaticStringType>(_literal.length());
|
return make_shared<StaticStringType>(_literal.length());
|
||||||
return shared_ptr<StaticStringType>();
|
return shared_ptr<StaticStringType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticStringType::StaticStringType(int _bytes): m_bytes(_bytes)
|
StaticStringType::StaticStringType(int _bytes): m_bytes(_bytes)
|
||||||
{
|
{
|
||||||
if (asserts(m_bytes > 0 && m_bytes <= 32))
|
if (asserts(m_bytes >= 0 && m_bytes <= 32))
|
||||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid byte number for static string type: " +
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid byte number for static string type: " +
|
||||||
dev::toString(m_bytes)));
|
dev::toString(m_bytes)));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user