[Issue 17448] Move semantics cause memory corruption and cryptic bugs

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17448

--- Comment #28 from Tomer Filiba (weka)  ---
My point is, @safe is so constrained that it's practically unusable, so I don't
consider it a viable solution for this problem.

--


[Issue 17448] Move semantics cause memory corruption and cryptic bugs

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17448

--- Comment #27 from Tomer Filiba (weka)  ---
(In reply to Andrei Alexandrescu from comment #25)
> > So... more special cases?
> 
> That's a straight use of scope per DIP 1000, in fact the very design intent:
> scope in a function signature specifies the function won't escape the
> parameter.

I don't suppose this would help. It seems the & operator is just not allowed in
safe code:

void main() @safe {
int x;
auto tmp = // Error: cannot take address of local x in @safe
function
}

--


[Issue 18134] BitArray >>= broken when length % (8 * size_t.sizeof) == 0

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18134

github-bugzi...@puremagic.com changed:

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
 Resolution|--- |FIXED

--


[Issue 18134] BitArray >>= broken when length % (8 * size_t.sizeof) == 0

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18134

--- Comment #3 from github-bugzi...@puremagic.com ---
Commits pushed to master at https://github.com/dlang/phobos

https://github.com/dlang/phobos/commit/b211347454b70fdb5a539f3fd8bc82fcec846e70
Fix issue 18134 - BitArray right shift broken if length is multiple of
8*size_t.sizeof

https://github.com/dlang/phobos/commit/6264e40d8abbb411d4391b3cf8c4d2d4c69423e1
Merge pull request #6110 from byebye/issue_18134

Fix issue 18134 - BitArray right shift broken if length is multiple of
8*size_t.sizeof
merged-on-behalf-of: Jack Stouffer 

--


[Issue 17448] Move semantics cause memory corruption and cryptic bugs

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17448

Jonathan M Davis  changed:

   What|Removed |Added

 CC||issues.dl...@jmdavisprog.co
   ||m

--- Comment #29 from Jonathan M Davis  ---
(In reply to Tomer Filiba (weka) from comment #27)
> I don't suppose this would help. It seems the & operator is just not allowed
> in safe code:
> 
> void main() @safe {
> int x;
> auto tmp = // Error: cannot take address of local x in @safe
> function
> }

That code becomes @safe with -dip1000, because then it's inferred as scope, and
the compiler verifies that it doesn't escape, whereas without DIP 1000 and its
improvements to scope, the compiler doesn't have any way to ensure that the
resulting pointer is used in an @safe manner. So, DIP 1000 should have a fairly
large impact on how @safe certain operations are.

(In reply to Tomer Filiba (weka) from comment #28)
> My point is, @safe is so constrained that it's practically unusable, so I
> don't consider it a viable solution for this problem.

That would be highly dependent on what your code is doing and how willing you
are to vet code and mark functions @trusted where appropriate or use @trusted
lambdas to mark sections of code as @trusted (which isn't the most ideal
solution for marking a section of code as @trusted, but it's the best we have
right now).

 If you're constantly doing stuff like taking the address of a local variable,
then yes, @safe is going to be a miserable mess (though DIP 1000 may fix that).
But a lot of code can be @safe with no problem. It really depends on the type
of stuff your code is doing.

--


[Issue 18541] comparison `==` of two typeid() should always be rewritten as a "is"

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18541

Ketmar Dark  changed:

   What|Removed |Added

 CC||ket...@ketmar.no-ip.org

--


[Issue 17448] Move semantics cause memory corruption and cryptic bugs

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17448

--- Comment #26 from Eyal  ---
What solution is there for this use-case then?

We need objects to register themselves (i.e: set out-of-scope pointers to point
at them) and RAII-wise have them de-register themselves.  While they are
registered, we need a guarantee that they won't be moved.

Doesn't sound like D has any solution for us here?

1) We can't use classes, because:
1.A) they are hard to use without GC
1.B) cannot reasonably nest classes so they re-use the same allocation as the
container class
1.C) cannot easily allocate them on the stack

