Bug 22192 – Inconsistent attribute inference for template member function

Status
NEW
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-08-08T13:45:48Z
Last change time
2024-12-13T19:17:58Z
Keywords
industry
Assigned to
No Owner
Creator
Eyal
Moved to GitHub: dmd#19971 →

Comments

Comment #0 by eyal — 2021-08-08T13:45:48Z
This program exhibits at least 2 different issues: struct S() { align(1): bool x; public int* i; public void initialize(int* i) { this.i = i; } } S!() r1; // pragma(msg, "r1.initialize:", typeof(r1.initialize)); // <-- magical line pragma(msg, "S!().initialize:", typeof(S!().initialize)); Now this program compiles and the pragma msg emits: "S!().initialize:void(int* i)" Issue A) this is wrong, because inside a template, it should infer the method to be pure nothrow @nogc, but it doesn't. Issue B) if you uncomment the magical line, the pragma msgs now emit: "r1.initialize:pure nothrow @nogc @safe void(int* i) S!().initialize:pure nothrow @nogc @safe void(int* i)" so the first pragma(msg) changes the inferred type of initialize to correctly include "pure nothrow @nogc" but *incorrectly* include "@safe" (it isn't @safe because it assigns a misaligned pointer!) ----------------- A) So a typeof() computation on a type has side-effects. B) The attribute inference is too narrow without it C) The attribute inference is too wide with it ----------------- I've minimized to this example when debugging linker errors - where different compilation contexts inferred "@safe pure" differently on an expression.
Comment #1 by snarwin+bugzilla — 2021-08-08T14:26:08Z
More reduced version of the inconsistent attribute inference issue: --- struct S() { public void initialize() {} } version(NotInferred) // void() pragma(msg, typeof(S!().initialize)); else // pure nothrow @nogc @safe void() pragma(msg, typeof(S!()().initialize)); --- More reduced version of the alignment issue: --- struct S { align(1) int* p; } auto fun(int* p) { S s; s.p = p; return s; } // pure nothrow @nogc @safe S(int* p) pragma(msg, typeof(fun)); --- I am not sure the second one is actually a bug. The language spec section on pointers [1] does not say anything about misaligned pointer variables potentially causing undefined behavior, and I have not been able to come up with an example that uses such a variable to cause undefined behavior in @safe code. For now, I've edited the name of this bugzilla issue to refer to the attribute-inference issue in the first example, since that one's definitely a bug. [1] https://dlang.org/spec/arrays.html#pointers
Comment #2 by eyal — 2021-08-08T14:57:39Z
If you change your second to: struct S { ubyte x; align(1) int* p; } // @safe <-- will fail to build with this attribute, but it will infer as @safe! auto fun(int* p) { S s; s.p = p; return s; } // pure nothrow @nogc @safe S(int* p) pragma(msg, typeof(fun)); i.e: make the ptr be at offset 1, misaligned - it will infer as @safe, but refuse to type-check with @safe
Comment #3 by robert.schadek — 2024-12-13T19:17:58Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19971 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB