[cfe-commits] r109229 - in /cfe/trunk: include/clang/AST/CanonicalType.h include/clang/AST/Type.h lib/AST/ASTContext.cpp lib/AST/Type.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/SemaChecking.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/SemaType.cpp test/Sema/vector-ops.c

Douglas Gregor dgregor at apple.com
Fri Jul 23 08:58:25 PDT 2010


Author: dgregor
Date: Fri Jul 23 10:58:24 2010
New Revision: 109229

URL: http://llvm.org/viewvc/llvm-project?rev=109229&view=rev
Log:
Vectors are not integer types, so the type system should not classify
them as such. Type::is(Signed|Unsigned|)IntegerType() now return false
for vector types, and new functions
has(Signed|Unsigned|)IntegerRepresentation() cover integer types and
vector-of-integer types. This fixes a bunch of latent bugs.

Patch from Anton Yartsev!

Added:
    cfe/trunk/test/Sema/vector-ops.c   (with props)
Modified:
    cfe/trunk/include/clang/AST/CanonicalType.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/AST/CanonicalType.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CanonicalType.h?rev=109229&r1=109228&r2=109229&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/CanonicalType.h (original)
+++ cfe/trunk/include/clang/AST/CanonicalType.h Fri Jul 23 10:58:24 2010
@@ -273,6 +273,9 @@
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=109229&r1=109228&r2=109229&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Fri Jul 23 10:58:24 2010
@@ -952,10 +952,22 @@
   /// an objective pointer type for the purpose of GC'ability
   bool hasObjCPointerRepresentation() const;
 
+  /// \brief Determine whether this type has an integer representation
+  /// of some sort, e.g., it is an integer type or a vector.
+  bool hasIntegerRepresentation() const;
+
+  /// \brief Determine whether this type has an signed integer representation
+  /// of some sort, e.g., it is an signed integer type or a vector.
+  bool hasSignedIntegerRepresentation() const;
+
+  /// \brief Determine whether this type has an unsigned integer representation
+  /// of some sort, e.g., it is an unsigned integer type or a vector.
+  bool hasUnsignedIntegerRepresentation() const;
+
   /// \brief Determine whether this type has a floating-point representation
   /// of some sort, e.g., it is a floating-point type or a vector thereof.
   bool hasFloatingRepresentation() const;
