Problems when refining type

Hi

I'm using the llvm-c wrapper, and trying to build some recursive types
(using released 2.3).

I get an assert on trying to create a second opaque pointer type after
refining a first.

The first time through creating an opaque pointer type, a new type is
created and returned from PointerType::get, but the second time,
ValueType (the opaque type) is found in the PointerTypes map, which
seems to cause problems. I sort of feel like it probably shouldn't be
found because the opaque types should be distinct, but I also don't
really understand how it ought to work, so maybe I'm way off base.

Quick follow up on this,

I tried defining DEBUG_MERGE_TYPES to see if I could figure out what
was going wrong, but that made the problem disappear. Similarly,
sometimes, running it in a debugger causes the assert not to trigger.

Changing the test to:

int main()
{
    LLVMTypeRef x = LLVMOpaqueType();
    printf("%p\n", x);
    LLVMTypeRef a = LLVMPointerType(x, 0);
    LLVMTypeHandleRef ha = LLVMCreateTypeHandle(a);
    LLVMTypeRef atypes[1] = { LLVMResolveTypeHandle(ha) };
    LLVMRefineType(LLVMResolveTypeHandle(ha), LLVMStructType(atypes, 1, 0));

    LLVMTypeRef y = LLVMOpaqueType();
    printf("%p\n", y);
    LLVMTypeRef b = LLVMPointerType(y, 0);
    LLVMTypeHandleRef hb = LLVMCreateTypeHandle(b);
    LLVMTypeRef btypes[1] = { LLVMResolveTypeHandle(hb) };
    LLVMRefineType(LLVMResolveTypeHandle(hb), LLVMStructType(btypes, 1, 0));

    return 0;
}

made it a little more clear what was going on. When this test "works",
the return value from LLVMOpaqueType() is different both times, and
while PointerTypes in Type.cpp still has the old opaque type left
over, it isn't found.

But, since the first opaque type gets refined away (and deleted),
LLVMOpaqueType can return the same pointer value twice, meaning that
the PointerTypes map holding PointerValType's has a Type* that's
invalid.

Could anyone suggest where to try invalidating that map? (if that's
the right thing to do). Or perhaps PointerValType needs to be a
PATypeHolder?

thanks,
scott

It looks like a bug; the type map is somehow holding onto a stale
pointer to an opaque type. That said, refining a pointer type is a
very unusual operation; I'd suggest sticking to refining opaque types.

-Eli

Can anyone explain what I'm doing wrong here?

It looks like a bug; the type map is somehow holding onto a stale
pointer to an opaque type. That said, refining a pointer type is a
very unusual operation; I'd suggest sticking to refining opaque types.

Ah, that would be it. Thanks!

Could I suggest adding:

  assert(NewType->getTypeID() != PointerTyID && "Should not be
refining pointer type!");

to DerivedType::refineAbstractTypeTo(const Type *NewType)

if/because refining pointers makes no sense?

scott