@@ -221,6 +221,11 @@ namespace {
221221 ArraySize = 2;
222222 MostDerivedLength = I + 1;
223223 IsArray = true;
224+ } else if (const auto *VT = Type->getAs<VectorType>()) {
225+ Type = VT->getElementType();
226+ ArraySize = VT->getNumElements();
227+ MostDerivedLength = I + 1;
228+ IsArray = true;
224229 } else if (const FieldDecl *FD = getAsField(Path[I])) {
225230 Type = FD->getType();
226231 ArraySize = 0;
@@ -263,7 +268,6 @@ namespace {
263268 /// If the current array is an unsized array, the value of this is
264269 /// undefined.
265270 uint64_t MostDerivedArraySize;
266-
267271 /// The type of the most derived object referred to by this address.
268272 QualType MostDerivedType;
269273
@@ -437,6 +441,16 @@ namespace {
437441 MostDerivedArraySize = 2;
438442 MostDerivedPathLength = Entries.size();
439443 }
444+
445+ void addVectorElementUnchecked(QualType EltTy, uint64_t Size,
446+ uint64_t Idx) {
447+ Entries.push_back(PathEntry::ArrayIndex(Idx));
448+ MostDerivedType = EltTy;
449+ MostDerivedPathLength = Entries.size();
450+ MostDerivedArraySize = 0;
451+ MostDerivedIsArrayElement = false;
452+ }
453+
440454 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info, const Expr *E);
441455 void diagnosePointerArithmetic(EvalInfo &Info, const Expr *E,
442456 const APSInt &N);
@@ -1732,6 +1746,11 @@ namespace {
17321746 if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
17331747 Designator.addComplexUnchecked(EltTy, Imag);
17341748 }
1749+ void addVectorElement(EvalInfo &Info, const Expr *E, QualType EltTy,
1750+ uint64_t Size, uint64_t Idx) {
1751+ if (checkSubobject(Info, E, CSK_VectorElement))
1752+ Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1753+ }
17351754 void clearIsNullPointer() {
17361755 IsNullPtr = false;
17371756 }
@@ -3278,6 +3297,19 @@ static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E,
32783297 return true;
32793298}
32803299
3300+ static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E,
3301+ LValue &LVal, QualType EltTy,
3302+ uint64_t Size, uint64_t Idx) {
3303+ if (Idx) {
3304+ CharUnits SizeOfElement;
3305+ if (!HandleSizeof(Info, E->getExprLoc(), EltTy, SizeOfElement))
3306+ return false;
3307+ LVal.Offset += SizeOfElement * Idx;
3308+ }
3309+ LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3310+ return true;
3311+ }
3312+
32813313/// Try to evaluate the initializer for a variable declaration.
32823314///
32833315/// \param Info Information about the ongoing evaluation.
@@ -3823,6 +3855,27 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
38233855 return handler.found(Index ? O->getComplexFloatImag()
38243856 : O->getComplexFloatReal(), ObjType);
38253857 }
3858+ } else if (const auto *VT = ObjType->getAs<VectorType>()) {
3859+ uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3860+ unsigned NumElements = VT->getNumElements();
3861+ if (Index == NumElements) {
3862+ if (Info.getLangOpts().CPlusPlus11)
3863+ Info.FFDiag(E, diag::note_constexpr_access_past_end)
3864+ << handler.AccessKind;
3865+ else
3866+ Info.FFDiag(E);
3867+ return handler.failed();
3868+ }
3869+
3870+ if (Index > NumElements) {
3871+ Info.CCEDiag(E, diag::note_constexpr_array_index)
3872+ << Index << /*array*/ 0 << NumElements;
3873+ return handler.failed();
3874+ }
3875+
3876+ ObjType = VT->getElementType();
3877+ assert(I == N - 1 && "extracting subobject of scalar?");
3878+ return handler.found(O->getVectorElt(Index), ObjType);
38263879 } else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {
38273880 if (Field->isMutable() &&
38283881 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
@@ -8432,6 +8485,7 @@ class LValueExprEvaluator
84328485 bool VisitCXXTypeidExpr(const CXXTypeidExpr *E);
84338486 bool VisitCXXUuidofExpr(const CXXUuidofExpr *E);
84348487 bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E);
8488+ bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E);
84358489 bool VisitUnaryDeref(const UnaryOperator *E);
84368490 bool VisitUnaryReal(const UnaryOperator *E);
84378491 bool VisitUnaryImag(const UnaryOperator *E);
@@ -8755,15 +8809,63 @@ bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) {
87558809 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
87568810}
87578811
8812+ bool LValueExprEvaluator::VisitExtVectorElementExpr(
8813+ const ExtVectorElementExpr *E) {
8814+ bool Success = true;
8815+
8816+ APValue Val;
8817+ if (!Evaluate(Val, Info, E->getBase())) {
8818+ if (!Info.noteFailure())
8819+ return false;
8820+ Success = false;
8821+ }
8822+
8823+ SmallVector<uint32_t, 4> Indices;
8824+ E->getEncodedElementAccess(Indices);
8825+ // FIXME: support accessing more than one element
8826+ if (Indices.size() > 1)
8827+ return false;
8828+
8829+ if (Success) {
8830+ Result.setFrom(Info.Ctx, Val);
8831+ const auto *VT = E->getBase()->getType()->castAs<VectorType>();
8832+ HandleLValueVectorElement(Info, E, Result, VT->getElementType(),
8833+ VT->getNumElements(), Indices[0]);
8834+ }
8835+
8836+ return Success;
8837+ }
8838+
87588839bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
8759- // FIXME: Deal with vectors as array subscript bases.
8760- if (E->getBase()->getType()->isVectorType() ||
8761- E->getBase()->getType()->isSveVLSBuiltinType())
8840+ if (E->getBase()->getType()->isSveVLSBuiltinType())
87628841 return Error(E);
87638842
87648843 APSInt Index;
87658844 bool Success = true;
87668845
8846+ if (const auto *VT = E->getBase()->getType()->getAs<VectorType>()) {
8847+ APValue Val;
8848+ if (!Evaluate(Val, Info, E->getBase())) {
8849+ if (!Info.noteFailure())
8850+ return false;
8851+ Success = false;
8852+ }
8853+
8854+ if (!EvaluateInteger(E->getIdx(), Index, Info)) {
8855+ if (!Info.noteFailure())
8856+ return false;
8857+ Success = false;
8858+ }
8859+
8860+ if (Success) {
8861+ Result.setFrom(Info.Ctx, Val);
8862+ HandleLValueVectorElement(Info, E, Result, VT->getElementType(),
8863+ VT->getNumElements(), Index.getExtValue());
8864+ }
8865+
8866+ return Success;
8867+ }
8868+
87678869 // C++17's rules require us to evaluate the LHS first, regardless of which
87688870 // side is the base.
87698871 for (const Expr *SubExpr : {E->getLHS(), E->getRHS()}) {
0 commit comments