mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Possibility for unary operators to change type.
This commit is contained in:
parent
b6bad63d44
commit
d35842d65e
4
AST.cpp
4
AST.cpp
@ -227,8 +227,8 @@ void UnaryOperation::checkTypeRequirements()
|
||||
m_subExpression->checkTypeRequirements();
|
||||
if (m_operator == Token::Value::INC || m_operator == Token::Value::DEC || m_operator == Token::Value::DELETE)
|
||||
m_subExpression->requireLValue();
|
||||
m_type = m_subExpression->getType();
|
||||
if (!m_type->acceptsUnaryOperator(m_operator))
|
||||
m_type = m_subExpression->getType()->unaryOperatorResult(m_operator);
|
||||
if (!m_type)
|
||||
BOOST_THROW_EXCEPTION(createTypeError("Unary operator not compatible with type."));
|
||||
}
|
||||
|
||||
|
28
Types.cpp
28
Types.cpp
@ -156,18 +156,26 @@ bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
return _convertTo.getCategory() == getCategory() || _convertTo.getCategory() == Category::CONTRACT;
|
||||
}
|
||||
|
||||
bool IntegerType::acceptsUnaryOperator(Token::Value _operator) const
|
||||
TypePointer IntegerType::unaryOperatorResult(Token::Value _operator) const
|
||||
{
|
||||
// "delete" is ok for all integer types
|
||||
if (_operator == Token::DELETE)
|
||||
return true;
|
||||
if (isAddress())
|
||||
return false;
|
||||
if (_operator == Token::BIT_NOT)
|
||||
return true;
|
||||
if (isHash())
|
||||
return false;
|
||||
return _operator == Token::ADD || _operator == Token::SUB ||
|
||||
_operator == Token::INC || _operator == Token::DEC;
|
||||
return shared_from_this();
|
||||
// no further unary operators for addresses
|
||||
else if (isAddress())
|
||||
return TypePointer();
|
||||
// "~" is ok for all other types
|
||||
else if (_operator == Token::BIT_NOT)
|
||||
return shared_from_this();
|
||||
// nothing else for hashes
|
||||
else if (isHash())
|
||||
return TypePointer();
|
||||
// for non-hash integers, we allow +, -, ++ and --
|
||||
else if (_operator == Token::ADD || _operator == Token::SUB ||
|
||||
_operator == Token::INC || _operator == Token::DEC)
|
||||
return shared_from_this();
|
||||
else
|
||||
return TypePointer();
|
||||
}
|
||||
|
||||
bool IntegerType::operator==(Type const& _other) const
|
||||
|
16
Types.h
16
Types.h
@ -99,7 +99,10 @@ public:
|
||||
{
|
||||
return isImplicitlyConvertibleTo(_convertTo);
|
||||
}
|
||||
virtual bool acceptsUnaryOperator(Token::Value) const { return false; }
|
||||
/// @returns the resulting type of applying the given unary operator or an empty pointer if
|
||||
/// this is not possible.
|
||||
/// The default implementation does not allow any unary operator.
|
||||
virtual TypePointer unaryOperatorResult(Token::Value) const { return TypePointer(); }
|
||||
/// @returns the resulting type of applying the given binary operator or an empty pointer if
|
||||
/// this is not possible.
|
||||
/// The default implementation allows comparison operators if a common type exists
|
||||
@ -163,7 +166,7 @@ public:
|
||||
|
||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
virtual bool acceptsUnaryOperator(Token::Value _operator) const override;
|
||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
||||
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
||||
|
||||
virtual bool operator==(Type const& _other) const override;
|
||||
@ -225,9 +228,9 @@ public:
|
||||
BoolType() {}
|
||||
virtual Category getCategory() const { return Category::BOOL; }
|
||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
virtual bool acceptsUnaryOperator(Token::Value _operator) const override
|
||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override
|
||||
{
|
||||
return _operator == Token::NOT || _operator == Token::DELETE;
|
||||
return (_operator == Token::NOT || _operator == Token::DELETE) ? shared_from_this() : TypePointer();
|
||||
}
|
||||
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
||||
|
||||
@ -277,7 +280,10 @@ class StructType: public Type
|
||||
public:
|
||||
virtual Category getCategory() const override { return Category::STRUCT; }
|
||||
StructType(StructDefinition const& _struct): m_struct(_struct) {}
|
||||
virtual bool acceptsUnaryOperator(Token::Value _operator) const override { return _operator == Token::DELETE; }
|
||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override
|
||||
{
|
||||
return _operator == Token::DELETE ? shared_from_this() : TypePointer();
|
||||
}
|
||||
|
||||
virtual bool operator==(Type const& _other) const override;
|
||||
virtual u256 getStorageSize() const override;
|
||||
|
Loading…
Reference in New Issue
Block a user