D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 2474 - Recursive lazy arguments are inlined incorrectly
Summary: Recursive lazy arguments are inlined incorrectly
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: x86 Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: rejects-valid
: 2475 3244 (view as issue list)
Depends on:
Blocks:
 
Reported: 2008-11-26 18:24 UTC by Sergey Gromov
Modified: 2019-09-13 09:22 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 Sergey Gromov 2008-11-26 18:24:04 UTC
This code:

--8<-----------
int foo(lazy int x)
{
  int bar()
  {
    return foo(bar());
  }
  return bar();
}
--8<-----------

produces the following output when compiled:

> dmd inlinebug.d -c -inline
inlinebug.d(5): delegate inlinebug.foo.bar.__dgliteral1 is a nested function and cannot be accessed from foo

Without the -inline flag this code compiles and works as expected.

The same bug is present in DMD 1.037.
Comment 1 Stewart Gordon 2008-11-27 09:42:54 UTC
>> dmd inlinebug.d -c -inline
> inlinebug.d(5): delegate inlinebug.foo.bar.__dgliteral1 is a nested function
> and cannot be accessed from foo

Presumably, inlining changes

    return bar();

to

    return foo(bar());

after which it tries to TRO the foo call, but gets mixed up as it relies on the nested function bar.

I'm not sure if the compiler is actually within its rights to complain about this, as it's bad code even though not technically illegal.  And if such bad code interferes with optimisation, should the compiler error or just not bother with the optimisation?

> Without the -inline flag this code compiles and works as expected.

As in throws a stack overflow?

> The same bug is present in DMD 1.037.

And 1.036 and 2.020.  AIUI if the same bug occurs in both D1 and D2, it is preferred to file it under the D1 version.
Comment 2 Sergey Gromov 2008-11-27 10:51:08 UTC
> I'm not sure if the compiler is actually within its rights to complain about
> this, as it's bad code even though not technically illegal...
> 
> > Without the -inline flag this code compiles and works as expected.
> 
> As in throws a stack overflow?

This is a reduced version of Knuth's "Man or Boy" test:

--8<----------------
import std.stdio;

int a(int k, lazy int x1, lazy int x2, lazy int x3, lazy int x4, lazy int x5)
{
  int b()
  {
    k--;
    return a(k, b(), x1, x2, x3, x4);
  }
  return k <= 0 ? x4 + x5 : b();
}

void main()
{
  writefln(a(10, 1, -1, -1, 1, 0));
}
--8<----------------

>dmd manorboy.d

>manorboy
-67

>dmd -inline manorboy.d
manorboy.d(8): delegate manorboy.a.b.__dgliteral1 is a nested function and cannot be accessed from a
manorboy.d(8): delegate manorboy.a.b.__dgliteral2 is a nested function and cannot be accessed from a
manorboy.d(8): delegate manorboy.a.b.__dgliteral3 is a nested function and cannot be accessed from a
manorboy.d(8): delegate manorboy.a.b.__dgliteral4 is a nested function and cannot be accessed from a
manorboy.d(8): delegate manorboy.a.b.__dgliteral5 is a nested function and cannot be accessed from a

See also the issue 2475, it's the same.
Comment 3 Stewart Gordon 2009-01-11 16:47:28 UTC
*** Bug 2475 has been marked as a duplicate of this bug. ***
Comment 4 Don 2010-09-13 23:55:41 UTC
*** Issue 3244 has been marked as a duplicate of this issue. ***
Comment 5 RazvanN 2019-09-13 09:00:04 UTC
Code compiles successfully in D2. Closing as WORKSFORME.