]> granicus.if.org Git - clang/commitdiff
implement correct semantic analysis for shifts. For:
authorChris Lattner <sabre@nondot.org>
Wed, 12 Dec 2007 05:47:28 +0000 (05:47 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 12 Dec 2007 05:47:28 +0000 (05:47 +0000)
int test(int x, long long y) {
  return x << y;
}

we now realize the type of the shift is int, not long long.

This fixes a fixme from june.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44912 91177308-0d34-0410-b5e6-96231b3b80d8

Sema/Sema.h
Sema/SemaExpr.cpp

index d52d49b75c65c8480bac9e4717b9f4b49d49a6d4..e78bf308f70541fa4c07edc21c91a258e7d23284 100644 (file)
@@ -631,7 +631,7 @@ private:
   /// or a null QualType (indicating an error diagnostic was issued).
     
   /// type checking binary operators (subroutines of ActOnBinOp).
-  inline void InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
+  inline QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
   inline QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
   inline QualType CheckMultiplyDivideOperands( // C99 6.5.5
     Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false); 
index 0f5fe8ad0f26ae8120f5eb9115e38129d877d4fb..444ea1c78ce93c71dc2c96f7032f982183acaffd 100644 (file)
@@ -1176,10 +1176,11 @@ Sema::CheckCompoundAssignmentConstraints(QualType lhsType, QualType rhsType) {
   return CheckAssignmentConstraints(lhsType, rhsType);
 }
 
-inline void Sema::InvalidOperands(SourceLocation loc, Expr *&lex, Expr *&rex) {
+QualType Sema::InvalidOperands(SourceLocation loc, Expr *&lex, Expr *&rex) {
   Diag(loc, diag::err_typecheck_invalid_operands, 
        lex->getType().getAsString(), rex->getType().getAsString(),
        lex->getSourceRange(), rex->getSourceRange());
+  return QualType();
 }
 
 inline QualType Sema::CheckVectorOperands(SourceLocation loc, Expr *&lex, 
@@ -1208,8 +1209,7 @@ inline QualType Sema::CheckMultiplyDivideOperands(
   
   if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
     return compType;
-  InvalidOperands(loc, lex, rex);
-  return QualType();
+  return InvalidOperands(loc, lex, rex);
 }
 
 inline QualType Sema::CheckRemainderOperands(
@@ -1221,8 +1221,7 @@ inline QualType Sema::CheckRemainderOperands(
   
   if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
     return compType;
-  InvalidOperands(loc, lex, rex);
-  return QualType();
+  return InvalidOperands(loc, lex, rex);
 }
 
 inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
@@ -1241,8 +1240,7 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
     return lex->getType();
   if (lex->getType()->isIntegerType() && rex->getType()->isPointerType())
     return rex->getType();
-  InvalidOperands(loc, lex, rex);
-  return QualType();
+  return InvalidOperands(loc, lex, rex);
 }
 
 inline QualType Sema::CheckSubtractionOperands( // C99 6.5.6
@@ -1307,22 +1305,22 @@ inline QualType Sema::CheckSubtractionOperands( // C99 6.5.6
     }
   }
   
-  InvalidOperands(loc, lex, rex);
-  return QualType();
+  return InvalidOperands(loc, lex, rex);
 }
 
 inline QualType Sema::CheckShiftOperands( // C99 6.5.7
-  Expr *&lex, Expr *&rex, SourceLocation loc, bool isCompAssign)
-{
-  // FIXME: Shifts don't perform usual arithmetic conversions.  This is wrong
-  // for int << longlong -> the result type should be int, not long long.
-  QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
+  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())
+    return InvalidOperands(loc, lex, rex);
   
-  // handle the common case first (both operands are arithmetic).
-  if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
-    return compType;
-  InvalidOperands(loc, lex, rex);
-  return QualType();
+  // Shifts don't perform usual arithmetic conversions, they just do integer
+  // promotions on each operand. C99 6.5.7p3
+  UsualUnaryConversions(lex);
+  UsualUnaryConversions(rex);
+  
+  // "The type of the result is that of the promoted left operand."
+  return lex->getType();
 }
 
 inline QualType Sema::CheckCompareOperands( // C99 6.5.8
@@ -1398,8 +1396,7 @@ inline QualType Sema::CheckCompareOperands( // C99 6.5.8
     promoteExprToType(lex, rType); // promote the integer to pointer
     return Context.IntTy;
   }
-  InvalidOperands(loc, lex, rex);
-  return QualType();
+  return InvalidOperands(loc, lex, rex);
 }
 
 inline QualType Sema::CheckBitwiseOperands(
@@ -1412,8 +1409,7 @@ inline QualType Sema::CheckBitwiseOperands(
   
   if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
     return compType;
-  InvalidOperands(loc, lex, rex);
-  return QualType();
+  return InvalidOperands(loc, lex, rex);
 }
 
 inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14]
@@ -1424,8 +1420,7 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14]
   
   if (lex->getType()->isScalarType() || rex->getType()->isScalarType())
     return Context.IntTy;
-  InvalidOperands(loc, lex, rex);
-  return QualType();
+  return InvalidOperands(loc, lex, rex);
 }
 
 inline QualType Sema::CheckAssignmentOperands( // C99 6.5.16.1