www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3867] New: forward delcaration generates very stange bug

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3867

           Summary: forward delcaration generates very stange bug
           Product: D
           Version: 1.057
          Platform: Other
        OS/Version: Mac OS X
            Status: NEW
          Severity: regression
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: fawzi gmx.ch



Created an attachment (id=576)
a program showing the bug

a forward declaration of an enum constant makes the ctfe evaluation of a
tempated function return the function call as result when called inside some
templates.

I think that this is a regression since 1.048 (1.047 works).

The connection of very distant pieces of code, sensibility to small changes
makes it a very ugly bug to track down.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 01 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3867


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au



Please reduce this test case, as a first step towards fixing it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 02 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3867




Does further reduction really help the debugging? 
I did try a bit reducing it, but the bug changes a bit, it prints two or three
times the wrong thing, then it comes to the correct result.
I suppose that the problem is that the forward def forces reevaluation, and
sometime the compiler manages to solve the forward def in time (before using
it), some time it doesn't.
So the error disappears or changes depending of the exact sequence of
evaluation.
I know for sure that for my whole code (several files with 1000s of lines) it
always finds a way to fail no matter what I do, unless I remove the forward
defs.
This example stops in a similar way.

From the number of forward def problems that dmd had I suppose they are treated
a posteriori, with some recursion in some places, and this means that errors
can easily slip in.

What is ugly is that it does not say "you have a forward def that I cannot
handle, so I give up", but it somehow tries to continue and gives a seemingly
fully unrelated error...

if more reduction is needed maybe Matti Niemenmaa can apply his mad reduction
skillz... (please ;-)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 02 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3867


Matti Niemenmaa <matti.niemenmaa+dbugzilla iki.fi> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |rejects-valid, wrong-code
            Summary|forward delcaration         |Complex bug with a forward
                   |generates very stange bug   |referenced enum member via
                   |                            |an alias, templates,
                   |                            |tuples, and CTFE



2010-03-02 10:46:07 PST ---
Here I come to save the day! To be fair, this is a /bit/ different in that the
original evaluated to the wrong thing twice, but I think that's related to the
compilation errors there, which are either a separate bug or also caused by
this (possible, given that removing the misbehaving code there also
mysteriously fixes the errors).

Anyway, here's something a bit shorter (though still involving just about every
nontrivial language feature) showing this problem:



enum ArrayFlags { None }

class NArray(T) {
    uint flags = Flags.None;
    alias ArrayFlags Flags;
}

char[] axisFilterLoop(S...)() {
    static if (is(S[0]==NArray!(double))) {}
    return "yyyy";
}

//pragma(msg, "Outside: " ~ axisFilterLoop!(NArray!(int))());

void axisFilter1(S...)() {
    pragma(msg, "Inside: " ~ axisFilterLoop!(S)());
}

void main() { axisFilter1!(NArray!(int))(); }



As shown above, the code prints:

"Inside: " ~ axisFilterLoop()
Inside: yyyy

Note that axisFilter1 is instantiated and run only once, yet we get two lines
of output. If you uncomment the other pragma(msg) you get:

Outside: yyyy
Inside: yyyy

As expected.

And yes, you need things like the false-giving (testing for the correct
NArray!(int) instead of NArray!(double) hides the bug) static if on S[0] on
line 9 and the access to the enum member through the alias on lines 4-5.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 02 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3867


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Complex bug with a forward  |pragma(msg) with a forward
                   |referenced enum member via  |referenced enum member via
                   |an alias, templates,        |an alias, templates,
                   |tuples, and CTFE            |tuples, and CTFE



Thanks, cutting it down helps ENORMOUSLY.
But it looks to me as though what you're seeing is just the compiler internals.
Constant folding of  "Inside: " ~ axisFilterLoop!(S)() 
can only happen AFTER axisFilterLoop has been instantiated. When you uncomment
the "Outside" pragma, you're forcing the compiler to use instantiate it.
Without it, it happens to use another order, where it tries to axisFilter1
first, then realizes it needs to do axisFilterLoop first. So it fails, *but it
outputs the pragma first*.

It didn't do this in 1.050, but did in 1.051. But it looks as though it only
affects pragma(msg), in which case it's a minor issue.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 02 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3867




Yes indeed this was the reduction that I had found, and I also thought that it
was showing the internal evaluations, as (for example) mixing in the string
works (I checked).

That was what I meant that then it comes to the correct result.

In my code the mixin fails, and often gives the error it gives in my original
example (that it cannot find a valid instantatiation even if all instantiations
are fully explicit).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 02 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3867




Maybe by bringing an example with pragma(msg) I confused the things.
My original problem was with a mixin(ctfe_function!(....)(...));
but the problem is really the instantiation, not the mixin, so my example was
just instantiating it to a const char[].
As I was doing it I did print it out (with pragma(msg)), and saw something
strange.
But the message might be a red herring, as the example showing only the
message, but not the error shows.
the real show blocker is the error:
{{{
t2-2.d(70): Error: template t2.axisFilter1(T,int rank,S...) does not match any
function template declaration
t2-2.d(70): Error: template t2.axisFilter1(T,int rank,S...) cannot deduce
template function from argument types !(int,1,NArray)(NArray,NArray,NArray)
t2-2.d(70): Error: cannot implicitly convert expression ((axisFilter1(T,int
rank,S...))(a,res,_param_1)) of type int to t2.NArray!(int,1).NArray
t2-2.d(75): Error: template instance t2.axisFilter!(int,1,NArray) error
instantiating
t2-2.d(79):        instantiated from here: doFilt!(int)
}}}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 02 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3867


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|pragma(msg) with a forward  |Regression(1.051): forward
                   |referenced enum member via  |referenced enum member via
                   |an alias, templates,        |an alias, templates, and
                   |tuples, and CTFE            |is()



Reduced test case shows it has nothing to do with tuples or CTFE. Can probably
be simplified further.
This worked in 1.050, but failed in 1.051.
================
enum ArrayFlags {
    None =0,
}

class red(int rank) {
      uint flags = Flags.None;
      alias ArrayFlags Flags;
}

void violet(Y) (red!(2) b) {
    static assert (!is(red!(7) : red!(3)));
}

void main(){
    violet!(int)(null);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 11 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3867




Thanks for the reduction, I knew that just the instantiation was the problem,
but I hadn't found a proper reduction...

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 12 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3867


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|1.057                       |D1
            Summary|Regression(1.051): forward  |Regression(1.051) forward
                   |referenced enum member via  |referenced enum member via
                   |an alias, templates, and    |an alias, templates, and
                   |is()                        |is(), D1 only



This is very strange. Worked up to 1.050, failed in 1.051, 1.052, 1.053;
worked again in 1.054 and 1.055, failed since then in D1.
Does not apply to D2.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 06 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3867


nfxjfg gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |nfxjfg gmail.com



May I ask why there are so many forward ref bugs in general and why fixing
these bugs often causes other regressions? Just look at regressions like bug
4210...

Is the dmd code quality that bad or what?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 06 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3867





 May I ask why there are so many forward ref bugs in general and why fixing
 these bugs often causes other regressions? Just look at regressions like bug
 4210...
 
 Is the dmd code quality that bad or what?
No. To fix a forward reference bug, you need to change the order in which the compiler performs its semantic pass. And this is difficult, largely because it's quite difficult for the compiler to 'undo' analysis which it's already done. So it's very easy to get wrong. This is why most languages which are similar to D (eg, C++) don't allow arbitrary forward references. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 07 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3867


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED



Fixed in DMD 1.071, probably as part of the fixes to error gagging.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 19 2011