Bug 19091 – __traits(compiles) and error in templated structs leads to missing symbol

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2018-07-17T13:03:48Z
Last change time
2024-12-13T18:59:34Z
Keywords
industry, pull
Assigned to
No Owner
Creator
FeepingCreature
See also
https://issues.dlang.org/show_bug.cgi?id=19545
Moved to GitHub: dmd#17870 →

Comments

Comment #0 by default_357-line — 2018-07-17T13:03:48Z
Minimized repro: enum compiles = __traits(compiles, Outer!()); struct Inner() { // Note syntax error: missing return statement. This is important? int foo() { } void bar() { } } struct Outer() { Inner!() field; } void main() { Outer!()().field.bar; } Expected: Compiler error: missing return statement in foo Got: Linker error: undefined reference to test.Inner.bar()
Comment #1 by default_357-line — 2018-07-17T13:05:53Z
Note that __traits(compiles) evaluates to true?!
Comment #2 by default_357-line — 2020-07-02T09:14:55Z
Found a new version of this bug: ``` void early()() { Struct!() var; } struct Struct() { void fun() { error; } } void main() { void helper()() { early; } static assert(!__traits(compiles, helper())); helper(); } ```
Comment #3 by default_357-line — 2020-07-02T09:20:34Z
Correction, sorry; didn't pay attention and accidentally pasted a working version. This one properly linker errors: ``` void early()() { auto var = Struct!()(0); } struct Struct() { this(int) { } void fun() { error; } } void main() { void helper()() { early!(); } static assert(!__traits(compiles, helper())); helper(); } ```
Comment #4 by default_357-line — 2020-07-02T09:31:00Z
A different way of provoking the same effect: ``` struct Struct() { static void missing() { } // this will be missing from the linker void fun() { error; } // will provoke an error if attempted to compile } void helper1()() { Struct!().missing; } void helper2()() { helper1(); } void main() { static assert(!__traits(compiles, helper2())); helper1(); } ```
Comment #5 by default_357-line — 2020-09-10T13:49:20Z
https://issues.dlang.org/show_bug.cgi?id=21235 might be the same bug? I don't know.
Comment #6 by default_357-line — 2020-09-14T09:21:59Z
Update: version that makes it clearer what happens: ``` struct Template { void opEquals(U, this TA)(U) { pragma(msg, "Template.opEquals!(" ~ U.stringof ~ ", " ~ TA.stringof ~ ")"); foo(); } } void foo()() { static assert(false); // foo() fails xeq semantic3 while gagged bar!(); } // this is the symbol that sticks around and references foo(). // Despite foo() erroring, bar() is not errored and emits normally. void bar()() { pragma(msg, "bar()"); foo(); } void main() { } ```
Comment #7 by default_357-line — 2020-09-14T09:29:16Z
Unified with what I'm learning from the testcase from 21235: ``` // gag the foo error static assert(!__traits(compiles, foo())); void foo()() { static assert(false); bar!(); } // foo() is not errored while bar compiles? because circular void bar()() { foo(); } // no error void main() { bar(); } ``` I don't think we'll get it smaller than this.
Comment #8 by default_357-line — 2020-09-14T09:29:51Z
*** Issue 21235 has been marked as a duplicate of this issue. ***
Comment #9 by moonlightsentinel — 2020-09-14T10:21:28Z
(In reply to FeepingCreature from comment #7) > Unified with what I'm learning from the testcase from 21235: > > [...] Digger blames this PR: https://github.com/dlang/dmd/pull/544
Comment #10 by default_357-line — 2020-09-14T10:42:26Z
There's probably two issues. There's some sort of issue (which triggered this originally) where the same template is inferred @safe at one time and non-@safe in the other, which is what sent me off on 21235. But because the template error that would normally draw attention to this issue gets eaten and turned into a linker error, this is hard to differentiate from 19091 so I'd strongly recommend to get 19091 fixed first before even looking into the 21235 regression.
Comment #11 by dlang-bot — 2020-12-01T11:05:31Z
@WalterBright created dlang/dmd pull request #12014 "fix Issue 19091 - __traits(compiles) and error in templated structs l…" fixing this issue: - fix Issue 19091 - __traits(compiles) and error in templated structs leads to missing symbol https://github.com/dlang/dmd/pull/12014
Comment #12 by default_357-line — 2022-03-24T11:58:10Z
I have found a whole new manifestation of this bug! struct Inner() { bool opEquals(Inner) { } } struct Outer() { Inner!() field; bool opEquals(Outer) { return field == field; } } void main() { void nested()() { cast(void) Outer!()(); } static assert(__traits(compiles, nested()) == false); nested(); } In 2.097.1, this results in an illegal instruction! Building with master reveals that this is a compiled-out assert; it actually errors with core.exception.AssertError@src/dmd/e2ir.d(529): Assertion failure ---------------- ??:? _d_assertp [0x55a6c3d0d8bd] src/dmd/e2ir.d:529 _ZN13ToElemVisitor5visitEP10Expression [0x55a6c3bbe899] src/dmd/visitor.d:66 _ZN7Visitor5visitEP8ErrorExp [0x55a6c3baf006] src/dmd/expression.d:2026 _ZN8ErrorExp6acceptEP7Visitor [0x55a6c3aca97d] src/dmd/e2ir.d:504 _Z6toElemP10ExpressionP7IRState [0x55a6c3bbe7d3] src/dmd/e2ir.d:411 _Z10toElemDtorP10ExpressionP7IRState [0x55a6c3bbe41c] src/dmd/s2ir.d:728 _ZN11S2irVisitor5visitEP15ReturnStatement [0x55a6c3be9ee3] src/dmd/statement.d:1430 _ZN15ReturnStatement6acceptEP7Visitor [0x55a6c3b7e1b1] src/dmd/s2ir.d:1537 _ZN11S2irVisitor14Statement_toIREP9StatementP7IRStateP9StmtStateI5blockE [0x55a6c3bec1c3] src/dmd/s2ir.d:786 _ZN11S2irVisitor5visitEP17CompoundStatement [0x55a6c3bea127] src/dmd/statement.d:620 _ZN17CompoundStatement6acceptEP7Visitor [0x55a6c3b7c815] src/dmd/s2ir.d:1557 _Z14Statement_toIRP9StatementP7IRState [0x55a6c3bec2bf] src/dmd/glue.d:1100 _Z25FuncDeclaration_toObjFileP15FuncDeclarationb [0x55a6c3be1430] src/dmd/toobj.d:311 _ZN9toObjFile9ToObjFile5visitEP15FuncDeclaration [0x55a6c3bf6a64] src/dmd/func.d:2817 _ZN15FuncDeclaration6acceptEP7Visitor [0x55a6c3b09cdd] src/dmd/toobj.d:534 void dmd.toobj.toObjFile(dmd.dsymbol.Dsymbol, bool).ToObjFile.visit(dmd.dstruct.StructDeclaration).__lambda2!(dmd.dsymbol.Dsymbol).__lambda2(dmd.dsymbol.Dsymbol) [0x55a6c3bf7251] src/dmd/dsymbol.d:105 void dmd.dsymbol.foreachDsymbol(dmd.root.array.Array!(dmd.dsymbol.Dsymbol).Array*, void delegate(dmd.dsymbol.Dsymbol)) [0x55a6c3a8739f] src/dmd/toobj.d:534 _ZN9toObjFile9ToObjFile5visitEP17StructDeclaration [0x55a6c3bf719e] src/dmd/dstruct.d:451 _ZN17StructDeclaration6acceptEP7Visitor [0x55a6c3a86c6d] src/dmd/toobj.d:827 void dmd.toobj.toObjFile(dmd.dsymbol.Dsymbol, bool).ToObjFile.visit(dmd.dtemplate.TemplateInstance).__lambda2!(dmd.dsymbol.Dsymbol).__lambda2(dmd.dsymbol.Dsymbol) [0x55a6c3bf7b35] src/dmd/dsymbol.d:105 void dmd.dsymbol.foreachDsymbol(dmd.root.array.Array!(dmd.dsymbol.Dsymbol).Array*, void delegate(dmd.dsymbol.Dsymbol)) [0x55a6c3a8739f] src/dmd/toobj.d:827 _ZN9toObjFile9ToObjFile5visitEP16TemplateInstance [0x55a6c3bf7b0e] src/dmd/dtemplate.d:7504 _ZN16TemplateInstance6acceptEP7Visitor [0x55a6c3ab4cd1] src/dmd/toobj.d:1008 _Z9toObjFileP7Dsymbolb [0x55a6c3bf69ca] src/dmd/glue.d:522 _Z10genObjFileP6Moduleb [0x55a6c3bdf9d3] src/dmd/glue.d:137 void dmd.glue.generateCodeAndWrite(dmd.dmodule.Module[], const(char)*[], const(char)[], const(char)[], bool, bool, bool, bool, bool) [0x55a6c3bde396] src/dmd/mars.d:571 int dmd.mars.tryMain(ulong, const(char)**, ref dmd.globals.Param) [0x55a6c39f92a5] src/dmd/mars.d:953 _Dmain [0x55a6c39fa851]
Comment #13 by default_357-line — 2022-03-24T12:00:38Z
Oh yeah, the missing printf I forgot to paste: [] error: __error Ie. considering printf("[%s] %s: %s\n", e.loc.toChars(), EXPtoString(e.op).ptr, e.toChars()); meaning e, probably the opEquals, was in an errored state and we never reported the error and tried to emit it regardless.
Comment #14 by default_357-line — 2022-03-24T12:06:40Z
Hm, this one seems to be distinctive enough that I should report it as a new one. Sorry, it smelled familiar. But the assert seems its own problem site. Re-filed as https://issues.dlang.org/show_bug.cgi?id=22917
Comment #15 by robert.schadek — 2024-12-13T18:59:34Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17870 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB