www.digitalmars.com         C & C++   DMDScript  

D.gnu - weird bug with nested functions:

reply Johannes Pfau <nospam example.com> writes:
https://gist.github.com/jpf91/4738922

/tmp/cc8D6NeD.o:(.rodata._D6nested10__T5f7965Z5f7965FNaNbNfZC6nested10__T5f7965Z5f79656Result6Result6__vtblZ[_D6nested10__T5f7965Z5f7965FNaNbNfZC6nested10__T5f7965Z5f79656Result6Result6__vtblZ]+0x30):
undefined reference to
`_D6nested10__T5f7965Z5f7965FNaNbNfZC6nested10__T5f7965Z5f79656Result6Result1gMFZv'

This is currently not detected as needing a closure, it tries to use
the gcc nested function mechanism. I guess the gcc mechanism can't
handle function->class->function chains as it was developed for c
nested functions which can only be nested in functions AFAIK.

Background info: We don't call cgraph_finalize_function for GCC nested
functions (ObjectFile::outputFunction). This is correct, as
cgraph_finalize_function is called by the GCC middle / backend. But I
think in this case we're passing something to the backend which it can't
handle. Therefore cgraph_finalize_function is never called and the
function is not put out.

Uncommenting the /*a = 42;*/ makes everything work as we use the D
closure code path in that case. Marking the Result class as static also
works.

Do you know how we could force the D closure codepath in such cases or
how we should solve this?

(I actually found a fix for that verify_callgraph problem. But it
triggered some regressions which are actually caused by this bug.)
Feb 08 2013
next sibling parent Johannes Pfau <nospam example.com> writes:
Am Fri, 8 Feb 2013 14:05:24 +0100
schrieb Johannes Pfau <nospam example.com>:

 https://gist.github.com/jpf91/4738922
 

OK, found it and found a fix. As a result functions in nested structs can now also have static chains. With my changes it's possible that a function in a template instance has a static chain. So we can have functions which are nested, but for which we still need to call make_decl_one_only. There's a small problem: makeDeclOneOnly has this comment: /* Weak definitions have to be public. Nested functions may or may not be emitted as public even if TREE_PUBLIC is set. There is no way to tell if the back end implements make_decl_one_only with DECL_WEAK, so this check is done first. */ and therefore it doesn't mark nested functions as one-only. Do you know if that statement is still true for recent gcc versions? I removed that check and there were no regressions.
Feb 10 2013
prev sibling parent Iain Buclaw <ibuclaw ubuntu.com> writes:
--20cf3074b14e87fcc704d5708ab8
Content-Type: text/plain; charset=ISO-8859-1

On 10 February 2013 09:05, Johannes Pfau <nospam example.com> wrote:

 Am Fri, 8 Feb 2013 14:05:24 +0100
 schrieb Johannes Pfau <nospam example.com>:

 https://gist.github.com/jpf91/4738922

OK, found it and found a fix. As a result functions in nested structs can now also have static chains. With my changes it's possible that a function in a template instance has a static chain. So we can have functions which are nested, but for which we still need to call make_decl_one_only. There's a small problem: makeDeclOneOnly has this comment: /* Weak definitions have to be public. Nested functions may or may not be emitted as public even if TREE_PUBLIC is set. There is no way to tell if the back end implements make_decl_one_only with DECL_WEAK, so this check is done first. */ and therefore it doesn't mark nested functions as one-only. Do you know if that statement is still true for recent gcc versions? I removed that check and there were no regressions.

This code logic was from gcc-3.4 times, other changes around that may have made it work by now. Can you pull so I can review? -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0'; --20cf3074b14e87fcc704d5708ab8 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 1= 0 February 2013 09:05, Johannes Pfau <span dir=3D"ltr">&lt;<a href=3D"mailt= o:nospam example.com" target=3D"_blank">nospam example.com</a>&gt;</span> w= rote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex">Am Fri, 8 Feb 2013 14:05:24 +0100<br> schrieb Johannes Pfau &lt;<a href=3D"mailto:nospam example.com">nospam exam= ple.com</a>&gt;:<br> <br> &gt; <a href=3D"https://gist.github.com/jpf91/4738922" target=3D"_blank">ht= tps://gist.github.com/jpf91/4738922</a><br> &gt;<br> <br> OK, found it and found a fix. As a result functions in nested structs<br> can now also have static chains.<br> <br> With my changes it&#39;s possible that a function in a template instance<br=

for which we still need to call make_decl_one_only.<br> <br> There&#39;s a small problem: makeDeclOneOnly has this comment:<br> <br> =A0 =A0 =A0 /* Weak definitions have to be public. =A0Nested functions may = or<br> =A0 =A0 =A0 =A0 =A0may not be emitted as public even if TREE_PUBLIC is set.= <br> =A0 =A0 =A0 =A0 =A0There is no way to tell if the back end implements<br> =A0 =A0 =A0 =A0 =A0make_decl_one_only with DECL_WEAK, so this check is<br> =A0 =A0 =A0 =A0 =A0done first. =A0*/<br> <br> and therefore it doesn&#39;t mark nested functions as one-only.<br> <br> Do you know if that statement is still true for recent gcc versions? I<br> removed that check and there were no regressions.<br> </blockquote></div><br></div><div class=3D"gmail_extra">This code logic was= from gcc-3.4 times, other changes around that may have made it work by now= .=A0 Can you pull so I can review?<br clear=3D"all"></div><div class=3D"gma= il_extra"> <br>-- <br>Iain Buclaw<br><br>*(p &lt; e ? p++ : p) =3D (c &amp; 0x0f) + &#= 39;0&#39;; </div></div> --20cf3074b14e87fcc704d5708ab8--
Feb 11 2013