2) We can't use structs, because there's no way to make sure structs aren't
moved when they're registered.

In my experience, this use-case of registered objects is extremely common.

Immovable structs, even if those require some effort, sound like they should be
well worth virtually any effort they'd require.

In practice, we use structs for this, and we don't really have a choice so
we'll keep using structs. But D is fighting us here, instead of helping us.

--


[Issue 1985] import expression should return ubyte[] not string

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=1985

--- Comment #11 from anonymous4  ---
I think it's better to replace import expression with intrinsic, say,
importText (like std.file.readText). This will also reduce grammar complexity
and remove second and rarely used meaning from the import keyword. Due to how
rarely import expression is used it confuses newcomers that are used only to
it's usage as module import statement.

--


[Issue 1985] import expression should return ubyte[] not string

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=1985

anonymous4  changed:

   What|Removed |Added

   Keywords||spec

--


[Issue 18564] core.demangle exception Range violation

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18564

johanenge...@weka.io changed:

   What|Removed |Added

   Keywords||industry
 CC||r.sagita...@gmx.de

--


[Issue 18564] core.demangle exception Range violation

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18564

johanenge...@weka.io changed:

   What|Removed |Added

   Keywords||mangling

--


[Issue 9983] inout type can not be used as a parameter for structure template

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=9983

Martin Nowak  changed:

   What|Removed |Added

 CC||c...@dawg.eu
   Severity|normal  |enhancement

--


[Issue 18561] postblit should allow writing const/immutable members just like constructors

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18561

