-
Notifications
You must be signed in to change notification settings - Fork 171
Description
Let's discuss recursive types again.
The long story short - I have a verification failure in the GetMemberOp
: index out of bounds.
The code to reproduce is the following:
typedef struct SomeStruct {
struct SomeStruct* prev;
struct SomeStruct* next;
int x;
} A;
typedef struct {
A some;
} B;
void foo(B* b, A* a) {
a->x = 42; // <---- getMemberOp failed
}
Note, if we swap arguments as foo(A* a, B* b)
everything will be fine.
I spent a huge amount of time trying to understand the reason ( what is probably bad for me :) )
And what I came to is approximately the following.
First of all, the CIRGenTypes.cpp
and CIRRecordLayoutBuilder.cpp
have a similar implementation to one in clang/Codegen
. But the behaviour is different. I'm sure that the difference caused by CIR StructType
implementation and by the fact that instances of llvm::Type
counterpart are stored by pointer and are mutable.
For example, this is how the type is updated in the CGRecordLayoutBuilder
:
Ty->setBody(Builder.FieldTypes...
.
And how it's done in CIR
:
*Ty = Builder.getStructTy(builder.fieldTypes, ...
,
i.e. we create a new instance of mlir::Type
here. This is matter for the TypeCache
in the CIRGenTypes
: the type entry is stored by value. So when we create a new instance - nothing is reflected anywhere.
As I said, once we swap foo
's arguments, everything will be fine - i.e. it depends on order in which we create types and recursively traverse them.
There are several solution I can think of:
- relax the verification - may be it will help, since my test code worked with the
StructElementAddr
before, where no verification was used. - add kind of a mutability in
StructType
, so we will be able to actually change something during the recursive calls ofConverType
. Also we will need to be careful with passing types as arguments, i.e. pass them by reference. - Something else, e.g. don't cache incomplete types.
So.. what thoughts do you have? May be it's a known issue and the answer is simple one?