[LLVMbugs] [Bug 906] llvm-gcc4 crashes on this bitfield reference
bugzilla-daemon at cs.uiuc.edu
bugzilla-daemon at cs.uiuc.edu
Mon Sep 11 15:49:48 PDT 2006
http://llvm.org/bugs/show_bug.cgi?id=906
sabre at nondot.org changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
Keywords| |code-quality, compile-fail
Resolution| |FIXED
Target Milestone|--- |1.9
------- Additional Comments From sabre at nondot.org 2006-09-11 17:49 -------
Fixed. Testcase here:
Regression/CFrontend/2006-09-11-BitfieldRefCrash.c
Patch here:
Index: llvm-convert.cpp
===============================================================
====
--- llvm-convert.cpp (revision 117816)
+++ llvm-convert.cpp (working copy)
@@ -3704,6 +3704,9 @@
}
if (tree DeclaredType = DECL_BIT_FIELD_TYPE(FieldDecl)) {
+ const Type *LLVMFieldTy =
+ cast<PointerType>(FieldPtr->getType())->getElementType();
+
// If this is a bitfield, the declared type must be an integral type.
FieldTy = ConvertType(DeclaredType);
// If the field result is a bool, cast to a ubyte instead. It is not
@@ -3713,11 +3716,20 @@
FieldTy = Type::UByteTy;
assert(FieldTy->isInteger() && "Invalid bitfield");
+ // If the LLVM notion of the field type is larger than the actual field type
+ // being accessed, use the LLVM type. This avoids pointer casts and other
+ // bad things that are difficult to clean up later. This occurs in cases
+ // like "struct X{ unsigned long long x:50; unsigned y:2; }" when accessing
+ // y. We want to access the field as a ulong, not as a uint with an offset.
+ if (LLVMFieldTy->isInteger() &&
+ LLVMFieldTy->getPrimitiveSize() > FieldTy->getPrimitiveSize())
+ FieldTy = LLVMFieldTy;
+
// We are now loading/storing through a casted pointer type, whose
// signedness depends on the signedness of the field. Force the field to
// be unsigned. This solves performance problems where you have, for
// example: struct { int A:1; unsigned B:2; }; Consider a store to A then
- // a store to be. In this case, without this conversion, you'd have a
+ // a store to B. In this case, without this conversion, you'd have a
// store through an int*, followed by a load from a uint*. Forcing them
// both to uint* allows the store to be forwarded to the load.
FieldTy = FieldTy->getUnsignedVersion();
-Chris
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.
More information about the llvm-bugs
mailing list