--- Comment #4 from ajiesk...@gmail.com ---
(In reply to anonymous4 from comment #3)
> This passes:
> ---
> struct A
> {
> int a;
> this(int b) const { a=b; }
> }
> int main()
> {
> const A a;
> assert(a.a==0,"0");
> a.__ctor(1);
> assert(a.a==1,"1");
> return 0;
> }
> ---

I believe it should not. Yes, constructor should be able to do that, but only
when used as a constructor. But it is a separate issue from this one.

--


[Issue 18561] postblit should allow writing const/immutable members just like constructors

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18561

--- Comment #5 from Steven Schveighoffer  ---
(In reply to anonymous4 from comment #3)
> a.__ctor(1);

This is another bug. One should only be able to call const __ctor on a struct
once, before using it.

--


[Issue 18561] postblit should allow writing const/immutable members just like constructors

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18561

--- Comment #3 from anonymous4  ---
This passes:
---
struct A
{
int a;
this(int b) const { a=b; }
}
int main()
{
const A a;
assert(a.a==0,"0");
a.__ctor(1);
assert(a.a==1,"1");
return 0;
}
---

--


[Issue 18564] New: core.demangle exception Range violation

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18564

  Issue ID: 18564
   Summary: core.demangle exception Range violation
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: normal
  Priority: P1
 Component: druntime
  Assignee: nob...@puremagic.com
  Reporter: johanenge...@weka.io

Testcase:
```
import core.demangle;
import std.stdio;

void main() {
enum str =
"UVVUYUUY";

writeln(demangleType(str));
}
```

Instead of outputting the string, we get:
`core.exception.RangeError@core/demangle.d(230): Range violation`

(found by fuzz testing, but I get a range violation on the same line with a
real world type mangle too)

--


[Issue 18563] context pointer inside structs constness problems

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18563

Ketmar Dark  changed:

   What|Removed |Added

 CC||ket...@ketmar.no-ip.org

--


[Issue 18557] Types with 0 size should not be usable as aa key types

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18557

Ketmar Dark  changed:

   What|Removed |Added

 CC||ket...@ketmar.no-ip.org

--- Comment #3 from Ketmar Dark  ---
this patch breaks Variant: it is legal to use `This[This]` as a placeholder
type in Variant, and with the patch applied that code doesn't compiles anymore
('cause `This` is defined as `struct This;`).

adding real definition to `This` doesn't help too, 'cause then dmd errored with
"recursive template expansion".

--


[Issue 18565] New: std.regex Captures opAssign returns void since v2.079.0

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18565

  Issue ID: 18565
   Summary: std.regex Captures opAssign returns void since
v2.079.0
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: regression
  Priority: P1
 Component: phobos
  Assignee: nob...@puremagic.com
  Reporter: d.b...@webfreak.org

Before commit 59520969ef73eaf0691972ee00b389e5bbc4c8fb this code used to work:

---
import std.regex;

void main()
{
string str;
Captures!string match;
if (cast(bool)(match = str.matchFirst("a"))
 || cast(bool)(match = str.matchFirst("b"))) {}
}
---

and it performed the expected operations. However now the compilation fails
with:

---
a.d(7): Error: cannot cast expression match.opAssign(matchFirst(str, "a")) of
type void to bool
a.d(8): Error: cannot cast expression match.opAssign(matchFirst(str, "b")) of
type void to bool
---

--


[Issue 18542] DMD could generate better assembly for common range check idioms

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18542

Ketmar Dark  changed:

   What|Removed |Added

 CC||ket...@ketmar.no-ip.org

--


[Issue 17448] Move semantics cause memory corruption and cryptic bugs

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17448

--- Comment #30 from Andrei Alexandrescu  ---
Indeed it seems we are not supporting registration by address with ease for D
value types.

There are good reasons for that; by allowing value types to be moved around we
avoid a swath of complications and difficulties that C++ encounters with their
definition of rvalue references and move constructors. That C++ feature
complicates all code considerably and still has a variety of safety,
correctness, and efficiency issues (I am not exaggerating; all three problems
are present) that make the bread and butter of advanced C++ instructors
worldwide, including myself. I think we got the better deal there.

The disadvantage is that indeed an object can be born and die at different
addresses. So self-registering objects by address, or objects holding internal
pointers, do not work with automatic allocation. Such is the nature of
automatic allocation in D. 

(It should be noted that C++ has its own, distinct issues with self-registering
objects, to which I dedicate several slides in
http://erdani.com/index.php/training/mc1xd.)

Allow me to make a few suggestions for workarounds:

* Avoid automatic/stack allocation and also return by value. A struct may hold
internal pointers and a constant address as long as the memory it's in is not
automatic/stack. If you use raw memory in conjunction with functions such as
emplace and destroy, you have good control. As a perk, you avoid the creation,
copying, and destruction of spurious objects - which comes along with calls to
register/unregister, which I assume has a significant cost.

* Use a "cookie", not an address, in the registration. A classic registration
pattern returns a cookie/handle, usually an integer, which the object stores.
Then, the object passes that cookie back to the unregister function. In other
words, if the address of an object isn't invariant, let's define something that
is.

* Use dynamic allocation in conjunction with reference counting. I know this
has been mentioned and dismissed as too expensive, but I'm mentioning it for
completeness. Also, it's one of those cases in which engineering can go a long
way: use a high-performance allocator (for which we have a solid framework in
the standard library), duplicate objects lazily, etc.

If after exploring these and other solutions you come to the conclusion they
are not satisfactory, I encourage you to create a DIP. Two possible lines of
attack are:

(1) Allow specifying that an object can't be moved
(2) Allow a type to intercept its move by means of a nothrow hook

Drawing from extensive experience with Phobos and its very generic code, I can
tell you I foresee difficulties with (1). Anything that makes types "more
special than others" is bound to cause a smorgasbord of special handling in the
library. I think (2) would be a better angle because it encapsulates the
handling with the type.

Thanks!

--


[Issue 18566] New: const on method of nested data type is not applied to variables in context

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18566

  Issue ID: 18566
   Summary: const on method of nested data type is not applied to
variables in context
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: normal
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: timon.g...@gmx.ch

void main(){
int i = 0;
struct S{
int *fun()const pure{
return  // compiles, but shouldn't
}
}
}

The type of i within "fun" should be "const(int)".

--


[Issue 18562] expression is not evaluated when accessing manifest constant

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18562

Ketmar Dark  changed:

   What|Removed |Added

 CC||ket...@ketmar.no-ip.org

--


[Issue 18541] comparison `==` of two typeid() should always be rewritten as a "is"

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18541

--- Comment #9 from Ketmar Dark  ---
compiler transforms `==` for objects to virtual call, and dmd cannot
devirtualize calls (yet? ;-). so yeah, no inlining.

it is quite possible to rewrite the call into `e1 is e1 || .object.opEquals(e1,
e2)`, tho.


--- a/src/ddmd/opover.d
+++ b/src/ddmd/opover.d
@@ -30,6 +30,7 @@ import ddmd.globals;
 import ddmd.id;
 import ddmd.identifier;
 import ddmd.mtype;
+import ddmd.sideeffect;
 import ddmd.statement;
 import ddmd.tokens;
 import ddmd.visitor;
@@ -1162,7 +1163,7 @@ extern (C++) Expression op_overload(Expression e, Scope*
sc)
 if (!(cd1.cpp || cd2.cpp))
 {
 /* Rewrite as:
- *  .object.opEquals(e1, e2)
+ *  e1 is e2 || .object.opEquals(e1, e2)
  */
 Expression e1x = e.e1;
 Expression e2x = e.e2;
@@ -1176,12 +1177,38 @@ extern (C++) Expression op_overload(Expression e,
Scope* sc)
 if (cd2.isInterfaceDeclaration())
 e2x = new CastExp(e.loc, e.e2, t2.isMutable() ? to :
to.constOf());

+/* create temporaries, to avoid invalid rewriting of this:
+ *if (arr[i++] is obj || .object.opEquals(arr[i++],
obj)
+ * rewrite to:
+ *tmp1 = e1x, tmp2 = e2x, then use temps
+ */
+// load e1x to temporary
+auto tmp1 = copyToTemp(STCnodtor, "__opEqualsTmp1", e1x);
+auto e1xtmp = new CommaExp(e.loc, new
DeclarationExp(e.loc, tmp1), new VarExp(e.loc, tmp1));
+
+// load e2x to temporary
+auto tmp2 = copyToTemp(STCnodtor, "__opEqualsTmp2", e2x);
+auto e2xtmp = new CommaExp(e.loc, new
DeclarationExp(e.loc, tmp2), new VarExp(e.loc, tmp2));
+
+// e1 is e2
+auto expis = new IdentityExp(TOKidentity, e.loc, e1xtmp,
e2xtmp);
+
+// and use fresh varexps with temps (previous ones can be
changed by semanticing)
+e1x = new VarExp(e.loc, tmp1);
+e2x = new VarExp(e.loc, tmp2);
+
+// .object.opEquals(e1, e2)
 result = new IdentifierExp(e.loc, Id.empty);
 result = new DotIdExp(e.loc, result, Id.object);
 result = new DotIdExp(e.loc, result, Id.eq);
 result = new CallExp(e.loc, result, e1x, e2x);
+
+// expis || result
+result = new LogicalExp(e.loc, TOKoror, expis, result);
+
 if (e.op == TOKnotequal)
 result = new NotExp(e.loc, result);
+
 result = result.semantic(sc);
 return;
 }

--


[Issue 18560] find on infinite ranges is broken

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18560

Ketmar Dark  changed:

   What|Removed |Added

 CC||ket...@ketmar.no-ip.org

--


[Issue 18567] New: immutability hole related to context pointers accessed through const pure methods

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18567

  Issue ID: 18567
   Summary: immutability hole related to context pointers accessed
through const pure methods
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: critical
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: timon.g...@gmx.ch

DMD 2.079.0

void main(){
int i = 0;
struct S{
const(int)* fun()const pure{
return 
}
}
immutable S s;
static const(int)* foo(immutable(S) s)pure{
return s.fun();
}
immutable(int) *pi=foo(s);
import std.stdio;
writeln(*pi); // 0
i+=1;
writeln(*pi); // 1
}

I.e. the data *pi is typed as immutable(int), yet changes.

--


[Issue 18564] core.demangle exception Range violation

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18564

--- Comment #1 from Rainer Schuetze  ---
Did you try latest dmd master? There have been a couple of recent fixes that
look similar, e.g. https://issues.dlang.org/show_bug.cgi?id=18300 and
https://issues.dlang.org/show_bug.cgi?id=18208.

--


[Issue 17961] std.uni does not compile with -unittest -dip1000

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17961

--- Comment #11 from Carsten Blüggel  ---
(In reply to hsteoh from comment #10)
> Link: https://github.com/dlang/phobos/pull/6041

Due to lack of acceptance I closed PR
https://github.com/dlang/phobos/pull/6041.
Maybe https://github.com/dlang/phobos/pull/6212 will come to the rescue.

--


[Issue 14242] destruction of static arrays with elaborate destructor elements does not propagate attributes

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14242

Mike Franklin  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||slavo5...@yahoo.com
 Resolution|--- |WORKSFORME

--- Comment #1 from Mike Franklin  ---
This appears to have been fixed in 2.068.2.  I cannot reproduce it in the
latest compiler (2.079.0) either.  Resolving as WORKSFORME.

--


[Issue 18560] New: find on infinite ranges is broken

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18560

  Issue ID: 18560
   Summary: find on infinite ranges is broken
   Product: D
   Version: D2
  Hardware: x86_64
OS: Linux
Status: NEW
  Severity: enhancement
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: default_357-l...@yahoo.de

Consider:

assert(true.repeat.all != false);

We may expect this to hang indefinitely. We will certainly not expect it to
fail immediately!

What happens is this.

true.repeat is an infinite range. all searches for a place at which its
condition becomes false. For this, it employs find. Find uses "empty" to signal
success, ie.  it returns an empty range if the element was not found. However,
in this case find *cannot* return an empty range because the Repeat range type
can never be empty. It compiles anyways. This then leads to .empty concluding,
correctly, that find may never return an empty range, and immediately, without
evaluating its input range, returning false.

Either all must not be implemented on top of find, or find must be adjusted to
signal failure in some other way, possibly using a VariantN.

--


[Issue 18560] find on infinite ranges is broken

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18560

FeepingCreature  changed:

   What|Removed |Added

   Severity|enhancement |normal

--


[Issue 18560] find on infinite ranges is broken

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18560

--- Comment #1 from FeepingCreature  ---
The actual problem seems to be that expression.empty actually presumes that
expression terminates. So when .all checks for find.empty, it fails to account
for the case that find does not terminate, in which situation the behavior is
logically undefined.

--


[Issue 17448] Move semantics cause memory corruption and cryptic bugs

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17448

--- Comment #25 from Andrei Alexandrescu  ---
(In reply to Tomer Filiba (weka) from comment #24)
> > We should address this situation by having writeln take scope inputs. It 
> > does
> > not escape any pointers.
> 
> So... more special cases?

That's a straight use of scope per DIP 1000, in fact the very design intent:
scope in a function signature specifies the function won't escape the
parameter.

> > I think immovability is a red herring. The problem is a pointer is escaped
> > and it shouldn't be. Even if the struct were immovable, you could construct
> > other cases in which  gets messed up.
> 
> Of course I could *make* it fail, but that would require me doing memcpy or
> what not. It escapes the type system. I'm trying to make it work or fail
> inside the type system.
> 
> The whole point is that `struct S` cannot tell how people will use it. The
> author thought people would just do
> 
> void func() {
> auto s = S(100);
> // ...
> // when s goes out of scope it will cancel the callback
> }
> 
> The author tried to prevent people from shooting themselves in the foot by
> making the struct immovable. But then someone added a wrapper function that
> returns a `struct S`. This second author knew the struct is immovable and
> trusted the type system so his changes would either not compile, or compile
> but   never move the object. The code works in the happy flow, but when
> things go south, all of the sudden you get cryptic bugs that take many days
> -- and a lot of luck -- to track down.
> 
> In this specific example, the struct registers a timer to be called in XX
> seconds and kill the operation. Other examples could be a struct that adds
> itself to a link-list and removes itself when it's destroyed. 
> 
> It doesn't make sense that C++ gives me this guarantee, but D fools me into
> thinking my code is okay when in fact it isn't. It's not an implementation
> detail or an optimization -- it's a semantic guarantee.

What I'm saying is the problem is different: the address of this should not
escape a non-scope method (including the constructor), we're in a world of
trouble regardless whether we introduce a new feature regarding movability.

--


[Issue 18562] expression is not evaluated when accessing manifest constant

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18562

FeepingCreature  changed:

   What|Removed |Added

   Keywords||wrong-code

--


[Issue 18563] New: context pointer inside structs constness problems

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18563

  Issue ID: 18563
   Summary: context pointer inside structs constness problems
   Product: D
   Version: D2
  Hardware: x86_64
OS: Linux
Status: NEW
  Severity: enhancement
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: shac...@weka.io

The following program does not compile:
void main() {
struct S {
uint value;

~this() {
}
}

const S a = S(12);
S b = a;
}

test.d(10): Error: cannot implicitly convert expression a of type const(S) to S 

The reason is that the context pointer stored in a is const, and thus implies
that the context it points to is also const. This cannot be copied to the
non-const context pointer in b.

This context pointer is not, however, actually treated as const. The following
code compiles and passes:

unittest {
int i = 0;
struct S {
int n;
void fun() const {
i++;
}
}
const S s;
assert(i == 0);
s.fun();
assert(i == 1);
} 

Full discussion thread at
https://forum.dlang.org/thread/p7lp2b$1jod$1...@digitalmars.com

I would argue that the correct solution is to allow the assignment.

--


[Issue 17448] Move semantics cause memory corruption and cryptic bugs

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17448

--- Comment #24 from Tomer Filiba (weka)  ---
> We should address this situation by having writeln take scope inputs. It does
> not escape any pointers.

So... more special cases?

> I think immovability is a red herring. The problem is a pointer is escaped
> and it shouldn't be. Even if the struct were immovable, you could construct
> other cases in which  gets messed up.

Of course I could *make* it fail, but that would require me doing memcpy or
what not. It escapes the type system. I'm trying to make it work or fail inside
the type system.

The whole point is that `struct S` cannot tell how people will use it. The
author thought people would just do

void func() {
auto s = S(100);
// ...
// when s goes out of scope it will cancel the callback
}

The author tried to prevent people from shooting themselves in the foot by
making the struct immovable. But then someone added a wrapper function that
returns a `struct S`. This second author knew the struct is immovable and
trusted the type system so his changes would either not compile, or compile but
  never move the object. The code works in the happy flow, but when things go
south, all of the sudden you get cryptic bugs that take many days -- and a lot
of luck -- to track down.

In this specific example, the struct registers a timer to be called in XX
seconds and kill the operation. Other examples could be a struct that adds
itself to a link-list and removes itself when it's destroyed. 

It doesn't make sense that C++ gives me this guarantee, but D fools me into
thinking my code is okay when in fact it isn't. It's not an implementation
detail or an optimization -- it's a semantic guarantee.

--


[Issue 17448] Move semantics cause memory corruption and cryptic bugs

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17448

--- Comment #23 from Andrei Alexandrescu  ---
(In reply to Tomer Filiba (weka) from comment #21)
> Walter, the @safe-ty aspects of the issue are one thing. In real code, @safe
> is hardly workable, i.e.
> 
> void main() {
> int x;
> writeln();// Error: cannot take address of local `x` in `@safe`
> function `main`
> }

We should address this situation by having writeln take scope inputs. It does
not escape any pointers.

> It's either you go whole nine yards and implement a full-blown
> borrow-checker like rust, or impose very strict (and sometimes arbitrary)
> limitations that practically make it unusable.

We believe there's a third way, but the burden of proof is indeed on us.

> But @safe-aside, the *more important* aspect here that the compiler must
> provide a guarantee of *never moving* structs that are marked `@disable
> this(this)` or `pragma(immovable)` or with any other syntax. It's a semantic
> contract with the compiler, not an optimization.
> 
> So for example, a desired outcome might be for this not to compile:
> 
> pragma(immovable) struct S {
> int x;
> }
> S func() {
> return S(100);
> }
> void main() {
> S s = func();
> }
> 
> Should the compile be unable to rewrite this as pass-by-reference. 
> 
> I hope it makes the problem clear, again, @safe is really not the issue
> here. It's the guarantees provided by move semantics.

I think immovability is a red herring. The problem is a pointer is escaped and
it shouldn't be. Even if the struct were immovable, you could construct other
cases in which  gets messed up.

(Thinking of supporting the notion of immovable objects - it would have huge
ripples. Already supporting structs with @disable this(); and/or @disable
this(this); in the standard library is a recurring (and still ongoing)
nightmare. Dealing with immovability on top of that would make a lot of code a
lot heavier.)

--


[Issue 18560] find on infinite ranges is broken

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18560

--- Comment #2 from FeepingCreature  ---
No, this is the actual problem!

struct Struct
{
enum Enum = 5;
}

bool fooEvaluated;

Struct foo() { fooEvaluated = true; return Struct(); }

assert(foo().Enum == 5);

assert(fooEvaluated == true);

Should this last assert pass? Right now it doesn't, because foo() is never
evaluated because Enum is enum. This means that in any and all, the find()
never runs.

--


[Issue 18562] New: expression is not evaluated when accessing manifest constant

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18562

  Issue ID: 18562
   Summary: expression is not evaluated when accessing manifest
constant
   Product: D
   Version: D2
  Hardware: x86_64
OS: Linux
Status: NEW
  Severity: normal
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: default_357-l...@yahoo.de

Consider:

struct Struct
{
enum Enum = 5;
}

Struct foo()
{
while (true) { }
return Struct();
}

void main()
{
auto value = foo().Enum;
assert(false);
}

The assert trips, despite the fact that foo() should loop indefinitely, because
the compiler optimizes away the call to foo entirely. This is highly
unintuitive and also responsible for bug #18560 .

Is this really intended?

--


[Issue 18560] find on infinite ranges is broken

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18560

ag0ae...@gmail.com changed:

   What|Removed |Added

   Keywords||wrong-code
 CC||ag0ae...@gmail.com

--- Comment #3 from ag0ae...@gmail.com ---
That makes it a codegen bug. foo isn't pure so it must be executed for the side
effects. The compiler cannot skip the execution just because the result isn't
really used.

--


[Issue 18561] postblit should allow writing const/immutable members just like constructors

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18561

Steven Schveighoffer  changed:

   What|Removed |Added

   Hardware|x86 |All
 OS|Windows |All

--


[Issue 18561] postblit should allow writing const/immutable members just like constructors

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18561

Steven Schveighoffer  changed:

   What|Removed |Added

 Status|RESOLVED|REOPENED
 CC||schvei...@yahoo.com
 Resolution|DUPLICATE   |---
Summary|postblit behaves|postblit should allow
   |inconsistently with |writing const/immutable
   |constants   |members just like
   ||constructors

--- Comment #2 from Steven Schveighoffer  ---
I think the OP has a point here.

A more direct example:

struct S
{
   const char[] t;
   this(this)
   {
  t = t.dup; // this should be allowed
  // t[0] = 'w'; // this should not
   }
}

S s;

// Should be OK, calls postblit, s2 is new data.
auto s2 = s;

// error cannot overwrite const (does not call postblit). This happens already
s = s2;

essentially, when READING `this`, all normal rules apply. When WRITING members
of `this`, everything should be considered tail-X, where X is const, immutable,
etc. If we have any immutable or const data as members, the compiler should
have already forbade it if you couldn't overwrite it before the postblit.

It's the same as constructors, but for constructors, `this` didn't exist yet.
If we get to a postblit on a type that has const or immutable data, we have the
same guarantee.

This does not address postblits being called on const data types (with `this`
being mutable during the postblit). That is a different bug.

--


[Issue 18561] New: postblit behaves inconsistently with constants

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18561

  Issue ID: 18561
   Summary: postblit behaves inconsistently with constants
   Product: D
   Version: D2
  Hardware: x86
OS: Windows
Status: NEW
  Severity: enhancement
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: ajiesk...@gmail.com

This compiles:

import std.array;
import std.stdio;
import std.algorithm;
struct placeAtWorldMap
{   char[] title;
int[2] coordsMicroDeg;

this(this)
{   title = title.dup;
}
}
void main()
{   char[] title = "London bridge".dup;
const place = placeAtWorldMap(title, [51_508_038, -87_693]);
const samePlace = place;
"falling down ".copy(title);
place.title.writeln; // falling down
samePlace.title.writeln; // London bridge
readln;
}

This does not:

import std.array;
import std.stdio;
import std.algorithm;
struct placeAtWorldMap
{   const char[] title;
int[2] coordsMicroDeg;

this(char[] name, int[2] coords)
{   // you can assign const members here
this.title = name; 
this.coordsMicroDeg = coords;
}

this(this)
{   // remove to compile
title = title.dup;// cannot modify ´const´ expression ´this.title´
}
}

void main()
{   char[] title = "London bridge".dup;
const place = placeAtWorldMap(title, [51_508_038, -87_693]);
const newPlace = placeAtWorldMap("Big Ben".dup, [51_500_749, -124_611]);
const samePlace = place;
"falling down ".copy(title);
place.title.writeln; // falling down
samePlace.title.writeln; // London bridge (but falling down without the
postblit causing the error)
newPlace.title.writeln;  // Big Ben
}

Postblits behave inconsistently with constants. As shown in the second example,
it cannot modify members which are declared as const. But if that is wrong, the
first one should compile neither, as all the members should be treated as const
when the whole variable is const.

Postblits should behave either like member functions -no mutation of const
whatsover- or like constructors -allow mutating the variable once-.

I tend to think it should be the latter of the two, since postblits are
initializing an object, just like constructiors.

--


[Issue 18551] Improve hint for "does not override any function

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18551

--- Comment #2 from github-bugzi...@puremagic.com ---
Commits pushed to master at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/89243bdc93ef220f85e53d18a0c8521fc43afead
Fix Issue 18551 - Improve hint for does not override any function

https://github.com/dlang/dmd/commit/bc85c44e819a9ceaf14c33970a07e1105aaf5a93
Merge pull request #7984 from RazvanN7/Issue_18551

Fix Issue 18551 - Improve hint for does not override any function
merged-on-behalf-of: Mike Franklin 

--


[Issue 18561] postblit behaves inconsistently with constants

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18561

ag0ae...@gmail.com changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||ag0ae...@gmail.com
 Resolution|--- |DUPLICATE

--- Comment #1 from ag0ae...@gmail.com ---
(In reply to Ajieskola from comment #0)
> Postblits behave inconsistently with constants. As shown in the second
> example, it cannot modify members which are declared as const. But if that
> is wrong, the first one should compile neither, as all the members should be
> treated as const when the whole variable is const.

The first example shouldn't compile.

`title = title.dup;` doesn't do any actual harm, because you're not altering
the original. But consider `title[0] = 'W';`. Now you're changing the original
`title` to "Wondon bridge", and you're doing it through a `const` reference.
That should not be possible. Even worse, the original title could be
`immutable`:


import std.stdio;
struct placeAtWorldMap
{   char[] title;

this(this)
{   title[0] = 'W'; /* ! */
}
}
void main()
{   immutable char[] title = "London bridge".dup;
const place = const placeAtWorldMap(title);
const samePlace = place;
title.writeln; // Wondon bridge
}


Issue 18357 already covers that problem. Closing as DUPLICATE. Feel free to
revert if you think it's not an exact duplicate.

*** This issue has been marked as a duplicate of issue 18357 ***

--


[Issue 18357] can break immutable with postblit

2018-03-06 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18357

ag0ae...@gmail.com changed:

   What|Removed |Added

 CC||ajiesk...@gmail.com

--- Comment #1 from ag0ae...@gmail.com ---
*** Issue 18561 has been marked as a duplicate of this issue. ***

--