Skip to content

Verification failure for recursive struct #152

@gitoleg

Description

@gitoleg

The following code

struct ListNode {
  struct ListNode *next;
};

struct List {
  struct ListNode head;
};

void foo(struct List *lst) {
  lst->head.next = &lst->head;
}

currently fails verification due to

$ clang -fclangir-enable -S tmp.c
...
loc(fused["tmp.c":10:3, "tmp.c":10:26]): error: 'cir.store' op failed to verify that type of 'value' matches pointee type of 'addr'
fatal error: error in backend: CIR codegen: module verification error before running CIR passes

The problem is in the assignment operation which expands to

cir.store %2, %5 : !cir.ptr<!cir.struct<"struct.ListNode", !cir.ptr<!cir.struct<"struct.ListNode", incomplete, #cir.recdecl.ast>>, #cir.recdecl.ast>>, cir.ptr <!cir.ptr<!cir.struct<"struct.ListNode", incomplete, #cir.recdecl.ast>>>

As we can see type of the stored value is complete:

!cir.ptr<!cir.struct<"struct.ListNode", !cir.ptr<!cir.struct<"struct.ListNode", incomplete, #cir.recdecl.ast>>, #cir.recdecl.ast>>

but type of the address is not:

!cir.ptr<!cir.ptr<!cir.struct<"struct.ListNode", incomplete, #cir.recdecl.ast>>>

This cause verification failure due to StoreOp's TypesMatchWith constraint.

What would be the best way to fix this? My understanding is that MLIR does not allow recursive types...

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions