Bug 8651 – Slice op Slice throws exceptions (not errors), and nothrow
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-09-13T08:42:00Z
Last change time
2013-06-07T21:06:28Z
Keywords
pull
Assigned to
nobody
Creator
monarchdodra
Comments
Comment #0 by monarchdodra — 2012-09-13T08:42:59Z
2 related problems:
First
--------
import std.stdio;
void main()
{
try
{
int[] b = new int[](10);
b[] = 5;
b[0..6] = b[4..10];
}
catch(Exception e)
{
writeln(e);
}
writeln("finish");
}
--------
The built-in range assign will throw an Exception when it fails. This should be an Error.
Second
--------
nothrow void foo(int[] a)
{
a[] = a[];
}
nothrow void bar(int[] a)
{
a[] += a[];
}
--------
_arraySliceSliceAddass_i is not nothrow
function main.bar 'bar' is nothrow yet may throw
--------
This is doubly problematic:
First, these methods should throw Errors, so the code should compile.
Two, ironically, []+=[] currently doesn't throw anything, and []=[] throws an exception, yet it is the []+=[] version that doesn't compile.
Comment #1 by monarchdodra — 2012-09-15T23:53:18Z
Also, simple SlicoOp operations should be nothrow:
nothrow void foo(int[] a)
{
a[] += 5;
}
Error: _arrayExpSliceAddass_i is not nothrow
Error: function main.foo 'foo' is nothrow yet may throw
nothrow void foo(int[] a)
{
a[] &= 5;
}
Error: _arrayExpSliceAddass_i is not nothrow
Error: function main.foo 'foo' is nothrow yet may throw
Comment #2 by github-bugzilla — 2012-09-25T16:34:27Z
Comment #3 by bearophile_hugs — 2012-09-25T16:43:44Z
And someday even [1,2].dup will be nothrow.
Comment #4 by monarchdodra — 2012-09-25T23:26:30Z
(In reply to comment #3)
> And someday even [1,2].dup will be nothrow.
Doesn't dup allocate?
Comment #5 by monarchdodra — 2012-12-17T00:10:00Z
(In reply to comment #0)
> 2 related problems:
>
> First
> --------
> import std.stdio;
> void main()
> {
> try
> {
> int[] b = new int[](10);
> b[] = 5;
> b[0..6] = b[4..10];
> }
> catch(Exception e)
> {
> writeln(e);
> }
> writeln("finish");
> }
> --------
> The built-in range assign will throw an Exception when it fails. This should be
> an Error.
Confirmed fixed.
> Second
> --------
> nothrow void foo(int[] a)
> {
> a[] = a[];
> }
>
> nothrow void bar(int[] a)
> {
> a[] += a[];
> }
> --------
> _arraySliceSliceAddass_i is not nothrow
> function main.bar 'bar' is nothrow yet may throw
> --------
> This is doubly problematic:
> First, these methods should throw Errors, so the code should compile.
> Two, ironically, []+=[] currently doesn't throw anything, and []=[] throws an
> exception, yet it is the []+=[] version that doesn't compile.
!!!!!!!!
This is NOT FIXED.
!!!!!!!!
This is very strange, because arraySliceSliceAddass_i *is* marked as nothrow. However, when calling "a[] += a[]", I still get:
----
Error: _arraySliceSliceAddass_l is not nothrow
----
I'm not sure what to make about this? Maybe the "nothrow" info is lost in the "extern C" ?
If I place the code as a unittest *inside* "src/rt/arrayint.d", then it passes. But outside of that source, then... It doesn't compile.
We'd need one of the compiler guys (or just people that understand C and linking better than I do) to investigate.
Comment #6 by yebblies — 2013-01-01T22:09:31Z
(In reply to comment #5)
>
> !!!!!!!!
> This is NOT FIXED.
> !!!!!!!!
>
> This is very strange, because arraySliceSliceAddass_i *is* marked as nothrow.
> However, when calling "a[] += a[]", I still get:
> ----
> Error: _arraySliceSliceAddass_l is not nothrow
> ----
>
> I'm not sure what to make about this? Maybe the "nothrow" info is lost in the
> "extern C" ?
>
> If I place the code as a unittest *inside* "src/rt/arrayint.d", then it passes.
> But outside of that source, then... It doesn't compile.
>
> We'd need one of the compiler guys (or just people that understand C and
> linking better than I do) to investigate.
Being C functions, the nothrowness is not part of the mangled name, otherwise that change would have caused lots of link failures. Inside the compiler (arrayop.c) a dummy function declaration is created with the correct name, and a call is inserted in place of the array op.
This function declaration needs to be changed for the compiler to pick it up as nothrow, and it will need to be manually verified that the nothrowness matches at both ends for each function.
A lot of druntime functions should probably have D linkage to prevent mistakes like this.
Comment #7 by k.hara.pg — 2013-06-06T19:10:06Z
*** Issue 6311 has been marked as a duplicate of this issue. ***
Comment #8 by k.hara.pg — 2013-06-06T19:10:07Z
*** Issue 9933 has been marked as a duplicate of this issue. ***
Comment #9 by k.hara.pg — 2013-06-06T20:46:04Z
A while ago, built-in array-op implementations has been changed to @trusted nothrow by the druntime fix:
https://github.com/D-Programming-Language/druntime/pull/306
But, as yebblies said in comment #6, this still needs compiler fix.
I opened a new pull request for the compiler fix.
https://github.com/D-Programming-Language/dmd/pull/2141
(In reply to comment #6)
> (In reply to comment #5)
> A lot of druntime functions should probably have D linkage to prevent mistakes
> like this.
From 2.063, we can use pragma(mangle). Using it could add D linkages to the druntime functions with hiding internal module packages.
Comment #10 by github-bugzilla — 2013-06-07T21:06:08Z