Thread overview
[Issue 17363] @safety hole due to $ caching in slice expressions
May 02, 2017
anonymous4
May 03, 2017
anonymous4
May 03, 2017
kinke@gmx.net
May 04, 2017
anonymous4
Mar 11, 2018
Walter Bright
Mar 11, 2018
Walter Bright
May 02, 2017
https://issues.dlang.org/show_bug.cgi?id=17363

anonymous4 <dfj1esp02@sneakemail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |safe

--
May 03, 2017
https://issues.dlang.org/show_bug.cgi?id=17363

anonymous4 <dfj1esp02@sneakemail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://issues.dlang.org/sh
                   |                            |ow_bug.cgi?id=17364

--- Comment #1 from anonymous4 <dfj1esp02@sneakemail.com> ---
The slice should be loaded before evaluation of slice arguments, then length is safe to cache, see issue 17364.

--
May 03, 2017
https://issues.dlang.org/show_bug.cgi?id=17363

--- Comment #2 from kinke@gmx.net ---
> The slice should be loaded before evaluation of slice arguments, then length is safe to cache, see issue 17364.

Your argument for loading & caching length and pointer before evaluating the
bounds expressions being?
I mean it's perfectly safe and IMHO less awkward the other way around, loading
the current length for each $ and loading the base pointer after evaluating the
bounds expressions, with full side effects visibility for lvalue slicees.
People do come up with (arguably bad) code where this matters:
https://github.com/ldc-developers/ldc/issues/1433

--
May 04, 2017
https://issues.dlang.org/show_bug.cgi?id=17363

--- Comment #3 from anonymous4 <dfj1esp02@sneakemail.com> ---
Because you can't resolve $ before loading the array, therefore loading before resolution is the only way to do it.

--
March 11, 2018
https://issues.dlang.org/show_bug.cgi?id=17363

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com

--- Comment #4 from Walter Bright <bugzilla@digitalmars.com> ---
The only safe solution is for s[a..b] is to evaluate a and b first, then s. Then the slice will be array bounds checked safely if it got resized.

(Currently, s is evaluated first.)

--
March 11, 2018
https://issues.dlang.org/show_bug.cgi?id=17363

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |INVALID

--- Comment #5 from Walter Bright <bugzilla@digitalmars.com> ---
I don't think there is a solution to this problem. Consider:

    a()[b($)..c($)]

where a, b, c are functions with side effects that change the length of the array, and the calls to b and c depend on the $, the length of the array. Each function can only be called once, because they have side effects.

In order to get $, a() has to be called. But b($) and c($) both change the
value of $, so no ordering is correct.

However, it is not memory unsafe, because reallocating the array is memory safe even if other references to that array remain.

I'm marking this as INVALID because 1) there is no solution, cache or no cache, and 2) it is not memory unsafe. It's just buggy code.

--