Function pointers in structs in arrays codegen assert

It's fine for function pointers in global arrays, and function
pointers in global structs, just not the combination...

typedef void (* F)(void);
extern void foo(void);
struct S { F f; };
struct S a[1] = { { foo } };

CookieJar:Desktop keith$ clang -emit-llvm fptrinit.c
Assertion failed: (ILE->getType()->isArrayType() ||
ILE->getType()->isStructureType()), function GenerateAggregateInit,
file CodeGenModule.cpp, line 283.

-Keith

This looks like a sema bug. The init list expr is getting type "void", which is clearly wrong :slight_smile:

typedef void (* F)(void);
extern void foo(void);

struct S { F f; };
void bar() {
   struct S a[1] = { { foo } };
}

void bar()
(CompoundStmt 0x8061c0 <t.c:5:12, line:7:1>
   (DeclStmt 0x8061b0 <:0:0>
     0x806100 "struct S a[1] =
       (InitListExpr 0x806180 <t.c:6:19, col:29> 'struct S [1]'
         (InitListExpr 0x806150 <col:21, col:27> 'void'
           (DeclRefExpr 0x806130 <col:23> 'void (void)' FunctionDecl='foo' 0x806020)))"

Steve, please take a look. Incidentally, it looks like the sourcerange on the declstmt is wrong.

-Chris

Yeah the ILE with type void screws with compound initialisers -- eg struct of structs, array of structs, etc.
Broadly speaking the global struct initialiser logic (at least) should be able to handle these once the ILE
has the correct type.
Unfortunately that doesn't resolve the problem that C apparently allows the ILE's for initialising arrays of
structs, etc to be flattened. eg.
struct S {int a; int b;}
struct S foo = {{1,2}, {3,4}};
struct S bar = {1, 2, 3, 4};

foo and bar are both valid -- the initialiser logic will hork itself in that case.

--Oliver

Yeah the ILE with type void screws with compound initialisers -- eg struct of structs, array of structs, etc.
Broadly speaking the global struct initialiser logic (at least) should be able to handle these once the ILE
has the correct type.
Unfortunately that doesn't resolve the problem that C apparently allows the ILE's for initialising arrays of
structs, etc to be flattened. eg.
struct S {int a; int b;}
struct S foo = {{1,2}, {3,4}};
struct S bar = {1, 2, 3, 4};

foo and bar are both valid -- the initialiser logic will hork itself in that case.

Sema should produce an AST that is the same for both of those cases: in the 'bar' case, it should synthesize two initlistexprs of the right type.

-Chris