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 507baea..1b77bbe 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -3930,7 +3930,7 @@
 unsigned ASTContext::getIntWidth(QualType T) {
   if (T == BoolTy)
     return 1;
-  if (FixedWidthIntType* FWIT = dyn_cast<FixedWidthIntType>(T)) {
+  if (FixedWidthIntType *FWIT = dyn_cast<FixedWidthIntType>(T)) {
     return FWIT->getWidth();
   }
   // For builtin types, just use the standard type sizing method
@@ -3939,10 +3939,18 @@
 
 QualType ASTContext::getCorrespondingUnsignedType(QualType T) {
   assert(T->isSignedIntegerType() && "Unexpected type");
-  if (const EnumType* ETy = T->getAs<EnumType>())
+  
+  // Turn <4 x signed int> -> <4 x unsigned int>
+  if (const VectorType *VTy = T->getAs<VectorType>())
+    return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()),
+                         VTy->getNumElements());
+
+  // For enums, we return the unsigned version of the base type.
+  if (const EnumType *ETy = T->getAs<EnumType>())
     T = ETy->getDecl()->getIntegerType();
-  const BuiltinType* BTy = T->getAs<BuiltinType>();
-  assert (BTy && "Unexpected signed integer type");
+  
+  const BuiltinType *BTy = T->getAs<BuiltinType>();
+  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 6705886..b69e1fb 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3753,16 +3753,16 @@
     // 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 5162e1a..bf9c7f3 100644
--- a/test/Sema/vector-assign.c
+++ b/test/Sema/vector-assign.c
@@ -5,7 +5,7 @@
 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 @@
 }
 
 // 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 *'}}
+}