[ImportVerilog] Don't convert lvalues
- Dominant language
- C++
- Stars
- 2.2k
- Forks
- 524
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 46
Description
Removal of the `moore.conversion` op in #11024 has uncovered a few places where we try to cast an lvalue to a different type. This doesn't work, since lvalues are `ref` pointing to a variable or some other memory-like thing, and we can't simply cast that pointer to a `ref`. This has come up with `output`, `inout`, and `ref` subroutine arguments, and `inout` module port connections. Instead of trying to cast the lvalue, we need to pass in a temporary of the correct `ref` value, and then upon write-back cast the `U` to `V` and do the actual write to `ref`. Modules already do this to some degree when dealing with output ports.
```systemverilog
module implicitCastsFunctionArguments;
real r, q;
function void fn(output logic [3:0] o, input logic [3:0] val);
o = val;
endfunction
initial fn(q, r);
endmodule
```
```
error: unsupported conversion from '!moore.ref' to '!moore.ref'
```
The same shape shows up for module inout ports whose connecting net has a different width than the port (see the `virtual-interface-modport.sv` XFAIL test for a related but distinct case: modport port renaming, not a width/domain mismatch).
`Context::materializeConversion` is fundamentally an rvalue-conversion helper; given two ref types it has nothing better to do than reinterpret the pointee in place, which is wrong. A real fix needs to read through the actual's ref, convert the value, and write it back through a temporary (or similar) rather than converting the ref type itself — this is a different code path from ordinary value conversion. The two call sites are the output/inout/ref argument handling in `lib/Conversion/ImportVerilog/Expressions.cpp` and the module instance port connection handling in `lib/Conversion/ImportVerilog/Structure.cpp`.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in lib/Conversion/ImportVerilog/Expressions.cpp and Structure.cpp at the two call sites named in the issue, then inspect Context::materializeConversion to understand why ref types are mishandled. Use the implicitCastsFunctionArguments example and the virtual-interface-modport.sv XFAIL test as references. Done means output/inout/ref arguments and module inout connections read through the actual ref, convert through a temporary, and write back correctly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100