[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