Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assertion failed: "Initializer for composite element doesn't match!" #1741

Closed
JohanEngelen opened this issue Sep 4, 2016 · 13 comments
Closed

Comments

@JohanEngelen
Copy link
Member

JohanEngelen commented Sep 4, 2016

Steps to reproduce:

  • dub init -t vibe.d test
  • dub build -b debug --combined --compiler=ldc2

Fails for LDC built with LLVM 3.9.0 and LLVM 4.0 (trunk), with the LLVM assert:

type mismatch for entry # 6 in vtbl initializer
%vibe.core.task.Task (%vibe.core.task.TaskFiber*)*
{ i8*, i64 } (%vibe.core.task.TaskFiber*)*
Assertion failed: (V[I]->getType() == T->getTypeAtIndex(I) && "Initializer for composite element doesn't match!"), function ConstantAggregate, file ../lib/IR/Constants.cpp, line 881.

Works fine with LLVM 3.8.

I haven't had time to narrow this down to something workable, but thought it needed reporting.

@JohanEngelen
Copy link
Member Author

vibe version: vibe-d-0.7.29

@JohanEngelen
Copy link
Member Author

dustmiting...

@JohanEngelen
Copy link
Member Author

JohanEngelen commented Sep 4, 2016

File a.d

import task;

Task runTask;

File task.d

class Super
{

    this(void delegate())
    {
    }

}

struct Task
{
    shared(Child) m_fiber;
}

class Child : Super
{
    this(void delegate() fun)
    {
        super(fun);
    }

    @property task()
    {
        return Task();
    }
}

ldc2 -c task.d a.d errors with (LLVM 3.9):

type mismatch for entry # 5 in vtbl initializer
%task.Task (%task.Child*)*
i8* (%task.Child*)*
Assertion failed: (V[I]->getType() == T->getTypeAtIndex(I) && "Initializer for composite element doesn't match!"), function ConstantAggregate, file ../lib/IR/Constants.cpp, line 883.

The order of the files on the cmdline is important!
(compiles successfully with LLVM 3.8)

@JohanEngelen JohanEngelen changed the title Error compiling simple vibe.d project with LDC1.1.0 + LLVM3.9 Assertion failed with LLVM 3.9 : "Initializer for composite element doesn't match!" Sep 4, 2016
@dnadlinger
Copy link
Member

Is this a 3.8/3.9 mismatch issue or just down to LLVM assertions being enabled or not?

@JohanEngelen
Copy link
Member Author

Hmm, I initially found this using the 1.1.0 binary package built with LLVM3.8 and 3.9. Apparently one has assertions on, the other doesn't. Doh.

So, indeed, LLVM 3.8 also fails.

@JohanEngelen JohanEngelen changed the title Assertion failed with LLVM 3.9 : "Initializer for composite element doesn't match!" Assertion failed: "Initializer for composite element doesn't match!" Sep 4, 2016
@dnadlinger
Copy link
Member

Hmm, I initially found this using the 1.1.0 binary package built with LLVM3.8 and 3.9. Apparently one has assertions on, the other doesn't. Doh.

This is something we need to figure out for the release. In particular, shipping binaries with assertions enabled would be quite the performance regression. @redstar

@JohanEngelen
Copy link
Member Author

This is something we need to figure out for the release. In particular, shipping binaries with assertions enabled would be quite the performance regression.

This could be because I built the LLVM3.9 package using the SVN branch (instead of downloading the source tarball), which still has asserts enabled by default.

@kinke
Copy link
Member

kinke commented Sep 4, 2016

This looks nearly identical to #1237 (comment):

type mismatch for entry # 5 in vtbl initializer
%task.Task (%task.TaskFiber*)*
i8* (%task.TaskFiber*)*

@kinke
Copy link
Member

kinke commented Nov 19, 2016

Note that Johan's reduced testcase can be happily compiled on Win64 (I've checked both file orders). I can reproduce the issue on Linux x64 though.

@kinke kinke mentioned this issue Nov 19, 2016
@kinke
Copy link
Member

kinke commented Nov 20, 2016

I guess this has something to do with the TargetABI rewriting function types. The fact that it's no issue on Win64 would also point in that direction.

@kinke
Copy link
Member

kinke commented Nov 20, 2016

As suspected, the problem is a forward-referencing issue - for the vtable entries, we ask the TargetABI to rewrite function types which may reference parameter/return types that are currently being defined (and so still opaque). Without a size, it's obviously hard for the TargetABI to decide what to do with such a type, and chances for a discrepancy with the final rewritten function type (used for the function declaration/definition) are quite high.

Relevant excerpt from the -vv log (using the Linux x64 triple for Johan's reduced testcase):

* VarDeclaration::codegen(): 'a.runTask'
* * DtoResolveVariable(a.runTask)
* * * data segment
* * * parent: a (module)
* * * Building type: Task
* * * * Building struct type task.Task @ task.d(10)
* * * * * Field priority for m_fiber: 1
* * * * * Building type: task.Child
* * * * * * Building class type task.Child @ task.d(15)
* * * * * * * Instance size: 16
* * * * * * * Building vtbl type for class task.Child
* * * * * * * * Adding type of object.Object.toString
* * * * * * * * isMember = this is: object.Object
* * * * * * * * DtoFunctionType(string())
* * * * * * * * Adding type of object.Object.toHash
* * * * * * * * isMember = this is: object.Object
* * * * * * * * DtoFunctionType(nothrow @trusted ulong())
* * * * * * * * Adding type of object.Object.opCmp
* * * * * * * * isMember = this is: object.Object
* * * * * * * * DtoFunctionType(int(Object o))
* * * * * * * * Adding type of object.Object.opEquals
* * * * * * * * isMember = this is: object.Object
* * * * * * * * DtoFunctionType(bool(Object o))
* * * * * * * * Adding type of task.Child.task
* * * * * * * * isMember = this is: task.Child
* * * * * * * * DtoFunctionType(pure nothrow @nogc @property @safe Task())
* * * * * * * * * x86-64 ABI: Transforming return type
* * * * * * * * * * Rewriting argument type Task
* * * * * * * * * * * %task.Task = type opaque => i8*     <---
* * * * * * * * * x86-64 ABI: Transforming argument types
* * * * * * * * * Final function type: i8* (%task.Child*)
* * * * * * * class type: %task.Child = type { %task.Child.__vtbl*, i8* }
* * * * * final struct type: %task.Task = type { %task.Child* }

@kinke
Copy link
Member

kinke commented Nov 20, 2016

With #1891, the above excerpt is shortened to:

* VarDeclaration::codegen(): 'a.runTask'
* * DtoResolveVariable(a.runTask)
* * * data segment
* * * parent: a (module)
* * * Building type: Task
* * * * Building struct type task.Task @ task.d(10)
* * * * * Field priority for m_fiber: 1
* * * * * Building type: task.Child
* * * * * * Building class type task.Child @ task.d(15)
* * * * * * * Instance size: 16
* * * * * * * class type: %task.Child = type { [6 x i8*]*, i8* }
* * * * * final struct type: %task.Task = type { %task.Child* }

kinke added a commit to kinke/ldc that referenced this issue Nov 21, 2016
This fixes the forward-referencing issue ldc-developers#1741.
kinke added a commit to kinke/ldc that referenced this issue Nov 21, 2016
This fixes the forward-referencing issue ldc-developers#1741.
@kinke
Copy link
Member

kinke commented Nov 24, 2016

Fixed by #1891.

@kinke kinke closed this as completed Nov 24, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants