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
Issue15702: prohibit implicit conversion to void[] in @safe code if array elements have indirection #5468
Conversation
auto tn = t.nextOf(); | ||
if (et.hasPointers() && tn.ty == Tvoid && sc.func.setUnsafe()) | ||
{ | ||
e.error("cannot implicitly convert expression (%s) of type %s with indirections to %s in @safe code", |
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.
I would rather "cannot implicitly convert expression (%s) of type %s to %s in @safe code because the type contains indirections"
.
And converting to const(void)[]
should still work. Is there a test case?
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.
Fixed the error message.
And you're right, I missed the const(void)[]
case. Fixed.
No. A cast doesn't make anything |
Indeed, allowing the cast leaves us in no better position. We won't be able to have Socket.receive |
void[] arr = [ new Object() ]; | ||
} | ||
|
||
void unsafeFun() @system |
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.
I would split the acceptance test in compilable.
Also, could you provide additional tests for an array of:
- struct with a static array (should be accepted);
- struct with a pointer member (rejected);
- struct with a dynamic array member (rejected);
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.
Makes sense. Will do that when I get home later.
OK, will add code to reject explicit casts too. Gotta run now, will get to this later today. |
Don't forget it's not just casts to |
Updated code to reject all casts (explicit and implicit) from |
Ran out of time to work on the test cases... will update tomorrow, maybe. |
You've removed the implicit conversion check. And I'm pretty sure the cast safety checking is done in CastExp.semantic. |
Implicit conversions are still caught because But would that still apply if I moved the code to |
Updated code and rebased. The test cases still need some work, but will have to get to that later, gotta run now. |
Gah, looks like it's not as simple as I thought, since nested arrays like |
…array has indirections.
Reworked the fix. Haven't updated the tests yet, because the current code is rather ugly, particularly in |
Not to mention, |
Wait, doesn't this fix the wrong end of the equation? Why exactly would it be the T* to void* conversion that is unsafe (or equivalently, T[] to void[])? Using You've asked for a thorough look at |
The original solution was to fix You're right, though, that we probably need to find a more principled argument for (or against) this solution before committing to anything. |
As a usability compromise, still allow explicit casting to
void[]
in@safe
code. Not 100% sure about this. Maybe it's better to completely prohibit all such casts since they usually occur in I/O functions calling C APIs, which almost certainly means overwriting pointers with arbitrary external data.Note that implicitly casting arrays with no indirections is still allowed, so any code breakage will only be in places where the code is already breaking
@safe
.Also, not 100% sure this is the right place in the compiler to put this check, but it seems to be the place that needs minimal code changes.