Bug 5941 – Using inner struct which references nested function in a no-attribute or auto-return member function causes "nested function cannot be accessed" error

Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-05-07T00:11:00Z
Last change time
2015-06-23T00:46:27Z
Keywords
accepts-invalid
Assigned to
nobody
Creator
kennytm

Comments

Comment #0 by kennytm — 2011-05-07T00:11:05Z
May or may not be the same as issue 5939. Happens at least since 2.042. Test case: ----------------------------------------------------------------- auto f() { static int h(int x) pure nothrow @safe { return x*x*x-x*x; } struct S { int get() { return h(8); } } return S.init; } void main() { typeof(f()) z; assert(z.get == 448); assert(z.get == 448); } ----------------------------------------------------------------- x.d(11): Error: function x.f is a nested function and cannot be accessed from main ----------------------------------------------------------------- The bug will appear only when the 'get' function - is an auto-return function (e.g. '@property auto get()') - or has no attributes at all (e.g. 'int get()') The bug is gone when you supply at least one attribute to 'get', e.g. '@safe int get()'. I don't know if it is a reject-valid or accept-invalid.
Comment #1 by kennytm — 2011-05-07T00:27:39Z
A slight variant is when 'f' is a template function taking a delegate literal as input, it will generate an ICE: --------------------------------- auto f(alias T)() { static void h(){} struct S { void get() { h(); } } return S(); } void main() { typeof(f!((){})()) z; } --------------------------------- Internal error: backend/cgcs.c 363 ---------------------------------
Comment #2 by clugdbug — 2011-12-21T14:35:39Z
Reduced test case suggests it's related to typeof(): auto fx() { struct S { void get() {} } return S.init; } void main() { //auto w = fx(); // OK typeof(fx()) z; // fails! } Again, adding any attributes to get() removes the bug -- even though get() is never used.
Comment #3 by clugdbug — 2011-12-21T23:30:26Z
In bug 5939, Walter explicitly stated that the test case is comment 2 is not a bug. However, the fact that it compiles if the function 'get' is removed, or if attributes are added to get(), is surely a bug. Based on Walter's comment, it should never compile. So I'm marking as accepts-invalid.
Comment #4 by yebblies — 2012-01-18T19:04:52Z
In case anyone's wondering about why adding attributes changes anything, the compiler does a scan of all the top level members in a nested struct to determine if it contains any functions, and makes it a static struct otherwise. This is unfortunately done badly/too early and it finds AttributeDeclarations containing functions but doesn't investigate further. Given that, it sounds like the requirement for having no attributes is really just a requirement for a non-static nested struct.
Comment #5 by maximzms — 2013-03-04T09:20:24Z
Linux, 64-bit DMD from Git head https://github.com/D-Programming-Language/dmd/commit/13b3bdbf3819fec810ebfb077957510612dfa815 0. Compiling code from the description (http://d.puremagic.com/issues/show_bug.cgi?id=5941#c0): -------------------- test.d(11): Error: cannot access frame pointer of test.f.S -------------------- 1. Compiling code from comment 1 (http://d.puremagic.com/issues/show_bug.cgi?id=5941#c1): -------------------- test.d(11): Error: cannot access frame pointer of test.f!(function void() { } ).f.S -------------------- 2. Compiling code from comment 2 (http://d.puremagic.com/issues/show_bug.cgi?id=5941#c1): -------------------- test.d(9): Error: cannot access frame pointer of test.fx.S -------------------- Is this behavior correct?
Comment #6 by k.hara.pg — 2015-06-23T00:46:27Z
(In reply to Maksim Zholudev from comment #5) > Is this behavior correct? Currently it's correct. A nested struct is not constructible outside of the defined function, because it needs valid enclosing context. I think the original attribute-dependent issue is fixed.