-
Notifications
You must be signed in to change notification settings - Fork 6.3k
Remove the wrong codegen assumption that a conversion between non-byte calldata arrays can never happen #16415
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The PR is missing a changelog entry. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3858,11 +3858,18 @@ std::string YulUtilFunctions::copyStructToStorageFunction(StructType const& _fro | |
|
|
||
| std::string YulUtilFunctions::arrayConversionFunction(ArrayType const& _from, ArrayType const& _to) | ||
| { | ||
| if (_to.dataStoredIn(DataLocation::CallData)) | ||
| solAssert( | ||
| _from.dataStoredIn(DataLocation::CallData) && _from.isByteArrayOrString() && _to.isByteArrayOrString(), | ||
| "" | ||
| ); | ||
| solAssert( | ||
| !_to.dataStoredIn(DataLocation::CallData) || | ||
|
Comment on lines
-3861
to
+3862
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd keep the |
||
| ( | ||
| _from.dataStoredIn(DataLocation::CallData) && | ||
| ( | ||
| (_from.isByteArrayOrString() && _to.isByteArrayOrString()) || | ||
| (_from.baseType() == _to.baseType()) | ||
| ) | ||
| ), | ||
| "Conversion to calldata array is possible only from calldata array of the same type or for " | ||
| "(bytes calldata) <-> (string calldata) conversion." | ||
| ); | ||
|
|
||
| // Other cases are done explicitly in LValue::storeValue, and only possible by assignment. | ||
| if (_to.location() == DataLocation::Storage) | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add tests for slices and static arrays as well. At least the latter also trigger the ICE. contract C {
function f(uint[] calldata a) public {
(uint[] calldata b, ) = true ? (a[:], 0) : (a[0:1], 0);
}
}contract C {
function f(uint[3] calldata a) public {
(uint[3] calldata b, ) = true ? (a, 0) : (a, 0);
}
}Also a mix of arrays and slices (
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TBH I'd have no idea what this test does just from the current name. What do you mean by "ordinary types"? This should be way more specific: |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,69 @@ | ||||||||||||||||||||||
| pragma abicoder v2; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| contract C { | ||||||||||||||||||||||
| function g(uint[] calldata a) public returns(uint, uint, uint, uint) { | ||||||||||||||||||||||
| (uint[] calldata b, ) = true ? (a, 0) : (a, 0); | ||||||||||||||||||||||
| return (b.length, b[0], b[1], b[2]); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+4
to
+7
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd put this bit in a separate file. It's independent of the larger case, and when one of those fails it's usually nicer to have a smaller one that's easier to understand to debug. |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| struct N { | ||||||||||||||||||||||
| address addr; | ||||||||||||||||||||||
| bytes data; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| struct S { | ||||||||||||||||||||||
| uint8 a; | ||||||||||||||||||||||
| address addr; | ||||||||||||||||||||||
| N[] ns; | ||||||||||||||||||||||
| bytes data; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| function g() public returns(S[] memory) { | ||||||||||||||||||||||
| S[] memory ss = new S[](3); | ||||||||||||||||||||||
| ss[0].addr = address(this); | ||||||||||||||||||||||
| ss[0].a = 123; | ||||||||||||||||||||||
| ss[0].ns = new N[](1); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ss[0].ns[0].addr = address(this); | ||||||||||||||||||||||
| ss[0].ns[0].data = "abdeff00"; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ss[0].data = "abdeff"; | ||||||||||||||||||||||
|
Comment on lines
+25
to
+30
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ss[1].addr = msg.sender; | ||||||||||||||||||||||
| ss[1].a = 124; | ||||||||||||||||||||||
| ss[1].ns = new N[](2); | ||||||||||||||||||||||
| ss[1].ns[0].addr = msg.sender; | ||||||||||||||||||||||
| ss[1].ns[0].data = "abdeff10"; | ||||||||||||||||||||||
| ss[1].ns[1].addr = msg.sender; | ||||||||||||||||||||||
| ss[1].ns[1].data = "abdeff11"; | ||||||||||||||||||||||
| ss[1].data = "deabff"; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ss[2].addr = tx.origin; | ||||||||||||||||||||||
| ss[2].a = 125; | ||||||||||||||||||||||
| ss[2].ns = new N[](3); | ||||||||||||||||||||||
| ss[2].ns[0].addr = tx.origin; | ||||||||||||||||||||||
| ss[2].ns[0].data = "abdeff20"; | ||||||||||||||||||||||
| ss[2].ns[1].addr = tx.origin; | ||||||||||||||||||||||
| ss[2].ns[1].data = "abdeff21"; | ||||||||||||||||||||||
| ss[2].ns[2].addr = tx.origin; | ||||||||||||||||||||||
| ss[2].ns[2].data = "abdeff22"; | ||||||||||||||||||||||
| ss[2].data = "deffab"; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return ss; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| function g(S[] calldata a) public returns(S[] memory) { | ||||||||||||||||||||||
| (S[] calldata b, ) = true ? (a, 0) : (a, 0); | ||||||||||||||||||||||
| return b; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| // Two last results and input to last call must all be equal. | ||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be better if the expectations were just formatted in a way that makes it more obvious at a glance that they're correct. For example you could format strings as actual strings (soltest does accept those). I'd also use some regular-looking hard-coded addresses instead of things like Having to read it very carefully quickly gets tedious when reading a lot of tests. Overall we should try a bit harder optimize expectations for being able to quickly verifying them. |
||||||||||||||||||||||
| // ---- | ||||||||||||||||||||||
| // g(uint256[]): 0x20, 3, 11111111, 2222222, 888888888 -> 3, 11111111, 2222222, 888888888 | ||||||||||||||||||||||
| // g() | ||||||||||||||||||||||
| // -> | ||||||||||||||||||||||
| // 0x20, 0x03, 0x60, 0x01e0, 0x0400, 0x7b, 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0x80, 0x0140, 0x01, 0x20, 1098512253422041666021416798982440481960491542430, 0x40, 8, 0x6162646566663030000000000000000000000000000000000000000000000000, 6, 44048190233298227891509493227738300628996713231762343836654645076567135354880, 0x7c, 0x1212121212121212121212121212120000000012, 0x80, 0x01e0, 0x02, 0x40, 0xc0, 0x1212121212121212121212121212120000000012, 0x40, 0x08, 0x6162646566663130000000000000000000000000000000000000000000000000, 0x1212121212121212121212121212120000000012, 0x40, 0x08, 0x6162646566663131000000000000000000000000000000000000000000000000, 6, 45410408534123481836474933912542458712564453942015096274585020526880243056640, 0x7d, 0x9292929292929292929292929292929292929292, 0x80, 0x0280, 0x03, 0x60, 0xe0, 0x0160, 0x9292929292929292929292929292929292929292, 0x40, 0x08, 0x6162646566663230000000000000000000000000000000000000000000000000, 0x9292929292929292929292929292929292929292, 0x40, 0x08, 0x6162646566663231000000000000000000000000000000000000000000000000, 0x9292929292929292929292929292929292929292, 0x40, 0x08, 0x6162646566663232000000000000000000000000000000000000000000000000, 6, 45410443150166795494996323125458085338169329380009076603811707127780899553280 | ||||||||||||||||||||||
| // g((uint8,address,(address,bytes)[],bytes)[]): | ||||||||||||||||||||||
| // 0x20, 0x03, 0x60, 0x01e0, 0x0400, 0x7b, 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0x80, 0x0140, 0x01, 0x20, 1098512253422041666021416798982440481960491542430, 0x40, 8, 0x6162646566663030000000000000000000000000000000000000000000000000, 6, 44048190233298227891509493227738300628996713231762343836654645076567135354880, 0x7c, 0x1212121212121212121212121212120000000012, 0x80, 0x01e0, 0x02, 0x40, 0xc0, 0x1212121212121212121212121212120000000012, 0x40, 0x08, 0x6162646566663130000000000000000000000000000000000000000000000000, 0x1212121212121212121212121212120000000012, 0x40, 0x08, 0x6162646566663131000000000000000000000000000000000000000000000000, 6, 45410408534123481836474933912542458712564453942015096274585020526880243056640, 0x7d, 0x9292929292929292929292929292929292929292, 0x80, 0x0280, 0x03, 0x60, 0xe0, 0x0160, 0x9292929292929292929292929292929292929292, 0x40, 0x08, 0x6162646566663230000000000000000000000000000000000000000000000000, 0x9292929292929292929292929292929292929292, 0x40, 0x08, 0x6162646566663231000000000000000000000000000000000000000000000000, 0x9292929292929292929292929292929292929292, 0x40, 0x08, 0x6162646566663232000000000000000000000000000000000000000000000000, 6, 45410443150166795494996323125458085338169329380009076603811707127780899553280 | ||||||||||||||||||||||
| // -> | ||||||||||||||||||||||
| //0x20, 0x03, 0x60, 0x01e0, 0x0400, 0x7b, 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0x80, 0x0140, 0x01, 0x20, 1098512253422041666021416798982440481960491542430, 0x40, 8, 0x6162646566663030000000000000000000000000000000000000000000000000, 6, 44048190233298227891509493227738300628996713231762343836654645076567135354880, 0x7c, 0x1212121212121212121212121212120000000012, 0x80, 0x01e0, 0x02, 0x40, 0xc0, 0x1212121212121212121212121212120000000012, 0x40, 0x08, 0x6162646566663130000000000000000000000000000000000000000000000000, 0x1212121212121212121212121212120000000012, 0x40, 0x08, 0x6162646566663131000000000000000000000000000000000000000000000000, 6, 45410408534123481836474933912542458712564453942015096274585020526880243056640, 0x7d, 0x9292929292929292929292929292929292929292, 0x80, 0x0280, 0x03, 0x60, 0xe0, 0x0160, 0x9292929292929292929292929292929292929292, 0x40, 0x08, 0x6162646566663230000000000000000000000000000000000000000000000000, 0x9292929292929292929292929292929292929292, 0x40, 0x08, 0x6162646566663231000000000000000000000000000000000000000000000000, 0x9292929292929292929292929292929292929292, 0x40, 0x08, 0x6162646566663232000000000000000000000000000000000000000000000000, 6, 45410443150166795494996323125458085338169329380009076603811707127780899553280 | ||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you check #16066 (comment)? We should really check why something like
true ? (a, true) : (a, true)does not trigger this bug. This may mean that either we're not doing an array conversion in some case were we need it or that we shouldn't be doing it in thetrue ? (a, 0) : (a, 0)case.