From: Ted Kremenek Date: Thu, 10 Oct 2013 00:54:01 +0000 (+0000) Subject: Fix getIntegerTypeOrder() to properly handle enums by first unwrapping their underlyi... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=af3b980ef367e031051afd67ca3475bb7aa32db8;p=clang 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 Please somebody check this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192334 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 3b5bfe6d8c..04711e330c 100644 --- a/lib/AST/ASTContext.cpp +++ b/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(LHSC)) + LHSC = getIntegerTypeForEnum(ET); + if (const EnumType *ET = dyn_cast(RHSC)) + RHSC = getIntegerTypeForEnum(ET); + if (LHSC == RHSC) return 0; bool LHSUnsigned = LHSC->isUnsignedIntegerType(); diff --git a/test/Sema/ext_vector_casts.c b/test/Sema/ext_vector_casts.c index 848ec1f106..03316501a0 100644 --- a/test/Sema/ext_vector_casts.c +++ b/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; +} +