@@ -1325,6 +1325,57 @@ void CodeGenModule::EmitExplicitCastExprType(const ExplicitCastExpr *E,
1325
1325
// LValue Expression Emission
1326
1326
// ===----------------------------------------------------------------------===//
1327
1327
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
+
1328
1379
static Address EmitPointerWithAlignment (const Expr *E, LValueBaseInfo *BaseInfo,
1329
1380
TBAAAccessInfo *TBAAInfo,
1330
1381
KnownNonNull_t IsKnownNonNull,
@@ -1387,6 +1438,7 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
1387
1438
if (CE->getCastKind () == CK_AddressSpaceConversion)
1388
1439
Addr = CGF.Builder .CreateAddrSpaceCast (
1389
1440
Addr, CGF.ConvertType (E->getType ()), ElemTy);
1441
+
1390
1442
return CGF.authPointerToPointerCast (Addr, CE->getSubExpr ()->getType (),
1391
1443
CE->getType ());
1392
1444
}
@@ -1447,6 +1499,12 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
1447
1499
}
1448
1500
}
1449
1501
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
+
1450
1508
// TODO: conditional operators, comma.
1451
1509
1452
1510
// Otherwise, use the alignment of the type.
@@ -4236,21 +4294,6 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr,
4236
4294
}
4237
4295
}
4238
4296
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
-
4254
4297
static QualType getFixedSizeElementType (const ASTContext &ctx,
4255
4298
const VariableArrayType *vla) {
4256
4299
QualType eltType;
0 commit comments