[llvm-commits] [llvm-gcc-4.2] r41269 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h llvm-types.cpp
Duncan Sands
baldrick at free.fr
Wed Aug 22 01:47:00 PDT 2007
Author: baldrick
Date: Wed Aug 22 03:46:59 2007
New Revision: 41269
URL: http://llvm.org/viewvc/llvm-project?rev=41269&view=rev
Log:
TREE_OVERFLOW is no longer reliable, so just try to
do something reasonable if imperfect for array types
with overflowed size or length.
Modified:
llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
llvm-gcc-4.2/trunk/gcc/llvm-internal.h
llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=41269&r1=41268&r2=41269&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Aug 22 03:46:59 2007
@@ -299,7 +299,6 @@
/// isInt64 - Return true if t is an INTEGER_CST that fits in a 64 bit integer.
/// If Unsigned is false, returns whether it fits in a int64_t. If Unsigned is
/// true, returns whether the value is non-negative and fits in a uint64_t.
-/// Always returns false for overflowed constants.
bool isInt64(tree t, bool Unsigned) {
if (HOST_BITS_PER_WIDE_INT == 64)
return host_integerp(t, Unsigned);
@@ -307,7 +306,7 @@
assert(HOST_BITS_PER_WIDE_INT == 32 &&
"Only 32- and 64-bit hosts supported!");
return
- (TREE_CODE (t) == INTEGER_CST && !TREE_OVERFLOW (t))
+ (TREE_CODE (t) == INTEGER_CST)
&& ((TYPE_UNSIGNED(TREE_TYPE(t)) == Unsigned) ||
// If the constant is signed and we want an unsigned result, check
// that the value is non-negative. If the constant is unsigned and
@@ -318,8 +317,8 @@
/// getInt64 - Extract the value of an INTEGER_CST as a 64 bit integer. If
/// Unsigned is false, the value must fit in a int64_t. If Unsigned is true,
-/// the value must be non-negative and fit in a uint64_t. Must not be used on
-/// overflowed constants. These conditions can be checked by calling isInt64.
+/// the value must be non-negative and fit in a uint64_t. These conditions
+/// can be checked by calling isInt64.
uint64_t getInt64(tree t, bool Unsigned) {
assert(isInt64(t, Unsigned) && "invalid constant!");
return getINTEGER_CSTVal(t);
Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=41269&r1=41268&r2=41269&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Wed Aug 22 03:46:59 2007
@@ -189,13 +189,12 @@
/// isInt64 - Return true if t is an INTEGER_CST that fits in a 64 bit integer.
/// If Unsigned is false, returns whether it fits in a int64_t. If Unsigned is
/// true, returns whether the value is non-negative and fits in a uint64_t.
-/// Always returns false for overflowed constants.
bool isInt64(tree_node *t, bool Unsigned);
/// getInt64 - Extract the value of an INTEGER_CST as a 64 bit integer. If
/// Unsigned is false, the value must fit in a int64_t. If Unsigned is true,
-/// the value must be non-negative and fit in a uint64_t. Must not be used on
-/// overflowed constants. These conditions can be checked by calling isInt64.
+/// the value must be non-negative and fit in a uint64_t. These conditions can
+/// be checked by calling isInt64.
uint64_t getInt64(tree_node *t, bool Unsigned);
/// isPassedByInvisibleReference - Return true if the specified type should be
Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=41269&r1=41268&r2=41269&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Wed Aug 22 03:46:59 2007
@@ -73,8 +73,15 @@
// Note down LLVM type for GCC tree node.
static const Type * llvm_set_type(tree Tr, const Type *Ty) {
+ // Require gcc and LLVM types to have the same size, if the gcc type has a
+ // constant size that fits in 64 bits. Unfortunately we have to make an
+ // exception for huge arrays for which the size overflowed.
assert(!TYPE_SIZE(Tr) || !Ty->isSized() || !isInt64(TYPE_SIZE(Tr), true) ||
getInt64(TYPE_SIZE(Tr), true) == getTargetData().getTypeSizeInBits(Ty)
+ // Due to TREE_OVERFLOW not always being set correctly, we sometimes
+ // turn a gcc array with an overflowed size into a zero length LLVM
+ // array.
+ || (isa<ArrayType>(Ty) && !cast<ArrayType>(Ty)->getNumElements())
&& "LLVM type size doesn't match GCC type size!");
unsigned &TypeSlot = LTypesMap[Ty];
@@ -302,10 +309,11 @@
(!TYPE_SIZE(type) && isSequentialCompatible(type)) ||
// Arrays with constant size map to LLVM arrays. If the array has zero
- // size then there can be two exotic cases: (1) the array might have zero
- // length and a component type of variable size; or (2) the array could
- // have variable length and a component type with zero size. In both
- // cases we convert to a zero length LLVM array.
+ // size then there can be three exotic cases: (1) the array might have
+ // zero length and a component type of variable size; or (2) the array
+ // could have variable length and a component type with zero size; or
+ // (3) the array size computation overflowed, giving an apparent size of
+ // zero. In all cases we convert to a zero length LLVM array.
(TYPE_SIZE(type) && isInt64(TYPE_SIZE(type), true))
);
}
@@ -840,18 +848,28 @@
// to an unsized array of elements.
NumElements = 0;
} else if (!isInt64(length, true)) {
- // A variable length array where the element type has size zero. Turn
- // it into a zero length array of the element type.
- assert(integer_zerop(TYPE_SIZE(TREE_TYPE(type)))
- && "variable length array has constant size!");
+ // A variable length array where the element type has size zero.
+ // Alternatively, the length may be negative due to overflow.
+ // Turn it into a zero length array of the element type.
NumElements = 0;
} else {
// Normal array.
NumElements = getInt64(length, true);
}
- return TypeDB.setType(type, ArrayType::get(ConvertType(TREE_TYPE(type)),
- NumElements));
+ const Type *Ty = ArrayType::get(ConvertType(TREE_TYPE(type)),
+ NumElements);
+
+ if (NumElements && TYPE_SIZE(type) && Ty->isSized() &&
+ getInt64(TYPE_SIZE(type), true) !=
+ getTargetData().getTypeSizeInBits(Ty))
+ // The type size and/or the array length overflowed. It would be nice
+ // to detect this earlier as in llvm-gcc-4.0, but unfortunately
+ // TREE_OVERFLOW is no longer reliable. Use a zero length array.
+ // This may result in wrong code, but that seems to be unavoidable.
+ Ty = ArrayType::get(ConvertType(TREE_TYPE(type)), 0);
+
+ return TypeDB.setType(type, Ty);
}
// This handles cases like "int A[n]" which have a runtime constant
More information about the llvm-commits
mailing list