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());
|
||||
else // compound assignment
|
||||
{
|
||||
solAssert(binOp != Token::Exp, "Compound exp is not possible.");
|
||||
solAssert(leftType.isValueType(), "Compound operators only available for value types.");
|
||||
unsigned lvalueSize = m_currentLValue->sizeOnStack();
|
||||
unsigned itemSize = _assignment.annotation().type->sizeOnStack();
|
||||
@ -452,7 +453,10 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
|
||||
bool cleanupNeeded = cleanupNeededForOp(commonType->category(), c_op);
|
||||
|
||||
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, "");
|
||||
|
||||
// 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))
|
||||
// shift only cares about the signedness of both sides
|
||||
appendShiftOperatorCode(c_op, *leftTargetType, *rightTargetType);
|
||||
else if (c_op == Token::Exp)
|
||||
appendExpOperatorCode(*leftTargetType, *rightTargetType);
|
||||
else if (TokenTraits::isCompareOp(c_op))
|
||||
appendCompareOperatorCode(c_op, *commonType);
|
||||
else
|
||||
@ -2080,9 +2086,6 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token _operator, Type cons
|
||||
m_context << (c_isSigned ? Instruction::SMOD : Instruction::MOD);
|
||||
break;
|
||||
}
|
||||
case Token::Exp:
|
||||
m_context << Instruction::EXP;
|
||||
break;
|
||||
default:
|
||||
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(
|
||||
FunctionType const& _functionType,
|
||||
vector<ASTPointer<Expression const>> const& _arguments,
|
||||
|
@ -101,6 +101,7 @@ private:
|
||||
void appendArithmeticOperatorCode(Token _operator, Type const& _type);
|
||||
void appendBitOperatorCode(Token _operator);
|
||||
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.
|
||||
|
@ -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