[llvm-commits] CVS: llvm-gcc/gcc/llvm-types.c llvm-expand.c

Chris Lattner lattner at cs.uiuc.edu
Fri May 7 13:34:02 PDT 2004


Changes in directory llvm-gcc/gcc:

llvm-types.c updated: 1.4 -> 1.5
llvm-expand.c updated: 1.38 -> 1.39

---
Log message:

Fix the first part of PR298: http://llvm.cs.uiuc.edu/PR298 : [llvmgcc] Variable length array indexing miscompiled


---
Diffs of the changes:  (+44 -16)

Index: llvm-gcc/gcc/llvm-types.c
diff -u llvm-gcc/gcc/llvm-types.c:1.4 llvm-gcc/gcc/llvm-types.c:1.5
--- llvm-gcc/gcc/llvm-types.c:1.4	Wed Apr 21 13:57:43 2004
+++ llvm-gcc/gcc/llvm-types.c	Fri May  7 13:34:32 2004
@@ -987,19 +987,25 @@
 
   case ARRAY_TYPE: {
     unsigned NumElements;
-    if (TYPE_DOMAIN(type) && TYPE_MAX_VALUE(TYPE_DOMAIN(type)) &&
-        TREE_CODE(TYPE_MAX_VALUE(TYPE_DOMAIN(type))) == INTEGER_CST) {
-      NumElements = TREE_INT_CST_LOW(TYPE_MAX_VALUE(TYPE_DOMAIN(type)))+1;
+    tree Domain = TYPE_DOMAIN(type);
+    if (Domain && TYPE_MAX_VALUE(Domain)) {
+      if (TREE_CODE(TYPE_MAX_VALUE(Domain)) == INTEGER_CST) {
+        /* Normal array */
+        NumElements = TREE_INT_CST_LOW(TYPE_MAX_VALUE(Domain))+1;
+      } else {
+        /* This handles cases like "int A[n]" which have a runtime constant
+         * number of elements, but is a compile-time variable.  Since these are
+         * variable sized, we just represent them as the element themself.
+         */
+        return llvm_type_get_from_tree(TREE_TYPE(type));
+      }
     } else {
-      /* Otherwise the reasons we could get here is if they have something that
-       * is globally declared as an array with no dimension, this becomes just a
-       * zero size array of the element type so that: int X[] becomes *'%X =
-       * external global [0 x int]'
+      /* We get here is if they have something that is globally declared as an
+       * array with no dimension, this becomes just a zero size array of the
+       * element type so that: int X[] becomes *'%X = external global [0 x int]'
        *
        * Note that this also affects new expressions, which return a pointer to
-       * an unsized array of elements.  This also effects things like "int A[n]"
-       * which has an runtime constant number of elements, but is a compile-time
-       * variable.
+       * an unsized array of elements.
        */
       NumElements = 0;
     }


Index: llvm-gcc/gcc/llvm-expand.c
diff -u llvm-gcc/gcc/llvm-expand.c:1.38 llvm-gcc/gcc/llvm-expand.c:1.39
--- llvm-gcc/gcc/llvm-expand.c:1.38	Fri May  7 12:28:45 2004
+++ llvm-gcc/gcc/llvm-expand.c	Fri May  7 13:34:32 2004
@@ -5223,11 +5223,13 @@
   case ARRAY_REF: {
     tree tOp0 = TREE_OPERAND(exp, 0), tOp1 = TREE_OPERAND(exp, 1);
     llvm_type *Op0Ty = llvm_type_get_from_tree(TREE_TYPE(tOp0));
+    llvm_type *IntPtrTy =
+      llvm_type_get_integer(llvm_type_get_size(VoidPtrTy)*8, 0);
 
     if (llvm_type_is_composite(Op0Ty)) {
       llvm_value *Op0 = llvm_expand_lvalue_expr(Fn, tOp0, 0, 0);
       llvm_value *Op1 = llvm_expand_expr(Fn, tOp1, 0);
-      Op1 = cast_if_type_not_equal(Fn, Op1, LongTy);
+      Op1 = cast_if_type_not_equal(Fn, Op1, IntPtrTy);
       Result = append_inst(Fn, create_gep3(Op0, llvm_constant_long_0, Op1));
     } else {
       llvm_instruction *I;
@@ -5235,12 +5237,32 @@
        * take a pointer as the first operand.  In this case, we generate a two
        * operand GEP.
        */
-      llvm_value *Op0 = llvm_expand_expr(Fn, tOp0, 0);
-      llvm_value *Op1 = llvm_expand_expr(Fn, tOp1, 0);
-      llvm_type *IntPtrTy =
-        llvm_type_get_integer(llvm_type_get_size(VoidPtrTy)*8, 0);
+      llvm_value *Op0, *Op1;
+      unsigned LLVMSize;
+      
+      if (TREE_CODE(TREE_TYPE(tOp0)) == ARRAY_TYPE)
+        Op0 = llvm_expand_lvalue_expr(Fn, tOp0, 0, 0);
+      else
+        Op0 = llvm_expand_expr(Fn, tOp0, 0);
+      Op1 = llvm_expand_expr(Fn, tOp1, 0);
+      LLVMSize = llvm_type_get_size(GET_POINTER_TYPE_ELEMENT(Op0->Ty));
       Op1 = cast_if_type_not_equal(Fn, Op1, IntPtrTy);
-      /* FIXME: What do we do about bitfields here??? */
+
+      /* If we are stepping over a variable sized array, then the element size
+       * of the array will not match the size of the pointer, and we need to
+       * scale the index.
+       */
+      if (TREE_CODE(TREE_TYPE(tOp0)) == POINTER_TYPE) {
+        tree PointeeSize = TYPE_SIZE_UNIT(TREE_TYPE(TREE_TYPE(tOp0)));
+        if (TREE_CODE(PointeeSize) == INTEGER_CST) {
+          unsigned GCCSize = TREE_INT_CST_LOW(PointeeSize);
+          assert(GCCSize == LLVMSize &&"Unknown pointer subscript expression!");
+        } else {
+          llvm_value *Size = llvm_expand_expr(Fn, PointeeSize, 0);
+          Size = cast_if_type_not_equal(Fn, Size, Op1->Ty);
+          Op1 = append_inst(Fn, create_binary_inst("tmp", O_Mul, Op1, Size));
+        }
+      }
       
       assert(Op0->Ty->ID == PointerTyID &&
              "Cannot subscript non-pointer, non-array type!");





More information about the llvm-commits mailing list