fix: fold parenthesized type(X).max/min in IR generation - #3081
Open
innbuld wants to merge 1 commit into
Open
Conversation
`(type(uint8)).max` is parsed with the `type()` call wrapped in a single-element TupleExpression, so the `type(X).max`/`.min` folding in `_post_member_access` (which checked for a bare CallExpression) was skipped. The member access then reached `convert.py` and raised "type(uint8).max is unknown", failing IR generation for the function. Unwrap redundant single-element parentheses before the check so `(type(X)).max`, `((type(X))).min`, etc. fold to the correct constant, exactly like the non-parenthesized form. Adds a unit test asserting the folded constants for uint8/uint256/int256, parenthesized and nested, plus the plain form as a regression guard. Fixes crytic#2645
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
(type(uint8)).max(redundant parentheses aroundtype(X)) fails IR generation, while the non-parenthesizedtype(uint8).maxworks fine:Root cause
type(X).max/.minis folded to a constant inExpressionToSlithIR._post_member_access, but the check required the accessed sub-expression to be a bareCallExpression. Parentheses wrap thetype()call in a single-elementTupleExpression, so the fold is skipped. The member access then falls through toconvert.py's_convert_type_contract(which only handlescreationCode/runtimeCode/interfaceId/name) and raisestype(X).max is unknown.Fix
Unwrap redundant single-element parentheses before the
type(X).max/.mincheck.(type(X)).max,((type(X))).min, etc. now fold to the correct constant like the non-parenthesized form (elementary signed and unsigned types covered).Testing
tests/unit/slithir/test_type_minmax.pyasserts the folded constants foruint8/uint256/int256, parenthesized and nested, plus the plain form as a regression guard. It fails before the fix (type(uint8).max is unknown) and passes after.tests/unit/slithirandsolc_parsingminmax tests pass.Fixes #2645