Detect integer length from literals and remove "std::".

This commit is contained in:
Christian 2014-11-04 13:24:35 +01:00
parent e30d3f8d53
commit de493c673f
3 changed files with 29 additions and 19 deletions

View File

@ -497,6 +497,8 @@ void ElementaryTypeNameExpression::checkTypeRequirements()
void Literal::checkTypeRequirements() void Literal::checkTypeRequirements()
{ {
m_type = Type::forLiteral(*this); m_type = Type::forLiteral(*this);
if (!m_type)
BOOST_THROW_EXCEPTION(createTypeError("Literal value too large."));
} }
} }

View File

@ -25,12 +25,14 @@
#include <libsolidity/Types.h> #include <libsolidity/Types.h>
#include <libsolidity/AST.h> #include <libsolidity/AST.h>
using namespace std;
namespace dev namespace dev
{ {
namespace solidity namespace solidity
{ {
std::shared_ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken) shared_ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken)
{ {
if (asserts(Token::isElementaryTypeName(_typeToken))) if (asserts(Token::isElementaryTypeName(_typeToken)))
BOOST_THROW_EXCEPTION(InternalCompilerError()); BOOST_THROW_EXCEPTION(InternalCompilerError());
@ -44,52 +46,55 @@ std::shared_ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken)
else else
bits = (1 << (bits - 1)) * 32; bits = (1 << (bits - 1)) * 32;
int modifier = offset / 5; int modifier = offset / 5;
return std::make_shared<IntegerType>(bits, return make_shared<IntegerType>(bits,
modifier == 0 ? IntegerType::Modifier::SIGNED : modifier == 0 ? IntegerType::Modifier::SIGNED :
modifier == 1 ? IntegerType::Modifier::UNSIGNED : modifier == 1 ? IntegerType::Modifier::UNSIGNED :
IntegerType::Modifier::HASH); IntegerType::Modifier::HASH);
} }
else if (_typeToken == Token::ADDRESS) else if (_typeToken == Token::ADDRESS)
return std::make_shared<IntegerType>(0, IntegerType::Modifier::ADDRESS); return make_shared<IntegerType>(0, IntegerType::Modifier::ADDRESS);
else if (_typeToken == Token::BOOL) else if (_typeToken == Token::BOOL)
return std::make_shared<BoolType>(); return make_shared<BoolType>();
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."));
return std::shared_ptr<Type>(); return shared_ptr<Type>();
} }
std::shared_ptr<Type> Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName) shared_ptr<Type> Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName)
{ {
return std::make_shared<StructType>(*_typeName.getReferencedStruct()); return make_shared<StructType>(*_typeName.getReferencedStruct());
} }
std::shared_ptr<Type> Type::fromMapping(Mapping const&) shared_ptr<Type> Type::fromMapping(Mapping const&)
{ {
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Mapping types not yet implemented.")); BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Mapping types not yet implemented."));
return std::shared_ptr<Type>(); return shared_ptr<Type>();
} }
std::shared_ptr<Type> Type::forLiteral(Literal const& _literal) shared_ptr<Type> Type::forLiteral(Literal const& _literal)
{ {
switch (_literal.getToken()) switch (_literal.getToken())
{ {
case Token::TRUE_LITERAL: case Token::TRUE_LITERAL:
case Token::FALSE_LITERAL: case Token::FALSE_LITERAL:
return std::make_shared<BoolType>(); return make_shared<BoolType>();
case Token::NUMBER: case Token::NUMBER:
return IntegerType::smallestTypeForLiteral(_literal.getValue()); return IntegerType::smallestTypeForLiteral(_literal.getValue());
case Token::STRING_LITERAL: case Token::STRING_LITERAL:
return std::shared_ptr<Type>(); // @todo return shared_ptr<Type>(); // @todo
default: default:
return std::shared_ptr<Type>(); return shared_ptr<Type>();
} }
} }
std::shared_ptr<IntegerType> IntegerType::smallestTypeForLiteral(std::string const&) shared_ptr<IntegerType> IntegerType::smallestTypeForLiteral(string const& _literal)
{ {
//@todo bigint value(_literal);
return std::make_shared<IntegerType>(256, Modifier::UNSIGNED); unsigned bytes = max(bytesRequired(value), 1u);
if (bytes > 32)
return shared_ptr<IntegerType>();
return make_shared<IntegerType>(bytes * 8, Modifier::UNSIGNED);
} }
IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier): IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier):
@ -155,11 +160,11 @@ bool IntegerType::operator==(Type const& _other) const
return other.m_bits == m_bits && other.m_modifier == m_modifier; return other.m_bits == m_bits && other.m_modifier == m_modifier;
} }
std::string IntegerType::toString() const string IntegerType::toString() const
{ {
if (isAddress()) if (isAddress())
return "address"; return "address";
std::string prefix = isHash() ? "hash" : (isSigned() ? "int" : "uint"); string prefix = isHash() ? "hash" : (isSigned() ? "int" : "uint");
return prefix + dev::toString(m_bits); return prefix + dev::toString(m_bits);
} }

View File

@ -56,7 +56,8 @@ public:
static std::shared_ptr<Type> fromMapping(Mapping const& _typeName); static std::shared_ptr<Type> fromMapping(Mapping const& _typeName);
/// @} /// @}
/// Auto-detect the proper type for a literal /// Auto-detect the proper type for a literal. @returns an empty pointer if the literal does
/// not fit any type.
static std::shared_ptr<Type> forLiteral(Literal const& _literal); static std::shared_ptr<Type> forLiteral(Literal const& _literal);
virtual Category getCategory() const = 0; virtual Category getCategory() const = 0;
@ -95,6 +96,8 @@ public:
}; };
virtual Category getCategory() const override { return Category::INTEGER; } virtual Category getCategory() const override { return Category::INTEGER; }
/// @returns the smallest integer type for the given literal or an empty pointer
/// if no type fits.
static std::shared_ptr<IntegerType> smallestTypeForLiteral(std::string const& _literal); static std::shared_ptr<IntegerType> smallestTypeForLiteral(std::string const& _literal);
explicit IntegerType(int _bits, Modifier _modifier = Modifier::UNSIGNED); explicit IntegerType(int _bits, Modifier _modifier = Modifier::UNSIGNED);