D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 17819 - static foreach segfaults on __traits(allMembers)
Summary: static foreach segfaults on __traits(allMembers)
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86_64 Linux
: P1 major
Assignee: No Owner
URL:
Keywords:
: 18718 (view as issue list)
Depends on:
Blocks:
 
Reported: 2017-09-09 20:50 UTC by Jean-Louis Leroy
Modified: 2018-06-03 18:30 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Jean-Louis Leroy 2017-09-09 20:50:12 UTC
Given:

// staticforeach.d

import std.traits;

static foreach (m; __traits(allMembers, staticforeach)) {
  pragma(msg, m.stringof);
}

Try to compile:

$ dmd staticforeach.d 
Segmentation fault (core dumped)

$ dmd --version
DMD64 D Compiler v2.076.0-dirty
Copyright (c) 1999-2017 by Digital Mars written by Walter Bright
Comment 1 Jean-Louis Leroy 2018-01-10 20:50:41 UTC
The bug is still present in 2.078.
Comment 2 Jean-Louis Leroy 2018-02-23 20:10:25 UTC
Still present in v2.078.3 - it seems that no one is looking into this.
Comment 3 Citrus 2018-03-11 18:01:23 UTC
There's a stack overflow in Dsymbol's _foreach, every time it recurses into a AttribDeclaration (such as the `static foreach') the stack gets deeper until it explodes.
Comment 4 Seb 2018-04-05 03:35:27 UTC
Not really a fix, but a start https://github.com/dlang/dmd/pull/8125
Comment 5 Seb 2018-04-06 02:54:26 UTC
https://issues.dlang.org/show_bug.cgi?id=18718 is very related.
Comment 6 timon.gehr 2018-05-02 17:57:06 UTC
This is not really a `static foreach` issue, but rather a general issue with how DMD handles (or rather, does not handle) circular dependencies.

The following code runs into the same problem:

---
module c;
static if(__traits(allMembers,__traits(parent,{}))[0]=="c"){}
---

Here, DMD explicitly catches the infinite recursion and prints:
c.d(3): Error: error evaluating `static if` expression

(The code that does this has a bug in it, therefore the error message is not useful:

            if (exp.op == TOK.error || nest > 100)
            {
                error(loc, (nest > 1000) ? "unresolvable circular `static if` expression" : "error evaluating `static if` expression");
                return errorReturn();
            }
)

It is trivial to apply a similar "fix" for `static foreach`, but I doubt this is what Jean-Louis had in mind.


Interestingly enough, this "works" with string mixins:

module c;
mixin("enum "~__traits(allMembers,c)[1]~"2 = 2;");
int x;
pragma(msg, x2);
pragma(msg, __traits(allMembers,c)[1]);

(Clearly, the code actually has no reasonable interpretation, but DMD still successfully compiles it.)

This is because `CompileDeclaration.include` just returns null. I can "fix" the `static foreach` case by returning "null" in case a call to "include" is already on the stack. In fact, I could do the same to the `static if` case to make that "work" too.
Comment 7 timon.gehr 2018-05-02 19:14:24 UTC
*** Issue 18718 has been marked as a duplicate of this issue. ***
Comment 8 timon.gehr 2018-05-02 20:48:55 UTC
https://github.com/dlang/dmd/pull/8213
Comment 9 github-bugzilla 2018-06-03 18:29:59 UTC
Commits pushed to master at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/ebbd8e92b61bcf05df443b62deeff0786581067c
fix Issue 17819 - static foreach segfaults on __traits(allMembers)

https://github.com/dlang/dmd/commit/b625e01f4464768d0e7b1b8119d8f6ca3543efa1
Merge pull request #8213 from tgehr/fix17819

fix Issue 17819 - static foreach segfaults on __traits(allMembers)
merged-on-behalf-of: Razvan Nitu <RazvanN7@users.noreply.github.com>