Bug 9539 – Wrong implicit conversion of array to pointer

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-02-19T14:13:00Z
Last change time
2013-05-13T06:51:28Z
Keywords
pull, wrong-code
Assigned to
nobody
Creator
andrej.mitrovich

Comments

Comment #0 by andrej.mitrovich — 2013-02-19T14:13:47Z
void f(int** ptr) { assert(**ptr == 10); } void main() { int* i = new int; *i = 10; int*[1] x = [i]; f(&x[0]); } 2.060: $ dmd test.d > 2.061 $ dmd test.d > core.exception.AssertError@test(5): Assertion failure 2.062 $ dmd test.d > core.exception.AssertError@test(5): Assertion failure Same thing happens when you use 'x.ptr'.
Comment #1 by k.hara.pg — 2013-02-20T23:48:00Z
(In reply to comment #0) > void f(int** ptr) > { > assert(**ptr == 10); > } > > void main() > { > int* i = new int; > *i = 10; > int*[1] x = [i]; > f(&x[0]); > } More simple case: int*[1] x; int* p = new int; x = [p]; // is wrongly rewritten to: x[] = [p].ptr printf("p = %p, x[0] = %p\n", p, x[0]); assert(p == x[0]); // fails!? ---- This is horribly serious problem. The root issue is in TypeDArray::implicitConvTo. FROM THE BEGINNING of D2, an implicit conversion from dynamic array to its element pointer type as a deprecated feature. int[] arr; int* p; p = arr; // is expected to rewrite to p = arr.ptr BUT, it was completely broken FROM THE BEGINNING of D2. Instead of the expected behavior, dynamic array can be convertible to its element type. int*[] arr = [null]; int* p; p = arr; // bad! printf("p = %p, arr.ptr = %p\n", p, arr.ptr); It has been wrongly accepted in long time if '-d' switch is specified. Then, from 2.061, the situation has become worse by "informational deprecated error in default". Above code would be _silently_ accepted in default, and compiler outputs wrong-code. ---- But, we cannot *fix* TypeDArray::implicitConvTo to implement the deprecated feature, because it breaks phobos building. In std.process line 367: scope(exit) if (exists(filename)) remove(filename); // <---- Today, it calls std.file.remove in here. std.stdio.file line 413: void remove(in char[] name) But std.process also imports core.stdc.stdio through std.stdio. In there another 'remove' is defined. core.stdc.stdio line 453: int remove(in char* filename); // <---- After *fixing* the deprecated feature, the 'remove' call in std.process will match both 'remove's that defined in different modules, and it will raise an error according to overload set resolution rule. std\process.d(367): Error: std.file.remove at std\file.d(413) conflicts with core.stdc.stdio.remove at C:\Users\khara\dmd2\src\druntime\import\core\stdc\stdio.d(453) ---- So as a conclusion, we should just remove the deprecated "array to pointer conversion" feature, rather than fixing broken deprecated feature that already outdated.
Comment #2 by k.hara.pg — 2013-02-21T00:10:20Z
Comment #3 by github-bugzilla — 2013-02-21T16:47:54Z
Commit pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/beee8e88c4bdff61087cd34353481e7c364690d3 fix Issue 9539 - Regression (2.061): Wrong-code on static array pointer
Comment #4 by bearophile_hugs — 2013-02-21T18:22:08Z
From the commit: > the deprecated implicit conversion feature already being a cancer in D2 type system. Thank you Hara for fixing such things. Implicit type conversions are dangerous.
Comment #5 by andrej.mitrovich — 2013-03-01T13:19:34Z
Another person has ran into this recently. Shouldn't this be a good reason for an emergency release of a patched 2.062? It's really an awful bug.
Comment #6 by k.hara.pg — 2013-04-10T22:01:32Z
*** Issue 9518 has been marked as a duplicate of this issue. ***
Comment #7 by k.hara.pg — 2013-04-11T01:54:36Z
*** Issue 9916 has been marked as a duplicate of this issue. ***
Comment #8 by andrej.mitrovich — 2013-05-13T06:51:28Z
*** Issue 10072 has been marked as a duplicate of this issue. ***