[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