D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 13861 - compiler segfault with nested struct, cannot access frame
Summary: compiler segfault with nested struct, cannot access frame
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P1 critical
Assignee: No Owner
URL:
Keywords: ice, pull
Depends on:
Blocks:
 
Reported: 2014-12-14 12:04 UTC by Vlad Levenfeld
Modified: 2015-02-18 03:42 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Vlad Levenfeld 2014-12-14 12:04:35 UTC
This code does not compile:

struct Foo (alias f, T)
{
	void bar () {} // BUG if not commented out, I get "Error: cannot access frame pointer of test.N.Foo!((n) => n, ulong).Foo"
}

void main () {
	auto A = N;
	typeof (A) x;
}

static N () {return Foo!(n => n, size_t)();}

In addition, when I attempt to use the value of A instead of just taking the typeof, I get a compiler segfault. Here is the backtrace:

#0  0x000000000054637c in FuncDeclaration::hasNestedFrameRefs (this=0x0)
    at func.c:4182
#1  0x000000000058ae1d in getEthis (loc=..., irs=0x7fffffffded0, 
    fd=0x7ffff512a0c0) at toir.c:219
#2  0x000000000058b0f9 in setEthis (loc=..., irs=0x7fffffffded0, ey=0x1ec6298, 
    ad=0x7ffff1bff500) at toir.c:300
#3  0x00000000005848cb in ToElemVisitor::visit (this=0x7fffffffd9c0, 
    sle=0x7ffff084c6c0) at e2ir.c:5220
#4  0x000000000053737a in StructLiteralExp::accept (this=0x7ffff084c6c0, 
    v=0x7fffffffd9c0) at expression.h:493
#5  0x00000000005849f7 in toElem (e=0x7ffff084c6c0, irs=0x7fffffffded0)
    at e2ir.c:5247
#6  0x000000000057fc2e in ToElemVisitor::visit (this=0x7fffffffdb20, 
    ce=0x7ffff084c820) at e2ir.c:3435
#7  0x0000000000537948 in CallExp::accept (this=0x7ffff084c820, 
    v=0x7fffffffdb20) at expression.h:908
#8  0x00000000005849f7 in toElem (e=0x7ffff084c820, irs=0x7fffffffded0)
    at e2ir.c:5247
#9  0x0000000000584cee in toElemDtor (e=0x7ffff084c820, irs=0x7fffffffded0)
    at e2ir.c:5340
#10 0x00000000005732cf in S2irVisitor::visit (this=0x7fffffffdcb0, 
    s=0x7ffff0832d00) at s2ir.c:770
#11 0x00000000004655b6 in ReturnStatement::accept (this=0x7ffff0832d00, 
#12 0x00000000005716ab in Statement_toIR (s=0x7ffff0832d00, irs=0x7fffffffded0)
    at s2ir.c:1273
#13 0x0000000000573644 in S2irVisitor::visit (this=0x7fffffffdd40, 
    s=0x7ffff0833a90) at s2ir.c:850
#14 0x0000000000465176 in CompoundStatement::accept (this=0x7ffff0833a90, 
    v=0x7fffffffdd40) at statement.h:206
#15 0x00000000005716ab in Statement_toIR (s=0x7ffff0833a90, irs=0x7fffffffded0)
    at s2ir.c:1273
#16 0x0000000000573644 in S2irVisitor::visit (this=0x7fffffffddd0, 
    s=0x7ffff088aca0) at s2ir.c:850
#17 0x0000000000465176 in CompoundStatement::accept (this=0x7ffff088aca0, 
    v=0x7fffffffddd0) at statement.h:206
#18 0x00000000005716ab in Statement_toIR (s=0x7ffff088aca0, irs=0x7fffffffded0)
    at s2ir.c:1273
#19 0x000000000056fc62 in FuncDeclaration::toObjFile (this=0x7ffff082ca70, 
    multiobj=false) at glue.c:1222
#20 0x00000000005899c8 in TemplateInstance::toObjFile (this=0x7ffff082c5e0, 
    multiobj=false) at toobj.c:1168
#21 0x000000000056e040 in Module::genobjfile (this=0x7ffff7ee1600, 
    multiobj=false) at glue.c:383
