-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Fixes issue #43205: ICE in Rvalue::Len evaluation. #44060
Conversation
- fixes evaluation of array length for zero-sized type referenced by rvalue operand. - adds test to verify fix. Cause of the issue. Zero-sized aggregates are handled as operands, not lvalues. Therefore while visiting Assign statement by LocalAnalyser, mark_as_lvalue() is not called for related Local. This behaviour is controlled by rvalue_creates_operand() method. As result it causes error later, when rvalue operand is evaluated in trans_rvalue_operand() while handling Rvalue::Len case. Array length evaluation invokes trans_lvalue() which expects referenced Local to be value, not operand. How it is fixed. In certain cases result of Rvalue::Len can be evaluated without calling trans_lvalue(). Method evaluate_array_len() is introduced to handle length evaluation for zero-sized types referenced by Locals.
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @eddyb (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
r? @arielb1 |
@bors r+ |
📌 Commit e13090e has been approved by |
Fixes issue #43205: ICE in Rvalue::Len evaluation. - fixes evaluation of array length for zero-sized type referenced by rvalue operand. - adds test to verify fix. *Cause of the issue*. Zero-sized aggregates are handled as operands, not lvalues. Therefore while visiting `Assign` statement by `LocalAnalyser`, `mark_as_lvalue()` is not called for related `Local`. This behaviour is controlled by `rvalue_creates_operand()` method. As result it causes error later, when rvalue operand is evaluated in `trans_rvalue_operand()` while handling `Rvalue::Len` case. Array length evaluation invokes `trans_lvalue()` which expects referenced `Local` to be value, not operand. *How it is fixed*. In certain cases result of `Rvalue::Len` can be evaluated without calling `trans_lvalue()`. Method `evaluate_array_len()` is introduced to handle length evaluation for zero-sized types referenced by Locals. *Some concerns*. - `trans_lvalue()` has two other entry points in `rvalue.rs`: it is invoked while handling `Rvalue::Ref` and `Rvalue::Discriminant`. There is a chance those may produce the same issue, but I've failed to write a specific test that leads to this. - `evaluate_array_len()` performs the same check (matches lvalue and `Local`), which is performed again in `trans_lvalue()`. Without changing `trans_lvalue()` signature to make it aware that caller deals with rvalue, it seems there is no cheap solution to avoid this check.
☀️ Test successful - status-appveyor, status-travis |
Cause of the issue.
Zero-sized aggregates are handled as operands, not lvalues. Therefore while visiting
Assign
statement byLocalAnalyser
,mark_as_lvalue()
is not called for relatedLocal
. This behaviour is controlled byrvalue_creates_operand()
method.As result it causes error later, when rvalue operand is evaluated in
trans_rvalue_operand()
while handlingRvalue::Len
case. Array length evaluation invokestrans_lvalue()
which expects referencedLocal
to be value, not operand.How it is fixed.
In certain cases result of
Rvalue::Len
can be evaluated without callingtrans_lvalue()
. Methodevaluate_array_len()
is introduced to handle lengthevaluation for zero-sized types referenced by Locals.
Some concerns.
trans_lvalue()
has two other entry points inrvalue.rs
: it is invoked while handlingRvalue::Ref
andRvalue::Discriminant
. There is a chance those may produce the same issue, but I've failed to write a specific test that leads to this.evaluate_array_len()
performs the same check (matches lvalue andLocal
), which is performed again intrans_lvalue()
. Without changingtrans_lvalue()
signature to make it aware that caller deals with rvalue, it seems there is no cheap solution to avoid this check.