Skip to content

Commit e65ab9e

Browse files
committed
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
1 parent 394e36d commit e65ab9e

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

clang/lib/AST/ASTContext.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4417,12 +4417,27 @@ Qualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const {
44174417
return Qualifiers::OCL_None;
44184418
}
44194419

4420+
static const Type *getIntegerTypeForEnum(const EnumType *ET) {
4421+
// Incomplete enum types are not treated as integer types.
4422+
// FIXME: In C++, enum types are never integer types.
4423+
if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
4424+
return ET->getDecl()->getIntegerType().getTypePtr();
4425+
return NULL;
4426+
}
4427+
44204428
/// getIntegerTypeOrder - Returns the highest ranked integer type:
44214429
/// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If
44224430
/// LHS < RHS, return -1.
44234431
int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const {
44244432
const Type *LHSC = getCanonicalType(LHS).getTypePtr();
44254433
const Type *RHSC = getCanonicalType(RHS).getTypePtr();
4434+
4435+
// Unwrap enums to their underlying type.
4436+
if (const EnumType *ET = dyn_cast<EnumType>(LHSC))
4437+
LHSC = getIntegerTypeForEnum(ET);
4438+
if (const EnumType *ET = dyn_cast<EnumType>(RHSC))
4439+
RHSC = getIntegerTypeForEnum(ET);
4440+
44264441
if (LHSC == RHSC) return 0;
44274442

44284443
bool LHSUnsigned = LHSC->isUnsignedIntegerType();

clang/test/Sema/ext_vector_casts.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ typedef __attribute__(( ext_vector_type(4) )) int int4;
55
typedef __attribute__(( ext_vector_type(8) )) short short8;
66
typedef __attribute__(( ext_vector_type(4) )) float float4;
77
typedef float t3 __attribute__ ((vector_size (16)));
8+
typedef __typeof__(sizeof(int)) size_t;
9+
typedef unsigned long ulong2 __attribute__ ((ext_vector_type(2)));
10+
typedef size_t stride4 __attribute__((ext_vector_type(4)));
811

912
static void test() {
1013
float2 vec2;
@@ -50,3 +53,24 @@ void inc(float2 f2) {
5053
f2++; // expected-error{{cannot increment value of type 'float2'}}
5154
__real f2; // expected-error{{invalid type 'float2' to __real operator}}
5255
}
56+
57+
typedef enum
58+
{
59+
uchar_stride = 1,
60+
uchar4_stride = 4,
61+
ushort4_stride = 8,
62+
short4_stride = 8,
63+
uint4_stride = 16,
64+
int4_stride = 16,
65+
float4_stride = 16,
66+
} PixelByteStride;
67+
68+
stride4 RDar15091442_get_stride4(int4 x, PixelByteStride pixelByteStride);
69+
stride4 RDar15091442_get_stride4(int4 x, PixelByteStride pixelByteStride)
70+
{
71+
stride4 stride;
72+
// This previously caused an assertion failure.
73+
stride.lo = ((ulong2) x) * pixelByteStride; // no-warning
74+
return stride;
75+
}
76+

0 commit comments

Comments
 (0)