aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp65
1 files changed, 29 insertions, 36 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index a8e7348d41..adc1331a9f 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4372,7 +4372,7 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, ExprR
// Now check the two expressions.
if (LHSTy->isVectorType() || RHSTy->isVectorType())
- return CheckVectorOperands(QuestionLoc, LHS, RHS);
+ return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false);
// OpenCL: If the condition is a vector, and both operands are scalar,
// attempt to implicity convert them to the vector type to act like the
@@ -5470,7 +5470,8 @@ QualType Sema::InvalidOperands(SourceLocation Loc, ExprResult &lex, ExprResult &
return QualType();
}
-QualType Sema::CheckVectorOperands(SourceLocation Loc, ExprResult &lex, ExprResult &rex) {
+QualType Sema::CheckVectorOperands(ExprResult &lex, ExprResult &rex,
+ SourceLocation Loc, bool isCompAssign) {
// For conversion purposes, we ignore any qualifiers.
// For example, "const float" and "float" are equivalent.
QualType lhsType =
@@ -5482,42 +5483,33 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, ExprResult &lex, ExprResu
if (lhsType == rhsType)
return lhsType;
- // Handle the case of a vector & extvector type of the same size and element
- // type. It would be nice if we only had one vector type someday.
- if (getLangOptions().LaxVectorConversions) {
- if (const VectorType *LV = lhsType->getAs<VectorType>()) {
- if (const VectorType *RV = rhsType->getAs<VectorType>()) {
- if (LV->getElementType() == RV->getElementType() &&
- LV->getNumElements() == RV->getNumElements()) {
- if (lhsType->isExtVectorType()) {
- rex = ImpCastExprToType(rex.take(), lhsType, CK_BitCast);
- return lhsType;
- }
-
- lex = ImpCastExprToType(lex.take(), rhsType, CK_BitCast);
- return rhsType;
- } else if (Context.getTypeSize(lhsType) ==Context.getTypeSize(rhsType)){
- // If we are allowing lax vector conversions, and LHS and RHS are both
- // vectors, the total size only needs to be the same. This is a
- // bitcast; no bits are changed but the result type is different.
- rex = ImpCastExprToType(rex.take(), lhsType, CK_BitCast);
- return lhsType;
- }
- }
- }
- }
-
// Handle the case of equivalent AltiVec and GCC vector types
if (lhsType->isVectorType() && rhsType->isVectorType() &&
Context.areCompatibleVectorTypes(lhsType, rhsType)) {
- lex = ImpCastExprToType(lex.take(), rhsType, CK_BitCast);
+ if (lhsType->isExtVectorType()) {
+ rex = ImpCastExprToType(rex.take(), lhsType, CK_BitCast);
+ return lhsType;
+ }
+
+ if (!isCompAssign)
+ lex = ImpCastExprToType(lex.take(), rhsType, CK_BitCast);
return rhsType;
}
+ if (getLangOptions().LaxVectorConversions &&
+ Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType)) {
+ // If we are allowing lax vector conversions, and LHS and RHS are both
+ // vectors, the total size only needs to be the same. This is a
+ // bitcast; no bits are changed but the result type is different.
+ // FIXME: Should we really be allowing this?
+ rex = ImpCastExprToType(rex.take(), lhsType, CK_BitCast);
+ return lhsType;
+ }
+
// Canonicalize the ExtVector to the LHS, remember if we swapped so we can
// swap back (so that we don't reverse the inputs to a subtract, for instance.
bool swapped = false;
- if (rhsType->isExtVectorType()) {
+ if (rhsType->isExtVectorType() && !isCompAssign) {
swapped = true;
std::swap(rex, lex);
std::swap(rhsType, lhsType);
@@ -5550,6 +5542,7 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, ExprResult &lex, ExprResu
}
// Vectors of different size or scalar and non-ext-vector are errors.
+ if (swapped) std::swap(rex, lex);
Diag(Loc, diag::err_typecheck_vector_not_convertable)
<< lex.get()->getType() << rex.get()->getType()
<< lex.get()->getSourceRange() << rex.get()->getSourceRange();
@@ -5559,7 +5552,7 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, ExprResult &lex, ExprResu
QualType Sema::CheckMultiplyDivideOperands(
ExprResult &lex, ExprResult &rex, SourceLocation Loc, bool isCompAssign, bool isDiv) {
if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType())
- return CheckVectorOperands(Loc, lex, rex);
+ return CheckVectorOperands(lex, rex, Loc, isCompAssign);
QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
if (lex.isInvalid() || rex.isInvalid())
@@ -5583,7 +5576,7 @@ QualType Sema::CheckRemainderOperands(
if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType()) {
if (lex.get()->getType()->hasIntegerRepresentation() &&
rex.get()->getType()->hasIntegerRepresentation())
- return CheckVectorOperands(Loc, lex, rex);
+ return CheckVectorOperands(lex, rex, Loc, isCompAssign);
return InvalidOperands(Loc, lex, rex);
}
@@ -5605,7 +5598,7 @@ QualType Sema::CheckRemainderOperands(
QualType Sema::CheckAdditionOperands( // C99 6.5.6
ExprResult &lex, ExprResult &rex, SourceLocation Loc, QualType* CompLHSTy) {
if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType()) {
- QualType compType = CheckVectorOperands(Loc, lex, rex);
+ QualType compType = CheckVectorOperands(lex, rex, Loc, CompLHSTy);
if (CompLHSTy) *CompLHSTy = compType;
return compType;
}
@@ -5690,7 +5683,7 @@ QualType Sema::CheckAdditionOperands( // C99 6.5.6
QualType Sema::CheckSubtractionOperands(ExprResult &lex, ExprResult &rex,
SourceLocation Loc, QualType* CompLHSTy) {
if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType()) {
- QualType compType = CheckVectorOperands(Loc, lex, rex);
+ QualType compType = CheckVectorOperands(lex, rex, Loc, CompLHSTy);
if (CompLHSTy) *CompLHSTy = compType;
return compType;
}
@@ -5913,7 +5906,7 @@ QualType Sema::CheckShiftOperands(ExprResult &lex, ExprResult &rex, SourceLocati
// Vector shifts promote their scalar inputs to vector type.
if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType())
- return CheckVectorOperands(Loc, lex, rex);
+ return CheckVectorOperands(lex, rex, Loc, isCompAssign);
// Shifts don't perform usual arithmetic conversions, they just do integer
// promotions on each operand. C99 6.5.7p3
@@ -6382,7 +6375,7 @@ QualType Sema::CheckVectorCompareOperands(ExprResult &lex, ExprResult &rex,
bool isRelational) {
// Check to make sure we're operating on vectors of the same type and width,
// Allowing one side to be a scalar of element type.
- QualType vType = CheckVectorOperands(Loc, lex, rex);
+ QualType vType = CheckVectorOperands(lex, rex, Loc, /*isCompAssign*/false);
if (vType.isNull())
return vType;
@@ -6437,7 +6430,7 @@ inline QualType Sema::CheckBitwiseOperands(
if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType()) {
if (lex.get()->getType()->hasIntegerRepresentation() &&
rex.get()->getType()->hasIntegerRepresentation())
- return CheckVectorOperands(Loc, lex, rex);
+ return CheckVectorOperands(lex, rex, Loc, isCompAssign);
return InvalidOperands(Loc, lex, rex);
}