Open codesculpture opened 1 month ago
Summary: The analyzer incorrectly throws an .address
position error when a native call is made with an undefined getter, even though the getter error should be the only one reported. This issue was discovered while trying to fix a related issue.
I found the root cause of this issue and i actually tried to fix this, but i planned to fix this seperately once i landed this
(am not good at writing issue title, feel free to edit)
I had a thought while reasoning about this issue, we recently "supported" .cast()
on Pointers here
But i think thats a existing "bug" which we just fixed (i.e its not something we added to support, it should have worked before)
Because as far as i understand "Address Position" Error, We are only allowing .address on leaf native call.
From the above statement, .address.cast()
should have worked before since still the .address is called on native leaf call.
Also we should allow .address.a.b.c
these on native leaf call, if such a,b,c exists.
The cfe is now allowing such expression, this been landed while fixing this https://github.com/dart-lang/sdk/issues/56462
So now analyzer should do the same.
If we dont allow such these expression address.a.b.c
, then the definition of error should be different from what we have already "Address Position", it should be more like "Address member access is prohibited except cast"
But i dont think this is what we intended to.
Feel free to correct me. @dcharkes
Requested CL (this is my first direct cl which was created through git cl upload
, previously copybara helped me) here,
based on this below statement
Also we should allow .address.a.b.c these on native leaf call.
If we dont allow such these expression
address.a.b.c
, then the definition of error should be different from what we have already "Address Position", it should be more like "Address member access is prohibited except cast"
It should be like this. .address
is not a real expression, it changes how the FFI call works.
throws 2 errors by the analyzer
1. ERROR|COMPILE_TIME_ERROR|ADDRESS_POSITION|9|17|7|The '.address' expression can only be used as argument to a leaf native external call. 2. ERROR|COMPILE_TIME_ERROR|UNDEFINED_GETTER|9|25|2|The getter 'cc' isn't defined for the type 'Pointer<Int8>'.
But expected is only one error
1. ERROR|COMPILE_TIME_ERROR|UNDEFINED_GETTER|9|25|2|The getter 'cc' isn't defined for the type 'Pointer<Int8>'.
I think we would expect two errors here. They are separate errors, not one error causing the next error. Pointer
doesn't have a .cc
field. And .address
can only be the last expression (except for cast) for arguments of a leaf call.
You could compare it for example to trying to call a private method in Java or C++ and passing the wrong argument type to that method. You'd get an error that the method is private, and that the argument type is wrong.
I think ADDRESS_POSITION
message should maybe be updated to say The '.address' expression can only be used as argument to a leaf native external call. The '.address' expression must be the direct argument or be used as '.address.cast()'.
Or maybe it should not be in the error message itself, but in the dartdoc comment of .address
. And it should then also be in the published docs for the analyzer message @MaryaBelanger.
Well, now it makes sense. Then analyzer is doing the right job, but cfe is the one still buggy. We can close this and track the cfe issue in new issue ticket? @dcharkes
Thanks @dcharkes for clearing this, i think updating this error message would clearly indicate its purpose.
Well, now it makes sense. Then analyzer is doing the right job, but cfe is the one still buggy.
You can just make a PR without a bug report if you want to work on it right away. It saves who follow the bug reports on this repository an email. 😉
We can close this and track the cfe issue in new issue ticket?
We can update this issue to make it track updating the docs.
Btw, am just trying to understand the issue, If we really dont want anyone to access Pointer's address (which is int), or any members (except cast), why cant we just make them as private or if not used internally we can remove them. I understand it somehow used, but am not sure how.
Any previous references or issue regarding this also helps me to understand.
Btw, am just trying to understand the issue, If we really dont want anyone to access Pointer's address (which is int), or any members (except cast), why cant we just make them as private or if not used internally we can remove them. I understand it somehow used, but am not sure how.
Any previous references or issue regarding this also helps me to understand.
You can find references in the following way:
git blame
on the relevant lines of code in the analyzer and CFE (you can see this on GitHub).@dcharkes
When constructing new Arguments(listOfExpressions)
, where every expression's location
in listOfExpression
is being set to null after the construction of Arguments
, is there any way to hold the location
of every expression even if its constructed for a new Arguments
@dcharkes
When constructing new
Arguments(listOfExpressions)
, where every expression'slocation
inlistOfExpression
is being set to null after the construction ofArguments
, is there any way to hold thelocation
of every expression even if its constructed for a newArguments
Where is it being set to null? Why is it being set to null? Please add a reference to the code that does it.
newArguments
's every element (Expression
) has location, but after it passed to construct Arguments
its been just set to null, and i see that Arguments
constructor is re-assigning parent of every argument initially in its implementation, i just dived this much. Just in case if it helps.
@dcharkes
I faced consequence of this as an issue while reporting cfe error, where after this transformation, node.location?.file where the file is being null, thus error cannot point the file which belongs to.
newArguments
's every element (Expression
) has location, but after it passed to constructArguments
its been just set to null, and i see thatArguments
constructor is re-assigning parent of every argument initially in its implementation, i just dived this much. Just in case if it helps.
Maybe @jensjoha or @chloestefantsova knows the answer to this.
Seems location is not intentionally set to "null", but it is a getter which will get its location based on its parent, but Arguments
constructor is resetting its parent and then it might considered to be a orphan node, hence no location can be derived?
The constructed StaticInvocation
is orphan while walking here
https://github.com/dart-lang/sdk/blob/main/pkg%2Fvm%2Flib%2Fmodular%2Ftransformations%2Fffi%2Fuse_sites.dart#L538-L539 which makes sense.
Hi @dcharkes, Any update on updating docs?
TODO
.address
should mention or show an example of using.cast()
.ADDRESS_POSITION
documentation should mention.cast()
.Original bug report:
While trying to fix this, I found the below code is
throws 2 errors by the analyzer
But expected is only one error
FYI @dcharkes