First Last Prev Next    No search results available
Details
: [llvm-gcc] crash on union initialization
Bug#: 155
: tools
: llvm-gcc
Status: RESOLVED
Resolution: FIXED
: All
: All
: 1.0
: P2
: normal
: 1.1

:
: compile-fail
:
:
  Show dependency tree - Show dependency graph
People
Reporter: Misha Brukman <brukman+bugs@uiuc.edu>
Assigned To: Chris Lattner <clattner@apple.com>

Attachments


Note

You need to log in before you can comment on or make changes to this bug.

Related actions


Description:   Opened: 2003-11-25 14:23
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.
------- Comment #1 From Chris Lattner 2003-11-25 14:25:41 -------
Urg.  What the heck is non_lvalue_expr?

-Chris
------- Comment #2 From Chris Lattner 2003-11-25 19:14:32 -------
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

First Last Prev Next    No search results available