@@ -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;
@@ -437,6 +442,16 @@ namespace {
437442 MostDerivedArraySize = 2;
438443 MostDerivedPathLength = Entries.size();
439444 }
445+ void addVectorUnchecked(QualType EltTy, uint64_t Size, uint64_t Idx) {
446+ Entries.push_back(PathEntry::ArrayIndex(Idx));
447+
448+ // This is technically a most-derived object, though in practice this
449+ // is unlikely to matter.
450+ MostDerivedType = EltTy;
451+ MostDerivedIsArrayElement = true;
452+ MostDerivedArraySize = Size;
453+ MostDerivedPathLength = Entries.size();
454+ }
440455 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info, const Expr *E);
441456 void diagnosePointerArithmetic(EvalInfo &Info, const Expr *E,
442457 const APSInt &N);
@@ -1732,6 +1747,11 @@ namespace {
17321747 if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
17331748 Designator.addComplexUnchecked(EltTy, Imag);
17341749 }
1750+ void addVectorElement(EvalInfo &Info, const Expr *E, QualType EltTy,
1751+ uint64_t Size, uint64_t Idx) {
1752+ if (checkSubobject(Info, E, CSK_VectorElement))
1753+ Designator.addVectorUnchecked(EltTy, Size, Idx);
1754+ }
17351755 void clearIsNullPointer() {
17361756 IsNullPtr = false;
17371757 }
@@ -3278,6 +3298,19 @@ static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E,
32783298 return true;
32793299}
32803300
3301+ static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E,
3302+ LValue &LVal, QualType EltTy,
3303+ uint64_t Size, uint64_t Idx) {
3304+ if (Idx) {
3305+ CharUnits SizeOfElement;
3306+ if (!HandleSizeof(Info, E->getExprLoc(), EltTy, SizeOfElement))
3307+ return false;
3308+ LVal.Offset += SizeOfElement * Idx;
3309+ }
3310+ LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3311+ return true;
3312+ }
3313+
32813314/// Try to evaluate the initializer for a variable declaration.
32823315///
32833316/// \param Info Information about the ongoing evaluation.
@@ -3823,6 +3856,21 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
38233856 return handler.found(Index ? O->getComplexFloatImag()
38243857 : O->getComplexFloatReal(), ObjType);
38253858 }
3859+ } else if (const auto *VT = ObjType->getAs<VectorType>()) {
3860+ uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3861+ if (Index >= VT->getNumElements()) {
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+ ObjType = VT->getElementType();
3871+
3872+ assert(I == N - 1 && "extracting subobject of scalar?");
3873+ return handler.found(O->getVectorElt(Index), ObjType);
38263874 } else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {
38273875 if (Field->isMutable() &&
38283876 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
@@ -8432,6 +8480,7 @@ class LValueExprEvaluator
84328480 bool VisitCXXTypeidExpr(const CXXTypeidExpr *E);
84338481 bool VisitCXXUuidofExpr(const CXXUuidofExpr *E);
84348482 bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E);
8483+ bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E);
84358484 bool VisitUnaryDeref(const UnaryOperator *E);
84368485 bool VisitUnaryReal(const UnaryOperator *E);
84378486 bool VisitUnaryImag(const UnaryOperator *E);
@@ -8755,15 +8804,63 @@ bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) {
87558804 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
87568805}
87578806
8807+ bool LValueExprEvaluator::VisitExtVectorElementExpr(
8808+ const ExtVectorElementExpr *E) {
8809+ bool Success = true;
8810+
8811+ APValue Val;
8812+ if (!Evaluate(Val, Info, E->getBase())) {
8813+ if (!Info.noteFailure())
8814+ return false;
8815+ Success = false;
8816+ }
8817+
8818+ SmallVector<uint32_t, 4> Indices;
8819+ E->getEncodedElementAccess(Indices);
8820+ // FIXME: support accessing more than one element
8821+ if (Indices.size() > 1)
8822+ return false;
8823+
8824+ if (Success) {
8825+ Result.setFrom(Info.Ctx, Val);
8826+ const auto *VT = E->getBase()->getType()->castAs<VectorType>();
8827+ HandleLValueVectorElement(Info, E, Result, VT->getElementType(),
8828+ VT->getNumElements(), Indices[0]);
8829+ }
8830+
8831+ return Success;
8832+ }
8833+
87588834bool 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())
8835+ if (E->getBase()->getType()->isSveVLSBuiltinType())
87628836 return Error(E);
87638837
87648838 APSInt Index;
87658839 bool Success = true;
87668840
8841+ if (const auto *VT = E->getBase()->getType()->getAs<VectorType>()) {
8842+ APValue Val;
8843+ if (!Evaluate(Val, Info, E->getBase())) {
8844+ if (!Info.noteFailure())
8845+ return false;
8846+ Success = false;
8847+ }
8848+
8849+ if (!EvaluateInteger(E->getIdx(), Index, Info)) {
8850+ if (!Info.noteFailure())
8851+ return false;
8852+ Success = false;
8853+ }
8854+
8855+ if (Success) {
8856+ Result.setFrom(Info.Ctx, Val);
8857+ HandleLValueVectorElement(Info, E, Result, VT->getElementType(),
8858+ VT->getNumElements(), Index.getExtValue());
8859+ }
8860+
8861+ return Success;
8862+ }
8863+
87678864 // C++17's rules require us to evaluate the LHS first, regardless of which
87688865 // side is the base.
87698866 for (const Expr *SubExpr : {E->getLHS(), E->getRHS()}) {
0 commit comments