Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h	(revision 79176)
+++ include/clang/AST/ASTContext.h	(working copy)
@@ -808,6 +808,11 @@
   /// See C99 6.7.5.3p7 and C99 6.3.2.1p3.
   QualType getArrayDecayedType(QualType T);
   
+  /// getPromotedIntegerType - Returns the type that Promotable will
+  /// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable
+  /// integer type.
+  QualType getPromotedIntegerType(QualType PromotableType);
+
   /// getIntegerTypeOrder - Returns the highest ranked integer type: 
   /// C99 6.3.1.8p1.  If LHS > RHS, return 1.  If LHS == RHS, return 0. If
   /// LHS < RHS, return -1. 
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp	(revision 79176)
+++ lib/Sema/SemaType.cpp	(working copy)
@@ -1064,7 +1064,7 @@
             }
           } else if (!FTI.hasPrototype) {
             if (ArgTy->isPromotableIntegerType()) {
-              ArgTy = Context.IntTy;
+              ArgTy = Context.getPromotedIntegerType(ArgTy);
             } else if (const BuiltinType* BTy = ArgTy->getAsBuiltinType()) {
               if (BTy->getKind() == BuiltinType::Float)
                 ArgTy = Context.DoubleTy;
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 79176)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -272,7 +272,8 @@
   //   unsigned int. These are called the integer promotions. All
   //   other types are unchanged by the integer promotions.
   if (Ty->isPromotableIntegerType()) {
-    ImpCastExprToType(Expr, Context.IntTy);
+    QualType PT = Context.getPromotedIntegerType(Ty);
+    ImpCastExprToType(Expr, PT);
     return Expr;
   } else {
     QualType T = isPromotableBitField(Expr, Context);
@@ -374,11 +375,11 @@
   // qualifiers.  For example, "const float" and "float" are
   // equivalent.
   if (lhs->isPromotableIntegerType())
-    lhs = Context.IntTy;
+    lhs = Context.getPromotedIntegerType(lhs);
   else
     lhs = lhs.getUnqualifiedType();
   if (rhs->isPromotableIntegerType())
-    rhs = Context.IntTy;
+    rhs = Context.getPromotedIntegerType(rhs);
   else
     rhs = rhs.getUnqualifiedType();
 
@@ -4041,7 +4042,7 @@
       if (CompLHSTy) {
         QualType LHSTy = lex->getType();
         if (LHSTy->isPromotableIntegerType())
-          LHSTy = Context.IntTy;
+          LHSTy = Context.getPromotedIntegerType(LHSTy);
         else {
           QualType T = isPromotableBitField(lex, Context);
           if (!T.isNull())
@@ -4209,13 +4210,13 @@
 
   // Shifts don't perform usual arithmetic conversions, they just do integer
   // promotions on each operand. C99 6.5.7p3
-  QualType LHSTy;
-  if (lex->getType()->isPromotableIntegerType())
-    LHSTy = Context.IntTy;
+  QualType LHSTy = lex->getType();
+  if (LHSTy->isPromotableIntegerType())
+    LHSTy = Context.getPromotedIntegerType(LHSTy);
   else {
-    LHSTy = isPromotableBitField(lex, Context);
-    if (LHSTy.isNull())
-      LHSTy = lex->getType();
+    QualType T = isPromotableBitField(lex, Context);
+    if (!T.isNull())
+      LHSTy = T;
   }
   if (!isCompAssign)
     ImpCastExprToType(lex, LHSTy);
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp	(revision 79176)
+++ lib/AST/ASTContext.cpp	(working copy)
@@ -2468,6 +2468,20 @@
   }
 }
 
+/// getPromotedIntegerType - Returns the type that Promotable will
+/// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable
+/// integer type.
+QualType ASTContext::getPromotedIntegerType(QualType Promotable) {
+  assert(!Promotable.isNull());
+  assert(Promotable->isPromotableIntegerType());
+  if (Promotable->isSignedIntegerType())
+    return IntTy;
+  uint64_t PromotableSize = getTypeSize(Promotable);
+  uint64_t IntSize = getTypeSize(IntTy);
+  assert(Promotable->isUnsignedIntegerType() && PromotableSize <= IntSize);
+  return (PromotableSize != IntSize) ? IntTy : UnsignedIntTy;
+}
+
 /// getIntegerTypeOrder - Returns the highest ranked integer type: 
 /// C99 6.3.1.8p1.  If LHS > RHS, return 1.  If LHS == RHS, return 0. If
 /// LHS < RHS, return -1. 
