[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