Bug 21518 – delegates not checked for attribute match in const arrays

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2020-12-31T01:34:07Z
Last change time
2023-01-14T17:43:02Z
Keywords
pull
Assigned to
No Owner
Creator
Bolpat
See also
https://issues.dlang.org/show_bug.cgi?id=23626

Comments

Comment #0 by qs.il.paperinik — 2020-12-31T01:34:07Z
A function taking a slice of delegates as a parameter that is annotated @safe can be fed @system operations. An example for taking a slice of delegates is lazy variadic functions. Consider: void func(const void delegate() @safe [] paramDGs...) @safe { if (paramDGs.length > 0) paramDGs[0](); } A call to func(arr) should not compile when arr contains @system delegates and is typed accordingly. But the compiler accepts this: const dg = delegate() @system { int* p; int x; p = &x; }; // dg explicitly contains un-@safe operations to be sure. const(void delegate() @system)[] arg = [ dg ]; func(arg); // illegal call, not caught func(dg); // illegal variadic call, caught properly Replacing `delegate` by `function` everywhere, the compiler catches the type mismatch. In the declaration of `func`, `in` instead of `const` yields the same result with and without `-preview=in`. However, replacing `const` with `immutable` everywhere makes the compiler catch the illegal call. Pushing down const one level of indirection, i.e. const(void delegate() @safe)[] instead of const(void delegate() @safe []) does not help. Pushing down const and replacing it with immutable makes the compiler catch the illegal call. For some reason, const and delegate conspire to trick the compiler into accepting attribute mismatches. This issue is not directly related to @safe, the issue arises for pure, too.
Comment #1 by moonlightsentinel — 2021-01-01T20:39:36Z
This issue is not restricted to function parameters: void delegates() { const dg = delegate() @system { int* p; int x; p = &x; }; // pragma(msg, typeof(dg)); // const(void delegate() pure nothrow @nogc @system) // No error const(void delegate() @safe)[] arg = [ dg ]; // pragma(msg, typeof(arg)); // const(void delegate() @safe)[] // Correctly fails // void delegate() @safe[] arg = [ dg ]; }
Comment #2 by moonlightsentinel — 2021-01-01T20:43:32Z
Also not restricted (In reply to moonlightsentinel from comment #1) > This issue is not restricted to function parameters: > > void delegates() > { > const dg = delegate() @system { int* p; int x; p = &x; }; > // pragma(msg, typeof(dg)); // const(void delegate() pure nothrow @nogc > @system) > > // No error > const(void delegate() @safe)[] arg = [ dg ]; > // pragma(msg, typeof(arg)); // const(void delegate() @safe)[] > > // Correctly fails > // void delegate() @safe[] arg = [ dg ]; > } Also missing: const(void delegate() @system)[] sysA = [ dg ]; const(void delegate() @safe)[] safeA = sysA;
Comment #3 by dlang-bot — 2021-01-01T23:30:46Z
@MoonlightSentinel created dlang/dmd pull request #12090 "Fix 21518 - delegates not checked for attribute match in const arrays" fixing this issue: - Fix 21518 - delegates not checked for attribute match in const arrays Const-conversion checks for delegates are forwarded to the type of `funcptr`. But `TypeFunction` did not implement `constConv`, causing the inherited `TypeNext.constConv` (which only checks const`/`shared`/...). to ignore the missmatched attributes. The bug was restricted to `const` arrays because checks for (im)mutable arrays didn't use `constConv` and instead failed due to the missmatched `deco`. https://github.com/dlang/dmd/pull/12090
Comment #4 by dlang-bot — 2021-01-02T19:07:58Z
dlang/dmd pull request #12090 "Fix 21518 - delegates not checked for attribute match in const arrays" was merged into master: - de27c4edb84cab50f93f77283702d32bc6a38b48 by MoonlightSentinel: Fix 21518 - delegates not checked for attribute match in const arrays Const-conversion checks for delegates are forwarded to the type of `funcptr`. But `TypeFunction` did not implement `constConv`, causing the inherited `TypeNext.constConv` (which only checks const`/`shared`/...). to ignore the missmatched attributes. The bug was restricted to `const` arrays because checks for (im)mutable arrays didn't use `constConv` and instead failed due to the missmatched `deco`. https://github.com/dlang/dmd/pull/12090