@@ -1325,6 +1325,57 @@ void CodeGenModule::EmitExplicitCastExprType(const ExplicitCastExpr *E,
13251325// LValue Expression Emission
13261326// ===----------------------------------------------------------------------===//
13271327
1328+ static CharUnits getArrayElementAlign (CharUnits arrayAlign, llvm::Value *idx,
1329+ CharUnits eltSize) {
1330+ // If we have a constant index, we can use the exact offset of the
1331+ // element we're accessing.
1332+ if (auto *constantIdx = dyn_cast<llvm::ConstantInt>(idx)) {
1333+ CharUnits offset = constantIdx->getZExtValue () * eltSize;
1334+ return arrayAlign.alignmentAtOffset (offset);
1335+ }
1336+
1337+ // Otherwise, use the worst-case alignment for any element.
1338+ return arrayAlign.alignmentOfArrayElement (eltSize);
1339+ }
1340+
1341+ // / Emit pointer + index arithmetic.
1342+ static Address emitPointerArithmetic (CodeGenFunction &CGF,
1343+ const BinaryOperator *BO,
1344+ LValueBaseInfo *BaseInfo,
1345+ TBAAAccessInfo *TBAAInfo,
1346+ KnownNonNull_t IsKnownNonNull) {
1347+ assert (BO->isAdditiveOp () && " Expect an addition or subtraction." );
1348+ Expr *pointerOperand = BO->getLHS ();
1349+ Expr *indexOperand = BO->getRHS ();
1350+ bool isSubtraction = BO->getOpcode () == BO_Sub;
1351+
1352+ Address BaseAddr = Address::invalid ();
1353+ llvm::Value *index = nullptr ;
1354+ // In a subtraction, the LHS is always the pointer.
1355+ // Note: do not change the evaluation order.
1356+ if (!isSubtraction && !pointerOperand->getType ()->isAnyPointerType ()) {
1357+ std::swap (pointerOperand, indexOperand);
1358+ index = CGF.EmitScalarExpr (indexOperand);
1359+ BaseAddr = CGF.EmitPointerWithAlignment (pointerOperand, BaseInfo, TBAAInfo,
1360+ NotKnownNonNull);
1361+ } else {
1362+ BaseAddr = CGF.EmitPointerWithAlignment (pointerOperand, BaseInfo, TBAAInfo,
1363+ NotKnownNonNull);
1364+ index = CGF.EmitScalarExpr (indexOperand);
1365+ }
1366+
1367+ llvm::Value *pointer = BaseAddr.getBasePointer ();
1368+ llvm::Value *Res = CGF.EmitPointerArithmetic (
1369+ BO, pointerOperand, pointer, indexOperand, index, isSubtraction);
1370+ QualType PointeeTy = BO->getType ()->getPointeeType ();
1371+ CharUnits Align =
1372+ getArrayElementAlign (BaseAddr.getAlignment (), index,
1373+ CGF.getContext ().getTypeSizeInChars (PointeeTy));
1374+ return Address (Res, CGF.ConvertTypeForMem (PointeeTy), Align,
1375+ CGF.CGM .getPointerAuthInfoForPointeeType (PointeeTy),
1376+ /* Offset=*/ nullptr , IsKnownNonNull);
1377+ }
1378+
13281379static Address EmitPointerWithAlignment (const Expr *E, LValueBaseInfo *BaseInfo,
13291380 TBAAAccessInfo *TBAAInfo,
13301381 KnownNonNull_t IsKnownNonNull,
@@ -1387,6 +1438,7 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
13871438 if (CE->getCastKind () == CK_AddressSpaceConversion)
13881439 Addr = CGF.Builder .CreateAddrSpaceCast (
13891440 Addr, CGF.ConvertType (E->getType ()), ElemTy);
1441+
13901442 return CGF.authPointerToPointerCast (Addr, CE->getSubExpr ()->getType (),
13911443 CE->getType ());
13921444 }
@@ -1447,6 +1499,12 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
14471499 }
14481500 }
14491501
1502+ // Pointer arithmetic: pointer +/- index.
1503+ if (auto *BO = dyn_cast<BinaryOperator>(E)) {
1504+ if (BO->isAdditiveOp ())
1505+ return emitPointerArithmetic (CGF, BO, BaseInfo, TBAAInfo, IsKnownNonNull);
1506+ }
1507+
14501508 // TODO: conditional operators, comma.
14511509
14521510 // Otherwise, use the alignment of the type.
@@ -4236,21 +4294,6 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr,
42364294 }
42374295}
42384296
4239- static CharUnits getArrayElementAlign (CharUnits arrayAlign,
4240- llvm::Value *idx,
4241- CharUnits eltSize) {
4242- // If we have a constant index, we can use the exact offset of the
4243- // element we're accessing.
4244- if (auto constantIdx = dyn_cast<llvm::ConstantInt>(idx)) {
4245- CharUnits offset = constantIdx->getZExtValue () * eltSize;
4246- return arrayAlign.alignmentAtOffset (offset);
4247-
4248- // Otherwise, use the worst-case alignment for any element.
4249- } else {
4250- return arrayAlign.alignmentOfArrayElement (eltSize);
4251- }
4252- }
4253-
42544297static QualType getFixedSizeElementType (const ASTContext &ctx,
42554298 const VariableArrayType *vla) {
42564299 QualType eltType;
0 commit comments