On 1 January 2013 19:22, Johannes Pfau <nospam@example.com> wrote:
This is a bug which only seems to happen with gdc-4.7. At least I can't
reproduce it with gcc 4.8 but I'd like to fix it in 4.7 as well if
possible. (It prevents some phobos modules from being built in unittest
mode).

First, here's the reduced test case:
----------------
void main()
{
    topNIndex();
}

void topNIndex()() //<= only fails if this is a template
{
    bool indirectLess(int a, int b) //<= adding 'static' makes it work
    {
        return a > b;
    }
    auto a = BinaryHeap!(indirectLess)();
}

struct BinaryHeap(alias less )
{
    void percolateDown()
    {
        less(0, 1);
    }
}
----------------

It's somehow related to closures in templated functions. Making
topNIndex a function or making indirectLess static fixes the issue.

This is the compiler error:
----------------
bug/std/algorithm2.d:1: error: missing callgraph edge for call stmt:
algorithm2.topNIndex!().topNIndex.indirectLess (0B, 0, 1);

algorithm2.topNIndex!().topNIndex.BinaryHeap!(indirectLess).BinaryHeap.percolateDown/3
@0x7fe2ce7a6b40 (asm:
_D10algorithm214__T9topNIndexZ9topNIndexFZv82__T10BinaryHeapS63_D10algorithm214__T9topNIndexZ9topNIndexFZv12indirectLessMFiiZbZ10BinaryHeap13percolateDownMFZv)
analyzed needed reachable body finalized called by: calls:
_d_assert_msg/5 (1.00 per call) References: Refering this function:
bug/std/algorithm2.d:1: internal compiler error: verify_cgraph_node
failed
----------------

Any clue what to do about this?
* Was it probably a gdc specific issue fixed in master but missed when
  backporting?
* Could be an issue fixed in the GCC backend, but I can't find a
  matching bug report?
* Any clue how to debug this further?


Only two suggestions I can give are:

a) Make sure that indirectLess DECL_CONTEXT is topNIndex, and not main in code generation (eg: you don't want it to look logically like this)

void main()
{
    bool indirectLess(int a, int b)
    {
        return a > b;
    }
    topNIndex();
}

void topNIndex()
{
    auto a = BinaryHeap!(indirectLess);
}


b) Make sure that indirectLess is codegen'd and pushed before topNIndex.


Regards,
--
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';