September 09 [Issue 24757] New: Escaping with typesafe variadic functions is not detected, making @safe code potentially unsafe | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=24757 Issue ID: 24757 Summary: Escaping with typesafe variadic functions is not detected, making @safe code potentially unsafe Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nobody@puremagic.com Reporter: issues.dlang@jmdavisProg.com This code compiles and runs, but the assertion fails --- void main() @safe { auto arr = bar(); assert(arr == [1, 2, 3]); } int[] foo(int[] args...) @safe { auto saved = args; return saved; } int[] bar() @safe { return foo(1, 2, 3); } --- If you have --- void main() @safe { auto arr = foo(1, 2, 3); assert(arr == [1, 2, 3]); } int[] foo(int[] args...) @safe { auto saved = args; return saved; } --- it works - presumably because the array ends up sitting on the stack in main in that case - but it's still not actually memory safe. If you have --- void main() @safe { auto arr = foo(1, 2, 3); assert(arr == [1, 2, 3]); } int[] foo(int[] args...) @safe { return args; } --- then the compiler catches it with --- q.d(9): Error: returning `args` escapes a reference to variadic parameter `args` --- but once you slice the array, it can no longer catch the problem, making it so that @safe code is not actually memory safe. The issue is pretty similar to what happens with slicing static arrays - https://issues.dlang.org/show_bug.cgi?id=24750 - in that DIP 1000 does solve the problem, but without it, we have a hole in @safe. Also, just like with static arrays, slicing the array is caught when returning it directly but isn't otherwise (without DIP 1000). If we want to close the hole without needing DIP 1000, it seems to me that we either need to make it so that typesafe variadic functions are not considered @safe, or we need the compiler to flag anywhere that slices the variadic array as @system (even if it's implicit like when passing it to a function or using auto to slice the entire array). Making it @system to slice the variadic array would likely be the better choice, because then more code can be @safe, though I expect that a large percentage of such functions will ultimately have to be @trusted anyway, since in most cases, you're probably going to want to slice the array rather than simply access its elements. Also, special attention may have to be take with foreach, since depending on how that's implemented, it could be slicing the array, but if it is, it's guaranteed that the slice isn't escaping, because the compiler is doing it in a way that it can't escape. But it could be that that's simply lowered to using for with an index, in which case, no slicing actually happens, and it's a non-issue. I just bring it up, since it occurs to me that it might be, and it should not be flagged as @system. But regardless of how we want to solve it, as things stand, without DIP 1000, it's very possible to escape a variadic array from an @safe function. -- |
Copyright © 1999-2021 by the D Language Foundation