Describe the bug In 12.6.6 function member invocation, for E.M(args...), if E is not value type or does not implement M, then:
- evaluate
E
- evaluate
args...
- if
E is value type, box it and treat it as the boxed instance
- invoke
M
Suppose E is classified as a variable, then it's unclear when the value of E is read. Is it right after 1, or right before 3? The two options are not equivalent, because evaluation of args... could modify the value stored in that variable.
After some testing, it turns out that
- when
E is reference type, the value (reference) is read right after 1,
- Suppose
E is the identifier of a local variable and args... reassigns this variable, the receiver of E.M(args...) is the (old) object before reassignment.
- but, when
E is value type, the value is read right before 3.
- Suppose
E is the identifier of a local variable and args... reassigns this variable, the receiver of E.M(args...) is a boxed instance of the reassigned (new) value.
The timings are different!
Example
See replies to this issue.
Expected behavior
The standard should clearly specify the timing of reading of value from variable.
Additional context
Found when investigating the semantics of constrained. callvirt.. See dotnet/dotnet-api-docs#12359.
Describe the bug In 12.6.6 function member invocation, for
E.M(args...), ifEis not value type or does not implementM, then:Eargs...Eis value type, box it and treat it as the boxed instanceMSuppose
Eis classified as a variable, then it's unclear when the value ofEis read. Is it right after 1, or right before 3? The two options are not equivalent, because evaluation ofargs...could modify the value stored in that variable.After some testing, it turns out that
Eis reference type, the value (reference) is read right after 1,Eis the identifier of a local variable andargs...reassigns this variable, the receiver ofE.M(args...)is the (old) object before reassignment.Eis value type, the value is read right before 3.Eis the identifier of a local variable andargs...reassigns this variable, the receiver ofE.M(args...)is a boxed instance of the reassigned (new) value.The timings are different!
Example
See replies to this issue.
Expected behavior
The standard should clearly specify the timing of reading of value from variable.
Additional context
Found when investigating the semantics of
constrained. callvirt.. See dotnet/dotnet-api-docs#12359.