@@ -221,6 +221,11 @@ namespace {
221
221
ArraySize = 2;
222
222
MostDerivedLength = I + 1;
223
223
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;
224
229
} else if (const FieldDecl *FD = getAsField(Path[I])) {
225
230
Type = FD->getType();
226
231
ArraySize = 0;
@@ -263,7 +268,6 @@ namespace {
263
268
/// If the current array is an unsized array, the value of this is
264
269
/// undefined.
265
270
uint64_t MostDerivedArraySize;
266
-
267
271
/// The type of the most derived object referred to by this address.
268
272
QualType MostDerivedType;
269
273
@@ -437,6 +441,16 @@ namespace {
437
441
MostDerivedArraySize = 2;
438
442
MostDerivedPathLength = Entries.size();
439
443
}
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
+
440
454
void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info, const Expr *E);
441
455
void diagnosePointerArithmetic(EvalInfo &Info, const Expr *E,
442
456
const APSInt &N);
@@ -1732,6 +1746,11 @@ namespace {
1732
1746
if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
1733
1747
Designator.addComplexUnchecked(EltTy, Imag);
1734
1748
}
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
+ }
1735
1754
void clearIsNullPointer() {
1736
1755
IsNullPtr = false;
1737
1756
}
@@ -3278,6 +3297,19 @@ static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E,
3278
3297
return true;
3279
3298
}
3280
3299
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
+
3281
3313
/// Try to evaluate the initializer for a variable declaration.
3282
3314
///
3283
3315
/// \param Info Information about the ongoing evaluation.
@@ -3823,6 +3855,27 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
3823
3855
return handler.found(Index ? O->getComplexFloatImag()
3824
3856
: O->getComplexFloatReal(), ObjType);
3825
3857
}
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);
3826
3879
} else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {
3827
3880
if (Field->isMutable() &&
3828
3881
!Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
@@ -8432,6 +8485,7 @@ class LValueExprEvaluator
8432
8485
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E);
8433
8486
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E);
8434
8487
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E);
8488
+ bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E);
8435
8489
bool VisitUnaryDeref(const UnaryOperator *E);
8436
8490
bool VisitUnaryReal(const UnaryOperator *E);
8437
8491
bool VisitUnaryImag(const UnaryOperator *E);
@@ -8755,15 +8809,63 @@ bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) {
8755
8809
return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
8756
8810
}
8757
8811
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
+
8758
8839
bool 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())
8762
8841
return Error(E);
8763
8842
8764
8843
APSInt Index;
8765
8844
bool Success = true;
8766
8845
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
+
8767
8869
// C++17's rules require us to evaluate the LHS first, regardless of which
8768
8870
// side is the base.
8769
8871
for (const Expr *SubExpr : {E->getLHS(), E->getRHS()}) {
0 commit comments