[cfe-commits] r52853 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/Type.h lib/AST/ASTContext.cpp lib/AST/Type.cpp lib/Sema/SemaExpr.cpp test/Sema/int-arith-convert.c

Eli Friedman eli.friedman at gmail.com
Fri Jun 27 23:23:08 PDT 2008


Author: efriedma
Date: Sat Jun 28 01:23:08 2008
New Revision: 52853

URL: http://llvm.org/viewvc/llvm-project?rev=52853&view=rev
Log:
Fix for PR2501; this patch makes usual arithmetic conversions for 
integers which have the same width and different signedness work 
correctly. (The testcase in PR2501 uses a comparison between long and 
unsigned int).


Added:
    cfe/trunk/test/Sema/int-arith-convert.c
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=52853&r1=52852&r2=52853&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Sat Jun 28 01:23:08 2008
@@ -371,6 +371,19 @@
   }
 
   //===--------------------------------------------------------------------===//
+  //                    Integer Predicates
+  //===--------------------------------------------------------------------===//
+
+  // The width of an integer, as defined in C99 6.2.6.2. This is the number
+  // of bits in an integer type excluding any padding bits.
+  unsigned getIntWidth(QualType T);
+
+  // Per C99 6.2.5p6, for every signed integer type, there is a corresponding
+  // unsigned integer type.  This method takes a signed type, and returns the
+  // corresponding unsigned integer type.
+  QualType getCorrespondingUnsignedType(QualType T);
+
+  //===--------------------------------------------------------------------===//
   //                    Serialization
   //===--------------------------------------------------------------------===//
 

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=52853&r1=52852&r2=52853&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sat Jun 28 01:23:08 2008
@@ -48,6 +48,7 @@
   class VariableArrayType;
   class IncompleteArrayType;
   class RecordType;
+  class EnumType;
   class ComplexType;
   class TagType;
   class TypedefType;
@@ -352,6 +353,7 @@
   const RecordType *getAsStructureType() const;
   const TypedefType *getAsTypedefType() const;
   const RecordType *getAsUnionType() const;
+  const EnumType *getAsEnumType() const;
   const VectorType *getAsVectorType() const; // GCC vector type.
   const ComplexType *getAsComplexType() const;
   const ComplexType *getAsComplexIntegerType() const; // GCC complex int type.

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=52853&r1=52852&r2=52853&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sat Jun 28 01:23:08 2008
@@ -1757,6 +1757,41 @@
 }
 
 //===----------------------------------------------------------------------===//
+//                         Integer Predicates
+//===----------------------------------------------------------------------===//
+unsigned ASTContext::getIntWidth(QualType T) {
+  if (T == BoolTy)
+    return 1;
+  // At the moment, only bool has padding bits
+  return (unsigned)getTypeSize(T);
+}
+
+QualType ASTContext::getCorrespondingUnsignedType(QualType T) {
+  assert(T->isSignedIntegerType() && "Unexpected type");
+  if (const EnumType* ETy = T->getAsEnumType())
+    T = ETy->getDecl()->getIntegerType();
+  const BuiltinType* BTy = T->getAsBuiltinType();
+  assert (BTy && "Unexpected signed integer type");
+  switch (BTy->getKind()) {
+  case BuiltinType::Char_S:
+  case BuiltinType::SChar:
+    return UnsignedCharTy;
+  case BuiltinType::Short:
+    return UnsignedShortTy;
+  case BuiltinType::Int:
+    return UnsignedIntTy;
+  case BuiltinType::Long:
+    return UnsignedLongTy;
+  case BuiltinType::LongLong:
+    return UnsignedLongLongTy;
+  default:
+    assert(0 && "Unexpected signed integer type");
+    return QualType();
+  }
+}
+
+
+//===----------------------------------------------------------------------===//
 //                         Serialization Support
 //===----------------------------------------------------------------------===//
 

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=52853&r1=52852&r2=52853&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Sat Jun 28 01:23:08 2008
@@ -390,6 +390,13 @@
   return 0;
 }
 
+const EnumType *Type::getAsEnumType() const {
+  // Check the canonicalized unqualified type directly; the more complex
+  // version is unnecessary because there isn't any typedef information
+  // to preserve.
+  return dyn_cast<EnumType>(CanonicalType.getUnqualifiedType());
+}
+
 const ComplexType *Type::getAsComplexType() const {
   // Are we directly a complex type?
   if (const ComplexType *CTy = dyn_cast<ComplexType>(this))

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=52853&r1=52852&r2=52853&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Jun 28 01:23:08 2008
@@ -1221,12 +1221,35 @@
     }
   }
   // Finally, we have two differing integer types.
-  if (Context.getIntegerTypeOrder(lhs, rhs) >= 0) { // convert the rhs
-    if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
-    return lhs;
+  // The rules for this case are in C99 6.3.1.8
+  int compare = Context.getIntegerTypeOrder(lhs, rhs);
+  bool lhsSigned = lhs->isSignedIntegerType(),
+       rhsSigned = rhs->isSignedIntegerType();
+  QualType destType;
+  if (lhsSigned == rhsSigned) {
+    // Same signedness; use the higher-ranked type
+    destType = compare >= 0 ? lhs : rhs;
+  } else if (compare != (lhsSigned ? 1 : -1)) {
+    // The unsigned type has greater than or equal rank to the
+    // signed type, so use the unsigned type
+    destType = lhsSigned ? rhs : lhs;
+  } else if (Context.getIntWidth(lhs) != Context.getIntWidth(rhs)) {
+    // The two types are different widths; if we are here, that
+    // means the signed type is larger than the unsigned type, so
+    // use the signed type.
+    destType = lhsSigned ? lhs : rhs;
+  } else {
+    // The signed type is higher-ranked than the unsigned type,
+    // but isn't actually any bigger (like unsigned int and long
+    // on most 32-bit systems).  Use the unsigned type corresponding
+    // to the signed type.
+    destType = Context.getCorrespondingUnsignedType(lhsSigned ? lhs : rhs);
+  }
+  if (!isCompAssign) {
+    ImpCastExprToType(lhsExpr, destType);
+    ImpCastExprToType(rhsExpr, destType);
   }
-  if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs); // convert the lhs
-  return rhs;
+  return destType;
 }
 
 // CheckPointerTypesForAssignment - This is a very tricky routine (despite

Added: cfe/trunk/test/Sema/int-arith-convert.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/int-arith-convert.c?rev=52853&view=auto

==============================================================================
--- cfe/trunk/test/Sema/int-arith-convert.c (added)
+++ cfe/trunk/test/Sema/int-arith-convert.c Sat Jun 28 01:23:08 2008
@@ -0,0 +1,12 @@
+// RUN: clang -fsyntax-only -verify %s
+
+// Check types are the same through redeclaration
+unsigned long x;
+__typeof(1u+1l) x;
+
+unsigned y;
+__typeof(1+1u) y;
+__typeof(1u+1) y;
+
+long long z;
+__typeof(1ll+1u) z;





More information about the cfe-commits mailing list