From: Chris Lattner Date: Sat, 17 Oct 2009 20:33:28 +0000 (+0000) Subject: teach getCorrespondingUnsignedType how to handle vectors of integers, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6a2b9261bf9c973c7122d9d1febce24a38fa862d;p=clang teach getCorrespondingUnsignedType how to handle vectors of integers, fixing PR4838. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84353 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 507baeab27..1b77bbe1db 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -3930,7 +3930,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) { unsigned ASTContext::getIntWidth(QualType T) { if (T == BoolTy) return 1; - if (FixedWidthIntType* FWIT = dyn_cast(T)) { + if (FixedWidthIntType *FWIT = dyn_cast(T)) { return FWIT->getWidth(); } // For builtin types, just use the standard type sizing method @@ -3939,10 +3939,18 @@ unsigned ASTContext::getIntWidth(QualType T) { QualType ASTContext::getCorrespondingUnsignedType(QualType T) { assert(T->isSignedIntegerType() && "Unexpected type"); - if (const EnumType* ETy = T->getAs()) + + // Turn <4 x signed int> -> <4 x unsigned int> + if (const VectorType *VTy = T->getAs()) + return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()), + VTy->getNumElements()); + + // For enums, we return the unsigned version of the base type. + if (const EnumType *ETy = T->getAs()) T = ETy->getDecl()->getIntegerType(); - const BuiltinType* BTy = T->getAs(); - assert (BTy && "Unexpected signed integer type"); + + const BuiltinType *BTy = T->getAs(); + assert(BTy && "Unexpected signed integer type"); switch (BTy->getKind()) { case BuiltinType::Char_S: case BuiltinType::SChar: diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 67058860d6..b69e1fbcd6 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3753,16 +3753,16 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) { // Check if the pointee types are compatible ignoring the sign. // We explicitly check for char so that we catch "char" vs // "unsigned char" on systems where "char" is unsigned. - if (lhptee->isCharType()) { + if (lhptee->isCharType()) lhptee = Context.UnsignedCharTy; - } else if (lhptee->isSignedIntegerType()) { + else if (lhptee->isSignedIntegerType()) lhptee = Context.getCorrespondingUnsignedType(lhptee); - } - if (rhptee->isCharType()) { + + if (rhptee->isCharType()) rhptee = Context.UnsignedCharTy; - } else if (rhptee->isSignedIntegerType()) { + else if (rhptee->isSignedIntegerType()) rhptee = Context.getCorrespondingUnsignedType(rhptee); - } + if (lhptee == rhptee) { // Types are compatible ignoring the sign. Qualifier incompatibility // takes priority over sign incompatibility because the sign diff --git a/test/Sema/vector-assign.c b/test/Sema/vector-assign.c index 5162e1a41c..bf9c7f37ca 100644 --- a/test/Sema/vector-assign.c +++ b/test/Sema/vector-assign.c @@ -5,7 +5,7 @@ typedef signed int v1s __attribute__ ((vector_size (4))); typedef float v2f __attribute__ ((vector_size(8))); typedef signed short v4ss __attribute__ ((vector_size (8))); -void f() { +void test1() { v2s v1; v2u v2; v1s v3; @@ -39,7 +39,15 @@ void f() { } // PR2263 -float f2(__attribute__((vector_size(16))) float a, int b) { +float test2(__attribute__((vector_size(16))) float a, int b) { return a[b]; } +// PR4838 +typedef long long __attribute__((__vector_size__(2 * sizeof(long long)))) +longlongvec; + +void test3a(longlongvec *); +void test3(const unsigned *src) { + test3a(src); // expected-warning {{incompatible pointer types passing 'unsigned int const *', expected 'longlongvec *'}} +}