diff options
-rw-r--r-- | AST.cpp | 2 | ||||
-rw-r--r-- | Types.cpp | 41 | ||||
-rw-r--r-- | Types.h | 5 |
3 files changed, 29 insertions, 19 deletions
@@ -497,6 +497,8 @@ void ElementaryTypeNameExpression::checkTypeRequirements() void Literal::checkTypeRequirements() { m_type = Type::forLiteral(*this); + if (!m_type) + BOOST_THROW_EXCEPTION(createTypeError("Literal value too large.")); } } @@ -25,12 +25,14 @@ #include <libsolidity/Types.h> #include <libsolidity/AST.h> +using namespace std; + namespace dev { namespace solidity { -std::shared_ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken) +shared_ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken) { if (asserts(Token::isElementaryTypeName(_typeToken))) BOOST_THROW_EXCEPTION(InternalCompilerError()); @@ -44,52 +46,55 @@ std::shared_ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken) else bits = (1 << (bits - 1)) * 32; int modifier = offset / 5; - return std::make_shared<IntegerType>(bits, + return make_shared<IntegerType>(bits, modifier == 0 ? IntegerType::Modifier::SIGNED : modifier == 1 ? IntegerType::Modifier::UNSIGNED : IntegerType::Modifier::HASH); } 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) - return std::make_shared<BoolType>(); + return make_shared<BoolType>(); else BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to convert elementary typename " + 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.")); - 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()) { case Token::TRUE_LITERAL: case Token::FALSE_LITERAL: - return std::make_shared<BoolType>(); + return make_shared<BoolType>(); case Token::NUMBER: return IntegerType::smallestTypeForLiteral(_literal.getValue()); case Token::STRING_LITERAL: - return std::shared_ptr<Type>(); // @todo + return shared_ptr<Type>(); // @todo 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 - return std::make_shared<IntegerType>(256, Modifier::UNSIGNED); + bigint value(_literal); + 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): @@ -155,11 +160,11 @@ bool IntegerType::operator==(Type const& _other) const return other.m_bits == m_bits && other.m_modifier == m_modifier; } -std::string IntegerType::toString() const +string IntegerType::toString() const { if (isAddress()) return "address"; - std::string prefix = isHash() ? "hash" : (isSigned() ? "int" : "uint"); + string prefix = isHash() ? "hash" : (isSigned() ? "int" : "uint"); return prefix + dev::toString(m_bits); } @@ -56,7 +56,8 @@ public: 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); virtual Category getCategory() const = 0; @@ -95,6 +96,8 @@ public: }; 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); explicit IntegerType(int _bits, Modifier _modifier = Modifier::UNSIGNED); |