-
Notifications
You must be signed in to change notification settings - Fork 39
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
sem/transf: don't collapse implict addr/deref nodes #498
Conversation
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.
Looks good to me. Plenty of comments to understand and improve things over time.
compiler/sem/semexprs.nim
Outdated
else: | ||
result = c.config.newError(n, reportAst(rsemVarForOutParamNeeded, n)) | ||
## Wraps the expression `n` in an ``nkHiddenAddr`` or, if the expression is | ||
## not a mutable lvalue, an ``nkError`` |
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.
Thanks for documenting it, as well.
let n = result | ||
# collapse ``nkAddr( nkDerefExpr(x) )`` to ``x``, but only if ``x`` is of | ||
# pointer type. Performing the collapsing when ``x`` is a ``ref`` would be | ||
# incorrect, as there'd be a formal vs. actual type mismatch then |
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.
Yup
3390d1f
to
badb6e8
Compare
Once tests pass let's merge. |
e7ae3e5
to
4742dad
Compare
b4f136a
to
243dcb7
Compare
Another detour is needed, it seems. The PR that fixed the JS code-generator issue that was the previous blocker also added a test for arguments to |
## Summary The collapsing produces unsound AST in the case that the operand of the `nkHiddenDeref` doesn't have the same type as the `nkHiddenAddr` node. For example, if the `nkHiddenDeref` dereferences a `ptr` or `ref` value, the collapsing would result in a `ptr` or `ref` value to be directly passed to `var` parameter (because `nkHiddenAddr` nodes are generated when passing something to a `var` parameter), which is incorrect. The reason that this didn't cause many problems so far is that `var`, `ref`, and `ptr` are all pointers underneath for the C target, and that `cgen` doesn't inspect the type of nodes in many cases. The collapsing done directly in `semexpr` is removed and the one done in `transf` is adjusted: - only `DerefExpr( Addr(x) )` and `Addr( DerefExpr(x) )` (both are expressions explicitly provided by the user) are collapsed -- the latter one only when `x` is of `ptr` type. - since collapsing `HiddenDeref( HiddenAddr(x) )` is always known to be safe, the behaviour is kept. Because of a `cgen` issue, it's currently also required. Unconditional collapsing of all address-of + deref expression is now performed inside the C code-generator, because it is known that the operands to all dereference operations map to C pointers at that point. ## Details The compiler targets C89, where dereferencing a pointer requires a pointer to complete type, even when the result is immediately passed to an address-of operation (i.e. `&(*x)`). `cgen` now requests the complete type whenever emitting a deref. `vmgen` depends on the removed collapsing and thus generates incorrect code in some cases now -- until the code-generator is fixed, the `tvar_arguments` test is disabled for the VM target.
243dcb7
to
55a8ca7
Compare
I'm in the process of fixing the mentioned In order to break the cyclic dependency, I disabled the bors r+ |
Build succeeded: |
Summary
The collapsing produces unsound AST in the case that the operand of the
nkHiddenDeref
doesn't have the same type as thenkHiddenAddr
node.For example, if the
nkHiddenDeref
dereferences aptr
orref
value,the collapsing would result in a
ptr
orref
value to be directlypassed to
var
parameter (becausenkHiddenAddr
nodes are generatedwhen passing something to a
var
parameter), which is incorrect.The reason that this didn't cause many problems so far is that
var
,ref
, andptr
are all pointers underneath for the C target, and thatcgen
doesn't inspect the type of nodes in many cases.The collapsing done directly in
semexpr
is removed and the one done intransf
is adjusted:DerefExpr( Addr(x) )
andAddr( DerefExpr(x) )
(both areexpressions explicitly provided by the user) are collapsed -- the
latter one only when
x
is ofptr
type.HiddenDeref( HiddenAddr(x) )
is always known to besafe, the behaviour is kept. Because of a
cgen
issue, it's currentlyalso required.
Unconditional collapsing of all address-of + deref expression is now
performed inside the C code-generator, because it is known that the
operands to all dereference operations map to C pointers at that point.
Details
The compiler targets C89, where dereferencing a pointer requires a
pointer to complete type, even when the result is immediately passed to
an address-of operation (i.e.
&(*x)
).cgen
now requests the completetype whenever emitting a deref.