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
Issue 12622 - Purity, @safe not checked for pointers to functions #3489
Conversation
} | ||
if (tf->trust <= TRUSTsystem && sc->func->setUnsafe()) | ||
{ | ||
error("safe function '%s' cannot call system %s '%s'", sc->func->toPrettyChars(), p, e1->toChars()); | ||
return new ErrorExp(); |
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.
In order to invoke nothrow check later, don't return ErrorExp.
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.
Why invoke nothrow check later? Once there's an error detected, no need for further checking. And errors need to be propagated, not ignored.
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.
Because of the consistency.
Currently, for direct function calls, the failure of checkPurity
and checkSafety
is not translated to ErrorExp
.
if (f)
{
checkPurity(sc, f); // purity check failure is ignored
checkSafety(sc, f); // safety check failure is ignored
f->checkNestedReference(sc, loc);
}
Because of that, nothrow attribute violation is properly checked later.
I think that function pointer calls should follow the behavior.
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 believe it is a bug that the purity/safety checks ignore the error rather than propagate it. Those errors are not warnings or suggestions, they need to be propagated. I want to get to the point where we can remove the global.errors checks.
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 also think propagating error would be better. But, current nothrow check is separated from purity/safety check, and if we return ErrorExp against purity/safety violation, it will hide nothrow error.
fail12622.d(23): Error: pure function 'fail12622.foo' cannot call impure function pointer 'fp'
fail12622.d(23): Error: safe function 'fail12622.foo' cannot call system function pointer 'fp'
fail12622.d(25): Error: pure function 'fail12622.foo' cannot call impure function pointer 'fp'
fail12622.d(25): Error: safe function 'fail12622.foo' cannot call system function pointer 'fp'
fail12622.d(27): Error: pure function 'fail12622.foo' cannot call impure function 'fail12622.bar'
fail12622.d(27): Error: safe function 'fail12622.foo' cannot call system function 'fail12622.bar'
fail12622.d(23): Error: 'fp' is not nothrow // These errors will disappear
fail12622.d(25): Error: 'fp' is not nothrow // if we return ErrorExp
fail12622.d(27): Error: 'fail12622.bar' is not nothrow // against purity or safety
fail12622.d(19): Error: function 'fail12622.foo' is nothrow yet may throw // violations.
I'd keep this code, because it would generate better diagnostic. And we can improve nothrow check mechanism in the future.
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.
Then I suggest combining the safety/purity/nothrow checks so they all done together, rather than not propagating the error.
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.
Yes, we should do it. But we would need more work to do it.
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'm not sure whether a debatable, slight improvement in diagnostics is worth compromising the internal structure of the frontend.
(Debatable, as unfortunately still quite often only the first error message is reliable, especially when compiling multiple modules at once. If anything, we should try to make error handling more methodical at this point, even if some special (test) cases possibly suffer a slight reduction in diagnostics quality.)
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.
Internal structure improvement is still work in progress - more much work is necessary. So this trivial compromising won't become serious.
On the other hand, the small diagnostic improvement can be fixed with the test case. We can improve internals without downgrade the compiler output.
I want to get the small, but reliable improvement.
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.
OK... I gave up the better diagnostic. It should be fixed later.
That was quick! |
Rebased onto the new |
Auto-merge toggled on |
Issue 12622 - Purity, @safe not checked for pointers to functions
Thanks. |
https://issues.dlang.org/show_bug.cgi?id=12622