@@ -5970,19 +5970,18 @@ static bool ConvertForConditional(Sema &Self, ExprResult &E, QualType T) {
5970
5970
// extension.
5971
5971
static bool isValidVectorForConditionalCondition (ASTContext &Ctx,
5972
5972
QualType CondTy) {
5973
- if (!CondTy->isVectorType () || CondTy->isExtVectorType ())
5973
+ if (!CondTy->isVectorType () && ! CondTy->isExtVectorType ())
5974
5974
return false ;
5975
5975
const QualType EltTy =
5976
5976
cast<VectorType>(CondTy.getCanonicalType ())->getElementType ();
5977
-
5978
5977
assert (!EltTy->isBooleanType () && !EltTy->isEnumeralType () &&
5979
5978
" Vectors cant be boolean or enum types" );
5980
5979
return EltTy->isIntegralType (Ctx);
5981
5980
}
5982
5981
5983
- QualType Sema::CheckGNUVectorConditionalTypes (ExprResult &Cond, ExprResult &LHS,
5984
- ExprResult &RHS,
5985
- SourceLocation QuestionLoc) {
5982
+ QualType Sema::CheckVectorConditionalTypes (ExprResult &Cond, ExprResult &LHS,
5983
+ ExprResult &RHS,
5984
+ SourceLocation QuestionLoc) {
5986
5985
LHS = DefaultFunctionArrayLvalueConversion (LHS.get ());
5987
5986
RHS = DefaultFunctionArrayLvalueConversion (RHS.get ());
5988
5987
@@ -5997,24 +5996,17 @@ QualType Sema::CheckGNUVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
5997
5996
5998
5997
QualType ResultType;
5999
5998
6000
- // FIXME: In the future we should define what the Extvector conditional
6001
- // operator looks like.
6002
- if (LHSVT && isa<ExtVectorType>(LHSVT)) {
6003
- Diag (QuestionLoc, diag::err_conditional_vector_operand_type)
6004
- << /* isExtVector*/ true << LHSType;
6005
- return {};
6006
- }
6007
-
6008
- if (RHSVT && isa<ExtVectorType>(RHSVT)) {
6009
- Diag (QuestionLoc, diag::err_conditional_vector_operand_type)
6010
- << /* isExtVector*/ true << RHSType;
6011
- return {};
6012
- }
6013
5999
6014
6000
if (LHSVT && RHSVT) {
6001
+ if (isa<ExtVectorType>(CondVT) != isa<ExtVectorType>(LHSVT)) {
6002
+ Diag (QuestionLoc, diag::err_conditional_vector_cond_result_mismatch)
6003
+ << /* isExtVector*/ isa<ExtVectorType>(CondVT);
6004
+ return {};
6005
+ }
6006
+
6015
6007
// If both are vector types, they must be the same type.
6016
6008
if (!Context.hasSameType (LHSType, RHSType)) {
6017
- Diag (QuestionLoc, diag::err_conditional_vector_mismatched_vectors )
6009
+ Diag (QuestionLoc, diag::err_conditional_vector_mismatched )
6018
6010
<< LHSType << RHSType;
6019
6011
return {};
6020
6012
}
@@ -6039,18 +6031,22 @@ QualType Sema::CheckGNUVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
6039
6031
6040
6032
if (ResultElementTy->isEnumeralType ()) {
6041
6033
Diag (QuestionLoc, diag::err_conditional_vector_operand_type)
6042
- << /* isExtVector */ false << ResultElementTy;
6034
+ << ResultElementTy;
6043
6035
return {};
6044
6036
}
6045
- ResultType = Context.getVectorType (
6046
- ResultElementTy, CondType->castAs <VectorType>()->getNumElements (),
6047
- VectorType::GenericVector);
6037
+ if (CondType->isExtVectorType ())
6038
+ ResultType =
6039
+ Context.getExtVectorType (ResultElementTy, CondVT->getNumElements ());
6040
+ else
6041
+ ResultType = Context.getVectorType (
6042
+ ResultElementTy, CondVT->getNumElements (), VectorType::GenericVector);
6048
6043
6049
6044
LHS = ImpCastExprToType (LHS.get (), ResultType, CK_VectorSplat);
6050
6045
RHS = ImpCastExprToType (RHS.get (), ResultType, CK_VectorSplat);
6051
6046
}
6052
6047
6053
6048
assert (!ResultType.isNull () && ResultType->isVectorType () &&
6049
+ (!CondType->isExtVectorType () || ResultType->isExtVectorType ()) &&
6054
6050
" Result should have been a vector type" );
6055
6051
auto *ResultVectorTy = ResultType->castAs <VectorType>();
6056
6052
QualType ResultElementTy = ResultVectorTy->getElementType ();
@@ -6077,15 +6073,21 @@ QualType Sema::CheckGNUVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
6077
6073
// / See C++ [expr.cond]. Note that LHS is never null, even for the GNU x ?: y
6078
6074
// / extension. In this case, LHS == Cond. (But they're not aliases.)
6079
6075
// /
6080
- // / This function also implements GCC's vector extension for conditionals.
6081
- // / GCC's vector extension permits the use of a?b:c where the type of
6082
- // / a is that of a integer vector with the same number of elements and
6083
- // / size as the vectors of b and c. If one of either b or c is a scalar
6084
- // / it is implicitly converted to match the type of the vector.
6085
- // / Otherwise the expression is ill-formed. If both b and c are scalars,
6086
- // / then b and c are checked and converted to the type of a if possible.
6087
- // / Unlike the OpenCL ?: operator, the expression is evaluated as
6088
- // / (a[0] != 0 ? b[0] : c[0], .. , a[n] != 0 ? b[n] : c[n]).
6076
+ // / This function also implements GCC's vector extension and the
6077
+ // / OpenCL/ext_vector_type extension for conditionals. The vector extensions
6078
+ // / permit the use of a?b:c where the type of a is that of a integer vector with
6079
+ // / the same number of elements and size as the vectors of b and c. If one of
6080
+ // / either b or c is a scalar it is implicitly converted to match the type of
6081
+ // / the vector. Otherwise the expression is ill-formed. If both b and c are
6082
+ // / scalars, then b and c are checked and converted to the type of a if
6083
+ // / possible.
6084
+ // /
6085
+ // / The expressions are evaluated differently for GCC's and OpenCL's extensions.
6086
+ // / For the GCC extension, the ?: operator is evaluated as
6087
+ // / (a[0] != 0 ? b[0] : c[0], .. , a[n] != 0 ? b[n] : c[n]).
6088
+ // / For the OpenCL extensions, the ?: operator is evaluated as
6089
+ // / (most-significant-bit-set(a[0]) ? b[0] : c[0], .. ,
6090
+ // / most-significant-bit-set(a[n]) ? b[n] : c[n]).
6089
6091
QualType Sema::CXXCheckConditionalOperands (ExprResult &Cond, ExprResult &LHS,
6090
6092
ExprResult &RHS, ExprValueKind &VK,
6091
6093
ExprObjectKind &OK,
@@ -6169,7 +6171,7 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
6169
6171
6170
6172
// Neither is void.
6171
6173
if (IsVectorConditional)
6172
- return CheckGNUVectorConditionalTypes (Cond, LHS, RHS, QuestionLoc);
6174
+ return CheckVectorConditionalTypes (Cond, LHS, RHS, QuestionLoc);
6173
6175
6174
6176
// C++11 [expr.cond]p3
6175
6177
// Otherwise, if the second and third operand have different types, and
0 commit comments