summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2013-10-10 00:54:01 +0000
committerTed Kremenek <kremenek@apple.com>2013-10-10 00:54:01 +0000
commite65ab9e80eec0e56235bd74c6d487e5a89f66146 (patch)
treeceb1fb9ddc399b69541c0dd546171b9ce0f857b5
parent394e36dc810f8261bcf69d788ad412b7a1c5798f (diff)
downloadbcm5719-llvm-e65ab9e80eec0e56235bd74c6d487e5a89f66146.tar.gz
bcm5719-llvm-e65ab9e80eec0e56235bd74c6d487e5a89f66146.zip
Fix getIntegerTypeOrder() to properly handle enums by first unwrapping their underlying integer type. This is a precondition for calling getIntegerRank().
Fixes an assertion failure in a test case involving vectors. Fixes <rdar://problem/15091442> Please somebody check this. llvm-svn: 192334
-rw-r--r--clang/lib/AST/ASTContext.cpp15
-rw-r--r--clang/test/Sema/ext_vector_casts.c24
2 files changed, 39 insertions, 0 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 3b5bfe6d8c3..04711e330c0 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -4417,12 +4417,27 @@ Qualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const {
return Qualifiers::OCL_None;
}
+static const Type *getIntegerTypeForEnum(const EnumType *ET) {
+ // Incomplete enum types are not treated as integer types.
+ // FIXME: In C++, enum types are never integer types.
+ if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
+ return ET->getDecl()->getIntegerType().getTypePtr();
+ return NULL;
+}
+
/// getIntegerTypeOrder - Returns the highest ranked integer type:
/// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If
/// LHS < RHS, return -1.
int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const {
const Type *LHSC = getCanonicalType(LHS).getTypePtr();
const Type *RHSC = getCanonicalType(RHS).getTypePtr();
+
+ // Unwrap enums to their underlying type.
+ if (const EnumType *ET = dyn_cast<EnumType>(LHSC))
+ LHSC = getIntegerTypeForEnum(ET);
+ if (const EnumType *ET = dyn_cast<EnumType>(RHSC))
+ RHSC = getIntegerTypeForEnum(ET);
+
if (LHSC == RHSC) return 0;
bool LHSUnsigned = LHSC->isUnsignedIntegerType();
diff --git a/clang/test/Sema/ext_vector_casts.c b/clang/test/Sema/ext_vector_casts.c
index 848ec1f106f..03316501a0e 100644
--- a/clang/test/Sema/ext_vector_casts.c
+++ b/clang/test/Sema/ext_vector_casts.c
@@ -5,6 +5,9 @@ typedef __attribute__(( ext_vector_type(4) )) int int4;
typedef __attribute__(( ext_vector_type(8) )) short short8;
typedef __attribute__(( ext_vector_type(4) )) float float4;
typedef float t3 __attribute__ ((vector_size (16)));
+typedef __typeof__(sizeof(int)) size_t;
+typedef unsigned long ulong2 __attribute__ ((ext_vector_type(2)));
+typedef size_t stride4 __attribute__((ext_vector_type(4)));
static void test() {
float2 vec2;
@@ -50,3 +53,24 @@ void inc(float2 f2) {
f2++; // expected-error{{cannot increment value of type 'float2'}}
__real f2; // expected-error{{invalid type 'float2' to __real operator}}
}
+
+typedef enum
+{
+ uchar_stride = 1,
+ uchar4_stride = 4,
+ ushort4_stride = 8,
+ short4_stride = 8,
+ uint4_stride = 16,
+ int4_stride = 16,
+ float4_stride = 16,
+} PixelByteStride;
+
+stride4 RDar15091442_get_stride4(int4 x, PixelByteStride pixelByteStride);
+stride4 RDar15091442_get_stride4(int4 x, PixelByteStride pixelByteStride)
+{
+ stride4 stride;
+ // This previously caused an assertion failure.
+ stride.lo = ((ulong2) x) * pixelByteStride; // no-warning
+ return stride;
+}
+
OpenPOWER on IntegriCloud