Bugzilla – Bug 155
[llvm-gcc] crash on union initialization
Last modified: 2003-11-25 19:14:32
You need to log in before you can comment on or make changes to this bug.
This happens to occur in the Linux kernel... linux/arch/i386/kernel/init_task.c to be more precise. % cat it.i struct list_head { struct list_head *next, *prev; }; struct task_struct { int filler; struct list_head thread_group; }; union task_union { struct task_struct task; unsigned long stack[2048*sizeof(long)/sizeof(long)]; }; union task_union init_task_union = { { thread_group: { &(init_task_union.task.thread_group), 0 }, } }; % llvm-gcc it.i ERROR: In function llvm_expand_constant_expr:4488, tree not handled by LLVM yet! <non_lvalue_expr 0x402480dc type <pointer_type 0x40247310 type <record_type 0x40246d90 task_struct type_0 BLK size <integer_cst 0x40242c30 constant 96> unit size <integer_cst 0x400246b8 constant 12> align 32 symtab 0 alias set -1 fields <field_decl 0x40246e70 filler> context <translation_unit_decl 0x4001d070> pointer_to_this <pointer_type 0x40247310> chain <type_decl 0x40246e00>> unsigned SI size <integer_cst 0x4001b7d0 constant 32> unit size <integer_cst 0x4001b7f8 constant 4> align 32 symtab 0 alias set -1> constant arg 0 <nop_expr 0x402480c8 type <pointer_type 0x40247310> constant arg 0 <addr_expr 0x40248078 type <pointer_type 0x40247380> constant arg 0 <var_decl 0x402472a0 init_task_union>>>> it.i:14: internal compiler error: in llvm_expand_constant_expr, at llvm-expand.c:4488 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://llvm.cs.uiuc.edu> for instructions. Furthermore, if we remove "int filler" from the struct above, the error we get is different: cc1: ../../gcc-3.4/gcc/llvm-expand.c:144: cast_if_type_not_equal: Assertion `((V->Ty)->ID == PointerTyID || ((V->Ty->ID < FunctionTyID) && (V->Ty)->ID != VoidTyID)) &&"Cannot cast from non-first-class type!"' failed. it.i:13: internal compiler error: Aborted Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://llvm.cs.uiuc.edu> for instructions. GCC 3.3 seems to chew through this code without a problem.
Urg. What the heck is non_lvalue_expr? -Chris
Hrm... the first one was easy: $ diff -u llvm-expand.c~ llvm-expand.c --- llvm-expand.c~ 2003-11-25 18:19:27.000000000 -0600 +++ llvm-expand.c 2003-11-25 18:25:10.000000000 -0600 @@ -4443,6 +4443,7 @@ break; case NOP_EXPR: /* Cast constant_expr */ + case NON_LVALUE_EXPR: case CONVERT_EXPR: Val = D2V(llvm_expand_constant_expr(TREE_OPERAND(exp, 0), llvm_type_get_from_tree(TREE_TYPE(TREE_OPERAND(exp, 0))))); The second one was more phun: ]$ diff -u llvm-expand.c~ llvm-expand.c --- llvm-expand.c~ 2003-11-25 18:19:27.000000000 -0600 +++ llvm-expand.c 2003-11-25 19:10:27.000000000 -0600 @@ -3167,6 +3167,37 @@ ... Expansion of CONSTRUCTOR nodes ... *===----------------------------------------------------------------------===*/ +static void ExpandConstantInto(llvm_function *Fn, llvm_value *Val, + llvm_type **ElementTypes, llvm_value **Elements, + unsigned *Idx, unsigned Size) { + llvm_type *SourceTy = Val->Ty; + llvm_value **SrcElements; + unsigned i, SourceSize; + + if (llvm_type_is_scalar(SourceTy)) { + /* Reexpand the initializer into the current element. */ + Elements[*Idx] = cast_if_type_not_equal(Fn, Val, ElementTypes[*Idx]); + ++*Idx; + return; + } + + /* If this is an aggregate value, expand each element into the source slot */ + assert(Val->VTy == ConstantAggregate && + "Constant initializer translation is broken!"); + SrcElements = ((llvm_constant_aggregate*)Val)->Initializers; + + if (SourceTy->ID == ArrayTyID) { + SourceSize = GET_ARRAY_TYPE_SIZE(SourceTy); + } else if (SourceTy->ID == StructTyID) { + SourceSize = SourceTy->NumElements; + } else { + assert(0 && "Don't know how to expand this!"); + } + + for (i = 0; i < SourceSize && *Idx < Size; ++i) + ExpandConstantInto(Fn, SrcElements[i], ElementTypes, Elements, Idx, Size); +} + /* llvm_expand_constructor_element - This function handles the case of * initialization of either a contructor constant element or a constructor value * element in a function scope. @@ -3268,30 +3299,8 @@ ElementTypes[i] = GET_STRUCT_TYPE_ELEMENT(ElTy, i); } - if (llvm_type_is_scalar(SourceTy)) { - /* Reexpand the initializer into the zero'th element. */ - Elements[0] = llvm_expand_constructor_element(Fn, 0, value, - ElementTypes[0], 0, 0); - i = 1; - } else { - llvm_value **SrcElements; - unsigned SourceSize; - assert(Val->VTy == ConstantAggregate && - "Constant initializer translation"); - SrcElements = ((llvm_constant_aggregate*)Val)->Initializers; - - if (SourceTy->ID == ArrayTyID) { - SourceSize = GET_ARRAY_TYPE_SIZE(SourceTy); - } else if (SourceTy->ID == StructTyID) { - SourceSize = SourceTy->NumElements; - } else { - assert(0 && "Don't know how to expand this!"); - } - - for (i = 0; i < SourceSize && i < Size; ++i) - Elements[i] = cast_if_type_not_equal(Fn, SrcElements[i], - ElementTypes[i]); - } + i = 0; + ExpandConstantInto(Fn, Val, ElementTypes, Elements, &i, Size); /* For the rest of the initializer, expand nulls. */ for (; i != Size; ++i) Nevertheless, this is now fixed. -Chris