| 718 | } |
| 719 | |
| 720 | std::string YulUtilFunctions::overflowCheckedIntAddFunction(IntegerType const& _type) |
| 721 | { |
| 722 | std::string functionName = "checked_add_" + _type.identifier(); |
| 723 | return m_functionCollector.createFunction(functionName, [&]() { |
| 724 | return |
| 725 | Whiskers(R"( |
| 726 | function <functionName>(x, y) -> sum { |
| 727 | x := <cleanupFunction>(x) |
| 728 | y := <cleanupFunction>(y) |
| 729 | sum := add(x, y) |
| 730 | <?signed> |
| 731 | <?256bit> |
| 732 | // overflow, if x >= 0 and sum < y |
| 733 | // underflow, if x < 0 and sum >= y |
| 734 | if or( |
| 735 | and(iszero(slt(x, 0)), slt(sum, y)), |
| 736 | and(slt(x, 0), iszero(slt(sum, y))) |
| 737 | ) { <panic>() } |
| 738 | <!256bit> |
| 739 | if or( |
| 740 | sgt(sum, <maxValue>), |
| 741 | slt(sum, <minValue>) |
| 742 | ) { <panic>() } |
| 743 | </256bit> |
| 744 | <!signed> |
| 745 | <?256bit> |
| 746 | if gt(x, sum) { <panic>() } |
| 747 | <!256bit> |
| 748 | if gt(sum, <maxValue>) { <panic>() } |
| 749 | </256bit> |
| 750 | </signed> |
| 751 | } |
| 752 | )") |
| 753 | ("functionName", functionName) |
| 754 | ("signed", _type.isSigned()) |
| 755 | ("maxValue", toCompactHexWithPrefix(u256(_type.maxValue()))) |
| 756 | ("minValue", toCompactHexWithPrefix(u256(_type.minValue()))) |
| 757 | ("cleanupFunction", cleanupFunction(_type)) |
| 758 | ("panic", panicFunction(PanicCode::UnderOverflow)) |
| 759 | ("256bit", _type.numBits() == 256) |
| 760 | .render(); |
| 761 | }); |
| 762 | } |
| 763 | |
| 764 | std::string YulUtilFunctions::wrappingIntAddFunction(IntegerType const& _type) |
| 765 | { |
no test coverage detected