#22 0x0000000000406757 in tryMain (argc=6, argv=0x7295b0) at mars.c:1697
#23 0x0000000000406c84 in main (argc=2, argv=0x7fffffffe848) at mars.c:1782
Comment 1 John Colvin 2014-12-15 10:53:33 UTC
I don't get the segfault. What version of dmd are you testing on?
Comment 2 Vlad Levenfeld 2014-12-15 11:24:35 UTC
git head. The segfault came from the non-reduced version of this code which I wasn't able to use dustmite on (I was only able to make this example by avoiding the segfault, and getting the compiler error instead)
Comment 3 John Colvin 2014-12-15 11:26:51 UTC
You can dustmite for compiler segfaults by writing an appropriate test script to pass to dustmite: https://github.com/CyberShadow/DustMite/wiki/Detecting-a-segfault-in-dmd-itself
Comment 4 Vlad Levenfeld 2014-12-15 11:57:49 UTC
I'm sorry but I can't get the first script to work. It either reduces the codebase to nothing or else I get "Initial Test fails"
Comment 5 Vlad Levenfeld 2014-12-15 11:58:47 UTC
The second script is what I tried before, and it just seems to produce an unrelated segfault from definitely incorrect (and unrelated-looking) code.
Comment 6 John Colvin 2014-12-15 12:20:03 UTC
(In reply to Vlad Levenfeld from comment #5)
> The second script is what I tried before, and it just seems to produce an
> unrelated segfault from definitely incorrect (and unrelated-looking) code.

Please submit that as a separate bug report. If you're lucky it might fix this one too, you never know.

(In reply to Vlad Levenfeld from comment #4)
> I'm sorry but I can't get the first script to work. It either reduces the
> codebase to nothing or else I get "Initial Test fails"

Just to clarify, you should have a setup like this:

myFolder
| - projectFolder
    | - the code to reduce
| - dustmiteTest.sh

and you should be able to check your script like this:

$ cd myFolder/projectFolder
$ ../dustmiteTest.sh
$ echo $?
0

Obviously you have to be careful that your script isn't catching false positives (e.g. if you only checked for failure to compile+link, then dustmite will happily remove all your code).

An example of a test script for this bug would be

#!/bin/sh

# arguments to dmd
DMDARGS="file0.d file1.d"

OUTPUT=$(gdb --batch -ex "run $DMDARGS" dmd 2>&1)
echo "$OUTPUT" | fgrep -q 'in FuncDeclaration::hasNestedFrameRefs'
exit $?
Comment 7 Vlad Levenfeld 2014-12-16 03:56:24 UTC
Ok, looks like I had a bad directory structure. I got dustmite to work following your suggestion.

Here is a reduced case that segfaults:

struct Foo (alias f) 
{
		auto opIndex ()
		{
			return Bar ();
		}

		struct Bar
		{
			Bar opIndex ()
			{
				return Bar ();
			}
			Bar opIndex (size_t)
			{	
				return Bar ();
			}
		}
}

void main () {
	Foo!(n => n) A; // SEGFAULT
}
Comment 8 John Colvin 2014-12-16 08:25:39 UTC
Further reduced:

struct Foo(alias f)
{
    struct Bar
    {
        Bar func()
        {
            return Bar();
        }
    }
}

void main()
{
    Foo!(n => n) a;
}
Comment 10 github-bugzilla 2015-01-13 04:32:00 UTC
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/a8b021cdefea6f58d663c5ce381652757e5600b3
fix Issue 13861 - compiler segfault with nested struct, cannot access frame

https://github.com/D-Programming-Language/dmd/commit/661d7bbd9781bfa76d44aa7270c58e926177b5df
Merge pull request #4288 from 9rnsr/fix13861

Issue 13861 - compiler segfault with nested struct, cannot access frame
Comment 11 github-bugzilla 2015-02-18 03:42:27 UTC
Commits pushed to 2.067 at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/a8b021cdefea6f58d663c5ce381652757e5600b3
fix Issue 13861 - compiler segfault with nested struct, cannot access frame

https://github.com/D-Programming-Language/dmd/commit/661d7bbd9781bfa76d44aa7270c58e926177b5df
Merge pull request #4288 from 9rnsr/fix13861