summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp113
1 files changed, 72 insertions, 41 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 8b646e9943f..0a77c21875f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -174,10 +174,10 @@ void Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
/// GCC.
QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
bool isCompAssign) {
- if (!isCompAssign) {
+ if (!isCompAssign)
UsualUnaryConversions(lhsExpr);
- UsualUnaryConversions(rhsExpr);
- }
+
+ UsualUnaryConversions(rhsExpr);
// For conversion purposes, we ignore any qualifiers.
// For example, "const float" and "float" are equivalent.
@@ -196,10 +196,9 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
return lhs;
QualType destType = UsualArithmeticConversionsType(lhs, rhs);
- if (!isCompAssign) {
+ if (!isCompAssign)
ImpCastExprToType(lhsExpr, destType);
- ImpCastExprToType(rhsExpr, destType);
- }
+ ImpCastExprToType(rhsExpr, destType);
return destType;
}
@@ -3147,16 +3146,22 @@ inline QualType Sema::CheckRemainderOperands(
}
inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
- Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign)
+ Expr *&lex, Expr *&rex, SourceLocation Loc, QualType* CompLHSTy)
{
- if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
- return CheckVectorOperands(Loc, lex, rex);
+ if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
+ QualType compType = CheckVectorOperands(Loc, lex, rex);
+ if (CompLHSTy) *CompLHSTy = compType;
+ return compType;
+ }
- QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
+ QualType compType = UsualArithmeticConversions(lex, rex, CompLHSTy);
// handle the common case first (both operands are arithmetic).
- if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
+ if (lex->getType()->isArithmeticType() &&
+ rex->getType()->isArithmeticType()) {
+ if (CompLHSTy) *CompLHSTy = compType;
return compType;
+ }
// Put any potential pointer into PExp
Expr* PExp = lex, *IExp = rex;
@@ -3193,6 +3198,12 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
lex->getType()))
return QualType();
+ if (CompLHSTy) {
+ QualType LHSTy = lex->getType();
+ if (LHSTy->isPromotableIntegerType())
+ LHSTy = Context.IntTy;
+ *CompLHSTy = LHSTy;
+ }
return PExp->getType();
}
}
@@ -3202,17 +3213,22 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
// C99 6.5.6
QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex,
- SourceLocation Loc, bool isCompAssign) {
- if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
- return CheckVectorOperands(Loc, lex, rex);
+ SourceLocation Loc, QualType* CompLHSTy) {
+ if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
+ QualType compType = CheckVectorOperands(Loc, lex, rex);
+ if (CompLHSTy) *CompLHSTy = compType;
+ return compType;
+ }
- QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
+ QualType compType = UsualArithmeticConversions(lex, rex, CompLHSTy);
// Enforce type constraints: C99 6.5.6p3.
// Handle the common case first (both operands are arithmetic).
- if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
+ if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType()) {
+ if (CompLHSTy) *CompLHSTy = compType;
return compType;
+ }
// Either ptr - int or ptr - ptr.
if (const PointerType *LHSPTy = lex->getType()->getAsPointerType()) {
@@ -3258,6 +3274,7 @@ QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex,
<< ComplainAboutFunc->getType()
<< ComplainAboutFunc->getSourceRange();
+ if (CompLHSTy) *CompLHSTy = lex->getType();
return lex->getType();
}
@@ -3310,7 +3327,8 @@ QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex,
Diag(Loc, diag::ext_gnu_ptr_func_arith)
<< ComplainAboutFunc->getType()
<< ComplainAboutFunc->getSourceRange();
-
+
+ if (CompLHSTy) *CompLHSTy = lex->getType();
return Context.getPointerDiffType();
}
}
@@ -3327,12 +3345,18 @@ QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
// 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;
+ else
+ LHSTy = lex->getType();
if (!isCompAssign)
- UsualUnaryConversions(lex);
+ ImpCastExprToType(lex, LHSTy);
+
UsualUnaryConversions(rex);
// "The type of the result is that of the promoted left operand."
- return lex->getType();
+ return LHSTy;
}
// C99 6.5.8
@@ -4049,9 +4073,11 @@ static inline UnaryOperator::Opcode ConvertTokenKindToUnaryOpcode(
Action::OwningExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
unsigned Op,
Expr *lhs, Expr *rhs) {
- QualType ResultTy; // Result type of the binary operator.
- QualType CompTy; // Computation type for compound assignments (e.g. '+=')
+ QualType ResultTy; // Result type of the binary operator.
BinaryOperator::Opcode Opc = (BinaryOperator::Opcode)Op;
+ // The following two variables are used for compound assignment operators
+ QualType CompLHSTy; // Type of LHS after promotions for computation
+ QualType CompResultTy; // Type of computation result
switch (Opc) {
case BinaryOperator::Assign:
@@ -4100,37 +4126,41 @@ Action::OwningExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
break;
case BinaryOperator::MulAssign:
case BinaryOperator::DivAssign:
- CompTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true);
- if (!CompTy.isNull())
- ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompTy);
+ CompResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true);
+ CompLHSTy = CompResultTy;
+ if (!CompResultTy.isNull())
+ ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
case BinaryOperator::RemAssign:
- CompTy = CheckRemainderOperands(lhs, rhs, OpLoc, true);
- if (!CompTy.isNull())
- ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompTy);
+ CompResultTy = CheckRemainderOperands(lhs, rhs, OpLoc, true);
+ CompLHSTy = CompResultTy;
+ if (!CompResultTy.isNull())
+ ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
case BinaryOperator::AddAssign:
- CompTy = CheckAdditionOperands(lhs, rhs, OpLoc, true);
- if (!CompTy.isNull())
- ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompTy);
+ CompResultTy = CheckAdditionOperands(lhs, rhs, OpLoc, &CompLHSTy);
+ if (!CompResultTy.isNull())
+ ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
case BinaryOperator::SubAssign:
- CompTy = CheckSubtractionOperands(lhs, rhs, OpLoc, true);
- if (!CompTy.isNull())
- ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompTy);
+ CompResultTy = CheckSubtractionOperands(lhs, rhs, OpLoc, &CompLHSTy);
+ if (!CompResultTy.isNull())
+ ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
case BinaryOperator::ShlAssign:
case BinaryOperator::ShrAssign:
- CompTy = CheckShiftOperands(lhs, rhs, OpLoc, true);
- if (!CompTy.isNull())
- ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompTy);
+ CompResultTy = CheckShiftOperands(lhs, rhs, OpLoc, true);
+ CompLHSTy = CompResultTy;
+ if (!CompResultTy.isNull())
+ ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
case BinaryOperator::AndAssign:
case BinaryOperator::XorAssign:
case BinaryOperator::OrAssign:
- CompTy = CheckBitwiseOperands(lhs, rhs, OpLoc, true);
- if (!CompTy.isNull())
- ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompTy);
+ CompResultTy = CheckBitwiseOperands(lhs, rhs, OpLoc, true);
+ CompLHSTy = CompResultTy;
+ if (!CompResultTy.isNull())
+ ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
case BinaryOperator::Comma:
ResultTy = CheckCommaOperands(lhs, rhs, OpLoc);
@@ -4138,11 +4168,12 @@ Action::OwningExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
}
if (ResultTy.isNull())
return ExprError();
- if (CompTy.isNull())
+ if (CompResultTy.isNull())
return Owned(new (Context) BinaryOperator(lhs, rhs, Opc, ResultTy, OpLoc));
else
return Owned(new (Context) CompoundAssignOperator(lhs, rhs, Opc, ResultTy,
- CompTy, OpLoc));
+ CompLHSTy, CompResultTy,
+ OpLoc));
}
// Binary Operators. 'Tok' is the token for the operator.
OpenPOWER on IntegriCloud