Bug 11048 – Default arguments bypass most attributes check (pure, @safe, @nogc)

Status
NEW
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-09-15T14:54:15Z
Last change time
2024-12-13T18:11:27Z
Keywords
accepts-invalid, pull, safe
Assigned to
No Owner
Creator
Jonathan M Davis
See also
https://issues.dlang.org/show_bug.cgi?id=19645
Moved to GitHub: dmd#18670 →

Comments

Comment #0 by issues.dlang — 2013-09-15T14:54:15Z
int x = 7; void foo() pure { // Does not detect use of mutable global and compiles when it shouldn't. bar(); // Correctly detects the use of a mutable global and gives an error baz(x); } void bar(int a = x) pure {} void baz(int a) pure {} void main() {}
Comment #1 by andrej.mitrovich — 2013-09-16T08:48:37Z
So should the declaration of such a function be denied if it's pure, or should only calls be denied where a global is used? E.g.: // 1. ban this declaration? void bar(int a = x) pure {} // 2. or just this call? bar(); // If #2, then this could be considered ok: bar(1);
Comment #2 by issues.dlang — 2013-09-16T09:35:22Z
The default argument is only a problem if the pure function is called from a pure function. It's perfectly fine if it's called from an impure one. The problem is not that the default argument references a global but that the caller does not detect that the default argument of the function it's calling is a global. So, the caller does not detect that the call violates purity. The simplest solution is probably to ban the declaration, because then the caller doesn't have to worry about whether the pure function that it's calling has any default arguments which would violate the purity of the caller, but ideally, it's just the call which would be illegal, because the default argument is just fine so long as the caller isn't pure.
Comment #3 by pro.mathias.lang — 2020-11-09T00:21:32Z
This applies to all attributes but `nothrow`, but only because `nothrow` is the very last to be checked. E.g. this compiles: ``` int doit() { return 42; } void f(int i = doit()) nothrow @safe pure @nogc {} void main() /* nothrow */ @safe pure @nogc { f(); } ```
Comment #4 by pro.mathias.lang — 2020-11-09T00:22:24Z
*** Issue 13442 has been marked as a duplicate of this issue. ***
Comment #5 by ibuclaw — 2022-07-16T08:00:04Z
*** Issue 19645 has been marked as a duplicate of this issue. ***
Comment #6 by ibuclaw — 2022-07-16T08:10:58Z
I just encountered this when reviewing some @safe code in the dmd compiler implementation. The crux of which boils down to: ``` int findCondition() @system; int parseGeneric(int param = findCondition()) @safe { return param; } int parseSpec() @safe { return parseGeneric(); // Compiles! } ``` Call the function directly in @safe code, and you get the expected error.
Comment #7 by dlang-bot — 2022-07-16T09:16:48Z
@ibuclaw created dlang/dmd pull request #14309 "fix Issue 11048 - Default arguments bypass most attributes check (pure, @safe, @nogc)" fixing this issue: - fix Issue 11048 - Default arguments bypass most attributes check (pure, @safe, @nogc) https://github.com/dlang/dmd/pull/14309
Comment #8 by robert.schadek — 2024-12-13T18:11:27Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18670 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB