@@ -5918,19 +5918,18 @@ static bool ConvertForConditional(Sema &Self, ExprResult &E, QualType T) {
5918
5918
// extension.
5919
5919
static bool isValidVectorForConditionalCondition (ASTContext &Ctx,
5920
5920
QualType CondTy) {
5921
- if (!CondTy->isVectorType () || CondTy->isExtVectorType ())
5921
+ if (!CondTy->isVectorType () && ! CondTy->isExtVectorType ())
5922
5922
return false ;
5923
5923
const QualType EltTy =
5924
5924
cast<VectorType>(CondTy.getCanonicalType ())->getElementType ();
5925
-
5926
5925
assert (!EltTy->isBooleanType () && !EltTy->isEnumeralType () &&
5927
5926
" Vectors cant be boolean or enum types" );
5928
5927
return EltTy->isIntegralType (Ctx);
5929
5928
}
5930
5929
5931
- QualType Sema::CheckGNUVectorConditionalTypes (ExprResult &Cond, ExprResult &LHS,
5932
- ExprResult &RHS,
5933
- SourceLocation QuestionLoc) {
5930
+ QualType Sema::CheckVectorConditionalTypes (ExprResult &Cond, ExprResult &LHS,
5931
+ ExprResult &RHS,
5932
+ SourceLocation QuestionLoc) {
5934
5933
LHS = DefaultFunctionArrayLvalueConversion (LHS.get ());
5935
5934
RHS = DefaultFunctionArrayLvalueConversion (RHS.get ());
5936
5935
@@ -5945,24 +5944,17 @@ QualType Sema::CheckGNUVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
5945
5944
5946
5945
QualType ResultType;
5947
5946
5948
- // FIXME: In the future we should define what the Extvector conditional
5949
- // operator looks like.
5950
- if (LHSVT && isa<ExtVectorType>(LHSVT)) {
5951
- Diag (QuestionLoc, diag::err_conditional_vector_operand_type)
5952
- << /* isExtVector*/ true << LHSType;
5953
- return {};
5954
- }
5955
-
5956
- if (RHSVT && isa<ExtVectorType>(RHSVT)) {
5957
- Diag (QuestionLoc, diag::err_conditional_vector_operand_type)
5958
- << /* isExtVector*/ true << RHSType;
5959
- return {};
5960
- }
5961
5947
5962
5948
if (LHSVT && RHSVT) {
5949
+ if (isa<ExtVectorType>(CondVT) != isa<ExtVectorType>(LHSVT)) {
5950
+ Diag (QuestionLoc, diag::err_conditional_vector_cond_result_mismatch)
5951
+ << /* isExtVector*/ isa<ExtVectorType>(CondVT);
5952
+ return {};
5953
+ }
5954
+
5963
5955
// If both are vector types, they must be the same type.
5964
5956
if (!Context.hasSameType (LHSType, RHSType)) {
5965
- Diag (QuestionLoc, diag::err_conditional_vector_mismatched_vectors )
5957
+ Diag (QuestionLoc, diag::err_conditional_vector_mismatched )
5966
5958
<< LHSType << RHSType;
5967
5959
return {};
5968
5960
}
@@ -5987,18 +5979,22 @@ QualType Sema::CheckGNUVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
5987
5979
5988
5980
if (ResultElementTy->isEnumeralType ()) {
5989
5981
Diag (QuestionLoc, diag::err_conditional_vector_operand_type)
5990
- << /* isExtVector */ false << ResultElementTy;
5982
+ << ResultElementTy;
5991
5983
return {};
5992
5984
}
5993
- ResultType = Context.getVectorType (
5994
- ResultElementTy, CondType->castAs <VectorType>()->getNumElements (),
5995
- VectorType::GenericVector);
5985
+ if (CondType->isExtVectorType ())
5986
+ ResultType =
5987
+ Context.getExtVectorType (ResultElementTy, CondVT->getNumElements ());
5988
+ else
5989
+ ResultType = Context.getVectorType (
5990
+ ResultElementTy, CondVT->getNumElements (), VectorType::GenericVector);
5996
5991
5997
5992
LHS = ImpCastExprToType (LHS.get (), ResultType, CK_VectorSplat);
5998
5993
RHS = ImpCastExprToType (RHS.get (), ResultType, CK_VectorSplat);
5999
5994
}
6000
5995
6001
5996
assert (!ResultType.isNull () && ResultType->isVectorType () &&
5997
+ (!CondType->isExtVectorType () || ResultType->isExtVectorType ()) &&
6002
5998
" Result should have been a vector type" );
6003
5999
auto *ResultVectorTy = ResultType->castAs <VectorType>();
6004
6000
QualType ResultElementTy = ResultVectorTy->getElementType ();
@@ -6025,15 +6021,21 @@ QualType Sema::CheckGNUVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
6025
6021
// / See C++ [expr.cond]. Note that LHS is never null, even for the GNU x ?: y
6026
6022
// / extension. In this case, LHS == Cond. (But they're not aliases.)
6027
6023
// /
6028
- // / This function also implements GCC's vector extension for conditionals.
6029
- // / GCC's vector extension permits the use of a?b:c where the type of
6030
- // / a is that of a integer vector with the same number of elements and
6031
- // / size as the vectors of b and c. If one of either b or c is a scalar
6032
- // / it is implicitly converted to match the type of the vector.
6033
- // / Otherwise the expression is ill-formed. If both b and c are scalars,
6034
- // / then b and c are checked and converted to the type of a if possible.
6035
- // / Unlike the OpenCL ?: operator, the expression is evaluated as
6036
- // / (a[0] != 0 ? b[0] : c[0], .. , a[n] != 0 ? b[n] : c[n]).
6024
+ // / This function also implements GCC's vector extension and the
6025
+ // / OpenCL/ext_vector_type extension for conditionals. The vector extensions
6026
+ // / permit the use of a?b:c where the type of a is that of a integer vector with
6027
+ // / the same number of elements and size as the vectors of b and c. If one of
6028
+ // / either b or c is a scalar it is implicitly converted to match the type of
6029
+ // / the vector. Otherwise the expression is ill-formed. If both b and c are
6030
+ // / scalars, then b and c are checked and converted to the type of a if
6031
+ // / possible.
6032
+ // /
6033
+ // / The expressions are evaluated differently for GCC's and OpenCL's extensions.
6034
+ // / For the GCC extension, the ?: operator is evaluated as
6035
+ // / (a[0] != 0 ? b[0] : c[0], .. , a[n] != 0 ? b[n] : c[n]).
6036
+ // / For the OpenCL extensions, the ?: operator is evaluated as
6037
+ // / (most-significant-bit-set(a[0]) ? b[0] : c[0], .. ,
6038
+ // / most-significant-bit-set(a[n]) ? b[n] : c[n]).
6037
6039
QualType Sema::CXXCheckConditionalOperands (ExprResult &Cond, ExprResult &LHS,
6038
6040
ExprResult &RHS, ExprValueKind &VK,
6039
6041
ExprObjectKind &OK,
@@ -6117,7 +6119,7 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
6117
6119
6118
6120
// Neither is void.
6119
6121
if (IsVectorConditional)
6120
- return CheckGNUVectorConditionalTypes (Cond, LHS, RHS, QuestionLoc);
6122
+ return CheckVectorConditionalTypes (Cond, LHS, RHS, QuestionLoc);
6121
6123
6122
6124
// C++11 [expr.cond]p3
6123
6125
// Otherwise, if the second and third operand have different types, and
0 commit comments