Bugzilla – Bug 141
[llvm-gcc] Bitfields & large array don't mix well
Last modified: 2003-11-20 13:07:43
You need to log in before you can comment on or make changes to this bug.
Whereas I thought that the inability of llvm-gcc to chew pine was due to bug 6, apparently fixing it was not enough. Here's a test case reduced from addrbook.c in pine-4.58: struct pine { unsigned read_predicted:1; char cur_folder[4000]; int dlevel; }; extern struct pine *ps_global; void dump_some_debugging(char *message) { ps_global->dlevel = 1; } I thought I already filed this as a bug, but I can't find it. If you do, feel free to mark this as duplicate.
I'm not terribly suprised. The bitfield handling code is quite fragile and due for a rewrite. However, doing this will be a destabilizing change which I do not want to do at this point. This bug should be fixable though. :) -Chris
Another testcase: struct face_cachel { unsigned int reverse :1; unsigned char font_specified[1]; }; void ensure_face_cachel_contains_charset (struct face_cachel *cachel) { cachel->font_specified[0] = 0; }
The second testcase below is fixed by this patch: $ diff -u llvm-expand.c~ llvm-expand.c --- llvm-expand.c~ 2003-11-19 18:25:37.000000000 -0600 +++ llvm-expand.c 2003-11-20 12:59:12.000000000 -0600 @@ -4588,8 +4588,7 @@ llvm_type *Op0Ty = llvm_type_get_from_tree(TREE_TYPE(TREE_OPERAND(exp, 0))); if (llvm_type_is_composite(Op0Ty)) { - llvm_value *Op0 = llvm_expand_lvalue_expr(Fn, TREE_OPERAND(exp, 0), - BitStart, BitSize); + llvm_value *Op0 = llvm_expand_lvalue_expr(Fn, TREE_OPERAND(exp, 0), 0, 0); llvm_value *Op1 = llvm_expand_expr(Fn, TREE_OPERAND(exp, 1), 0); Op1 = cast_if_type_not_equal(Fn, Op1, LongTy); Result = append_inst(Fn, create_gep3(Op0, llvm_constant_long_0, Op1)); @@ -4655,7 +4654,7 @@ /* If this is accessing a union element, we can go ahead and cast the * pointer to the desired type now. */ - if (ActualOffset == Offset && Size > ActualSize) { + if (ActualOffset == Offset && ResultElTy != FieldDeclTy) { assert((ActualSize & 7) == 0 && (Size & 7) == 0 && "Illegal union field reference!"); Result = cast_if_type_not_equal(Fn, Op0, ... and is tested by CFrontend/2003-11-20-Bitfields.c The first testcase in this patch is HELPED by this patch, but not fixed completely. The rest of the fix falls under the guise of Bug 82. -Chris