mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9494 from ethereum/fixExp07
Fix conversion bug for exp operation.
This commit is contained in:
commit
82e5e80cba
@ -286,6 +286,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
|
|||||||
m_currentLValue->storeValue(*rightIntermediateType, _assignment.location());
|
m_currentLValue->storeValue(*rightIntermediateType, _assignment.location());
|
||||||
else // compound assignment
|
else // compound assignment
|
||||||
{
|
{
|
||||||
|
solAssert(binOp != Token::Exp, "Compound exp is not possible.");
|
||||||
solAssert(leftType.isValueType(), "Compound operators only available for value types.");
|
solAssert(leftType.isValueType(), "Compound operators only available for value types.");
|
||||||
unsigned lvalueSize = m_currentLValue->sizeOnStack();
|
unsigned lvalueSize = m_currentLValue->sizeOnStack();
|
||||||
unsigned itemSize = _assignment.annotation().type->sizeOnStack();
|
unsigned itemSize = _assignment.annotation().type->sizeOnStack();
|
||||||
@ -452,7 +453,10 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
|
|||||||
bool cleanupNeeded = cleanupNeededForOp(commonType->category(), c_op);
|
bool cleanupNeeded = cleanupNeededForOp(commonType->category(), c_op);
|
||||||
|
|
||||||
TypePointer leftTargetType = commonType;
|
TypePointer leftTargetType = commonType;
|
||||||
TypePointer rightTargetType = TokenTraits::isShiftOp(c_op) ? rightExpression.annotation().type->mobileType() : commonType;
|
TypePointer rightTargetType =
|
||||||
|
TokenTraits::isShiftOp(c_op) || c_op == Token::Exp ?
|
||||||
|
rightExpression.annotation().type->mobileType() :
|
||||||
|
commonType;
|
||||||
solAssert(rightTargetType, "");
|
solAssert(rightTargetType, "");
|
||||||
|
|
||||||
// for commutative operators, push the literal as late as possible to allow improved optimization
|
// for commutative operators, push the literal as late as possible to allow improved optimization
|
||||||
@ -474,6 +478,8 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
|
|||||||
if (TokenTraits::isShiftOp(c_op))
|
if (TokenTraits::isShiftOp(c_op))
|
||||||
// shift only cares about the signedness of both sides
|
// shift only cares about the signedness of both sides
|
||||||
appendShiftOperatorCode(c_op, *leftTargetType, *rightTargetType);
|
appendShiftOperatorCode(c_op, *leftTargetType, *rightTargetType);
|
||||||
|
else if (c_op == Token::Exp)
|
||||||
|
appendExpOperatorCode(*leftTargetType, *rightTargetType);
|
||||||
else if (TokenTraits::isCompareOp(c_op))
|
else if (TokenTraits::isCompareOp(c_op))
|
||||||
appendCompareOperatorCode(c_op, *commonType);
|
appendCompareOperatorCode(c_op, *commonType);
|
||||||
else
|
else
|
||||||
@ -2080,9 +2086,6 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token _operator, Type cons
|
|||||||
m_context << (c_isSigned ? Instruction::SMOD : Instruction::MOD);
|
m_context << (c_isSigned ? Instruction::SMOD : Instruction::MOD);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Token::Exp:
|
|
||||||
m_context << Instruction::EXP;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
solAssert(false, "Unknown arithmetic operator.");
|
solAssert(false, "Unknown arithmetic operator.");
|
||||||
}
|
}
|
||||||
@ -2177,6 +2180,14 @@ void ExpressionCompiler::appendShiftOperatorCode(Token _operator, Type const& _v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExpressionCompiler::appendExpOperatorCode(Type const& _valueType, Type const& _exponentType)
|
||||||
|
{
|
||||||
|
solAssert(_valueType.category() == Type::Category::Integer, "");
|
||||||
|
solAssert(!dynamic_cast<IntegerType const&>(_exponentType).isSigned(), "");
|
||||||
|
|
||||||
|
m_context << Instruction::EXP;
|
||||||
|
}
|
||||||
|
|
||||||
void ExpressionCompiler::appendExternalFunctionCall(
|
void ExpressionCompiler::appendExternalFunctionCall(
|
||||||
FunctionType const& _functionType,
|
FunctionType const& _functionType,
|
||||||
vector<ASTPointer<Expression const>> const& _arguments,
|
vector<ASTPointer<Expression const>> const& _arguments,
|
||||||
|
@ -101,6 +101,7 @@ private:
|
|||||||
void appendArithmeticOperatorCode(Token _operator, Type const& _type);
|
void appendArithmeticOperatorCode(Token _operator, Type const& _type);
|
||||||
void appendBitOperatorCode(Token _operator);
|
void appendBitOperatorCode(Token _operator);
|
||||||
void appendShiftOperatorCode(Token _operator, Type const& _valueType, Type const& _shiftAmountType);
|
void appendShiftOperatorCode(Token _operator, Type const& _valueType, Type const& _shiftAmountType);
|
||||||
|
void appendExpOperatorCode(Type const& _valueType, Type const& _exponentType);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// Appends code to call a function of the given type with the given arguments.
|
/// Appends code to call a function of the given type with the given arguments.
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
contract C {
|
||||||
|
function f() public pure returns (uint16 x) {
|
||||||
|
// tests that ``e`` is not converted to uint8
|
||||||
|
// right before the exp
|
||||||
|
uint16 e = 0x100;
|
||||||
|
uint8 b = 0x2;
|
||||||
|
return b**e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// f() -> 0x00
|
Loading…
Reference in New Issue
Block a user