-  
+
   // Type Checking Functions: Check to see if this type is structurally the
   // specified type, ignoring typedefs and qualifiers, and return a pointer to
   // the best type we can.

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=109229&r1=109228&r2=109229&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Jul 23 10:58:24 2010
@@ -5031,7 +5031,7 @@
 }
 
 QualType ASTContext::getCorrespondingUnsignedType(QualType T) {
-  assert(T->isSignedIntegerType() && "Unexpected type");
+  assert(T->hasSignedIntegerRepresentation() && "Unexpected type");
   
   // Turn <4 x signed int> -> <4 x unsigned int>
   if (const VectorType *VTy = T->getAs<VectorType>())
@@ -5411,8 +5411,8 @@
   // Finally, we have two differing integer types.
   // The rules for this case are in C99 6.3.1.8
   int compare = getIntegerTypeOrder(lhs, rhs);
-  bool lhsSigned = lhs->isSignedIntegerType(),
-       rhsSigned = rhs->isSignedIntegerType();
+  bool lhsSigned = lhs->hasSignedIntegerRepresentation(),
+       rhsSigned = rhs->hasSignedIntegerRepresentation();
   QualType destType;
   if (lhsSigned == rhsSigned) {
     // Same signedness; use the higher-ranked type

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=109229&r1=109228&r2=109229&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Fri Jul 23 10:58:24 2010
@@ -434,9 +434,14 @@
     // FIXME: In C++, enum types are never integer types.
     if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
       return true;
+  return false;
+}
+
+bool Type::hasIntegerRepresentation() const {
   if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
     return VT->getElementType()->isIntegerType();
-  return false;
+  else
+    return isIntegerType();
 }
 
 /// \brief Determine whether this type is an integral type.
@@ -523,8 +528,7 @@
 
 /// isSignedIntegerType - Return true if this is an integer type that is
 /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
-/// an enum decl which has a signed representation, or a vector of signed
-/// integer element type.
+/// an enum decl which has a signed representation
 bool Type::isSignedIntegerType() const {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
     return BT->getKind() >= BuiltinType::Char_S &&
@@ -534,15 +538,19 @@
   if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
     return ET->getDecl()->getIntegerType()->isSignedIntegerType();
 
+  return false;
+}
+
+bool Type::hasSignedIntegerRepresentation() const {
   if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
     return VT->getElementType()->isSignedIntegerType();
-  return false;
+  else
+    return isSignedIntegerType();
 }
 
 /// isUnsignedIntegerType - Return true if this is an integer type that is
 /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
-/// decl which has an unsigned representation, or a vector of unsigned integer
-/// element type.
+/// decl which has an unsigned representation
 bool Type::isUnsignedIntegerType() const {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
     return BT->getKind() >= BuiltinType::Bool &&
@@ -552,9 +560,14 @@
   if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
     return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
 
+  return false;
+}
+
+bool Type::hasUnsignedIntegerRepresentation() const {
   if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
     return VT->getElementType()->isUnsignedIntegerType();
-  return false;
+  else
+    return isUnsignedIntegerType();
 }
 
 bool Type::isFloatingType() const {

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=109229&r1=109228&r2=109229&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Fri Jul 23 10:58:24 2010
@@ -730,9 +730,9 @@
   const ABIArgInfo &RetAI = FI.getReturnInfo();
   switch (RetAI.getKind()) {
   case ABIArgInfo::Extend:
-   if (RetTy->isSignedIntegerType()) {
+   if (RetTy->hasSignedIntegerRepresentation()) {
      RetAttrs |= llvm::Attribute::SExt;
-   } else if (RetTy->isUnsignedIntegerType()) {
+   } else if (RetTy->hasUnsignedIntegerRepresentation()) {
      RetAttrs |= llvm::Attribute::ZExt;
    }
    // FALLTHROUGH

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=109229&r1=109228&r2=109229&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Fri Jul 23 10:58:24 2010
@@ -297,7 +297,7 @@
 
   // Binary Operators.
   Value *EmitMul(const BinOpInfo &Ops) {
-    if (Ops.Ty->isSignedIntegerType()) {
+    if (Ops.Ty->hasSignedIntegerRepresentation()) {
       switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
       case LangOptions::SOB_Undefined:
         return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
@@ -1422,7 +1422,7 @@
 Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
   if (Ops.LHS->getType()->isFPOrFPVectorTy())
     return Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
-  else if (Ops.Ty->isUnsignedIntegerType())
+  else if (Ops.Ty->hasUnsignedIntegerRepresentation())
     return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
   else
     return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div");
@@ -1523,7 +1523,7 @@
 
 Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) {
   if (!Ops.Ty->isAnyPointerType()) {
-    if (Ops.Ty->isSignedIntegerType()) {
+    if (Ops.Ty->hasSignedIntegerRepresentation()) {
       switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
       case LangOptions::SOB_Undefined:
         return Builder.CreateNSWAdd(Ops.LHS, Ops.RHS, "add");
@@ -1606,7 +1606,7 @@
 
 Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
   if (!isa<llvm::PointerType>(Ops.LHS->getType())) {
-    if (Ops.Ty->isSignedIntegerType()) {
+    if (Ops.Ty->hasSignedIntegerRepresentation()) {
       switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
       case LangOptions::SOB_Undefined:
         return Builder.CreateNSWSub(Ops.LHS, Ops.RHS, "sub");
@@ -1747,7 +1747,7 @@
     CGF.EmitBlock(Cont);
   }
 
-  if (Ops.Ty->isUnsignedIntegerType())
+  if (Ops.Ty->hasUnsignedIntegerRepresentation())
     return Builder.CreateLShr(Ops.LHS, RHS, "shr");
   return Builder.CreateAShr(Ops.LHS, RHS, "shr");
 }
@@ -1791,7 +1791,7 @@
     if (LHS->getType()->isFPOrFPVectorTy()) {
       Result = Builder.CreateFCmp((llvm::CmpInst::Predicate)FCmpOpc,
                                   LHS, RHS, "cmp");
-    } else if (LHSTy->isSignedIntegerType()) {
+    } else if (LHSTy->hasSignedIntegerRepresentation()) {
       Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)SICmpOpc,
                                   LHS, RHS, "cmp");
     } else {

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=109229&r1=109228&r2=109229&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Jul 23 10:58:24 2010
@@ -780,7 +780,7 @@
     // with mask.  If so, verify that RHS is an integer vector type with the
     // same number of elts as lhs.
     if (TheCall->getNumArgs() == 2) {
-      if (!RHSType->isIntegerType() || 
+      if (!RHSType->hasIntegerRepresentation() || 
           RHSType->getAs<VectorType>()->getNumElements() != numElements)
         Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector)
           << SourceRange(TheCall->getArg(1)->getLocStart(),
@@ -2453,7 +2453,7 @@
   // We don't do anything special if this isn't an unsigned integral
   // comparison:  we're only interested in integral comparisons, and
   // signed comparisons only happen in cases we don't care to warn about.
-  if (!T->isUnsignedIntegerType())
+  if (!T->hasUnsignedIntegerRepresentation())
     return AnalyzeImpConvsInComparison(S, E);
 
   Expr *lex = E->getLHS()->IgnoreParenImpCasts();
@@ -2462,12 +2462,12 @@
   // Check to see if one of the (unmodified) operands is of different
   // signedness.
   Expr *signedOperand, *unsignedOperand;
-  if (lex->getType()->isSignedIntegerType()) {
-    assert(!rex->getType()->isSignedIntegerType() &&
+  if (lex->getType()->hasSignedIntegerRepresentation()) {
+    assert(!rex->getType()->hasSignedIntegerRepresentation() &&
            "unsigned comparison between two signed integer expressions?");
     signedOperand = lex;
     unsignedOperand = rex;
-  } else if (rex->getType()->isSignedIntegerType()) {
+  } else if (rex->getType()->hasSignedIntegerRepresentation()) {
     signedOperand = rex;
     unsignedOperand = lex;
   } else {

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=109229&r1=109228&r2=109229&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jul 23 10:58:24 2010
@@ -2362,8 +2362,7 @@
        << LHSExp->getSourceRange() << RHSExp->getSourceRange());
   }
   // C99 6.5.2.1p1
-  if (!(IndexExpr->getType()->isIntegerType() &&
-        IndexExpr->getType()->isScalarType()) && !IndexExpr->isTypeDependent())
+  if (!IndexExpr->getType()->isIntegerType() && !IndexExpr->isTypeDependent())
     return ExprError(Diag(LLoc, diag::err_typecheck_subscript_not_integer)
                      << IndexExpr->getSourceRange());
 
@@ -4576,12 +4575,12 @@
     // "unsigned char" on systems where "char" is unsigned.
     if (lhptee->isCharType())
       lhptee = Context.UnsignedCharTy;
-    else if (lhptee->isSignedIntegerType())
+    else if (lhptee->hasSignedIntegerRepresentation())
       lhptee = Context.getCorrespondingUnsignedType(lhptee);
 
     if (rhptee->isCharType())
       rhptee = Context.UnsignedCharTy;
-    else if (rhptee->isSignedIntegerType())
+    else if (rhptee->hasSignedIntegerRepresentation())
       rhptee = Context.getCorrespondingUnsignedType(rhptee);
 
     if (lhptee == rhptee) {
@@ -5078,7 +5077,8 @@
 QualType Sema::CheckRemainderOperands(
   Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
   if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
-    if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
+    if (lex->getType()->hasIntegerRepresentation() && 
+        rex->getType()->hasIntegerRepresentation())
       return CheckVectorOperands(Loc, lex, rex);
     return InvalidOperands(Loc, lex, rex);
   }
@@ -5323,7 +5323,8 @@
 QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
                                   bool isCompAssign) {
   // C99 6.5.7p2: Each of the operands shall have integer type.
-  if (!lex->getType()->isIntegerType() || !rex->getType()->isIntegerType())
+  if (!lex->getType()->hasIntegerRepresentation() || 
+      !rex->getType()->hasIntegerRepresentation())
     return InvalidOperands(Loc, lex, rex);
 
   // Vector shifts promote their scalar inputs to vector type.
@@ -5777,7 +5778,7 @@
   // Return the type for the comparison, which is the same as vector type for
   // integer vectors, or an integer type of identical size and number of
   // elements for floating point vectors.
-  if (lType->isIntegerType())
+  if (lType->hasIntegerRepresentation())
     return lType;
 
   const VectorType *VTy = lType->getAs<VectorType>();
@@ -5794,8 +5795,13 @@
 
 inline QualType Sema::CheckBitwiseOperands(
   Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
-  if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
-    return CheckVectorOperands(Loc, lex, rex);
+  if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
+    if (lex->getType()->hasIntegerRepresentation() &&
+        rex->getType()->hasIntegerRepresentation())
+      return CheckVectorOperands(Loc, lex, rex);
+    
+    return InvalidOperands(Loc, lex, rex);
+  }
 
   QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
 
@@ -6702,7 +6708,7 @@
       // C99 does not support '~' for complex conjugation.
       Diag(OpLoc, diag::ext_integer_complement_complex)
         << resultType << Input->getSourceRange();
-    else if (!resultType->isIntegerType())
+    else if (!resultType->hasIntegerRepresentation())
       return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
         << resultType << Input->getSourceRange());
     break;

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=109229&r1=109228&r2=109229&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Fri Jul 23 10:58:24 2010
@@ -967,9 +967,8 @@
         if (Method && DiagnoseUseOfDecl(Method, Loc))
           return ExprError();
       } else if (!Context.getObjCIdType().isNull() &&
-                 (ReceiverType->isPointerType() ||
-                  (ReceiverType->isIntegerType() &&
-                   ReceiverType->isScalarType()))) {
+                 (ReceiverType->isPointerType() || 
+                  ReceiverType->isIntegerType())) {
         // Implicitly convert integers and pointers to 'id' but emit a warning.
         Diag(Loc, diag::warn_bad_receiver_type)
           << ReceiverType 

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=109229&r1=109228&r2=109229&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Jul 23 10:58:24 2010
@@ -1944,8 +1944,7 @@
     return;
   }
   // the base type must be integer or float, and can't already be a vector.
-  if (CurType->isVectorType() ||
-      (!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
+  if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
     Attr.setInvalid();
     return;

Added: cfe/trunk/test/Sema/vector-ops.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-ops.c?rev=109229&view=auto
==============================================================================
--- cfe/trunk/test/Sema/vector-ops.c (added)
+++ cfe/trunk/test/Sema/vector-ops.c Fri Jul 23 10:58:24 2010
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wvector-conversions
+typedef unsigned int v2u __attribute__ ((vector_size (8)));
+typedef int v2s __attribute__ ((vector_size (8)));
+typedef float v2f __attribute__ ((vector_size(8)));
+
+void test1(v2u v2ua, v2s v2sa, v2f v2fa) {
+  // Bitwise binary operators
+  (void)(v2ua & v2ua);
+  (void)(v2fa & v2fa); // expected-error{{invalid operands to binary expression}}
+
+  // Unary operators
+  (void)(~v2ua);
+  (void)(~v2fa); // expected-error{{invalid argument type 'v2f' to unary}}
+
+  // Arrays
+  int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u'}}
+  int array2[17];
+  // FIXME: error message below needs type!
+  (void)(array2[v2ua]); // expected-error{{array subscript is not an integer}}
+
+  v2u *v2u_ptr = 0;
+  v2s *v2s_ptr;
+  v2s_ptr = v2u_ptr; // expected-warning{{converts between pointers to integer types with different sign}}
+}
+ 

Propchange: cfe/trunk/test/Sema/vector-ops.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/Sema/vector-ops.c
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/Sema/vector-ops.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list