@@ -1314,6 +1314,57 @@ void CodeGenModule::EmitExplicitCastExprType(const ExplicitCastExpr *E,
1314
1314
// LValue Expression Emission
1315
1315
// ===----------------------------------------------------------------------===//
1316
1316
1317
+ static CharUnits getArrayElementAlign (CharUnits arrayAlign, llvm::Value *idx,
1318
+ CharUnits eltSize) {
1319
+ // If we have a constant index, we can use the exact offset of the
1320
+ // element we're accessing.
1321
+ if (auto *constantIdx = dyn_cast<llvm::ConstantInt>(idx)) {
1322
+ CharUnits offset = constantIdx->getZExtValue () * eltSize;
1323
+ return arrayAlign.alignmentAtOffset (offset);
1324
+ }
1325
+
1326
+ // Otherwise, use the worst-case alignment for any element.
1327
+ return arrayAlign.alignmentOfArrayElement (eltSize);
1328
+ }
1329
+
1330
+ // / Emit pointer + index arithmetic.
1331
+ static Address emitPointerArithmetic (CodeGenFunction &CGF,
1332
+ const BinaryOperator *BO,
1333
+ LValueBaseInfo *BaseInfo,
1334
+ TBAAAccessInfo *TBAAInfo,
1335
+ KnownNonNull_t IsKnownNonNull) {
1336
+ assert (BO->isAdditiveOp () && " Expect an addition or subtraction." );
1337
+ Expr *pointerOperand = BO->getLHS ();
1338
+ Expr *indexOperand = BO->getRHS ();
1339
+ bool isSubtraction = BO->getOpcode () == BO_Sub;
1340
+
1341
+ Address BaseAddr = Address::invalid ();
1342
+ llvm::Value *index = nullptr ;
1343
+ // In a subtraction, the LHS is always the pointer.
1344
+ // Note: do not change the evaluation order.
1345
+ if (!isSubtraction && !pointerOperand->getType ()->isAnyPointerType ()) {
1346
+ std::swap (pointerOperand, indexOperand);
1347
+ index = CGF.EmitScalarExpr (indexOperand);
1348
+ BaseAddr = CGF.EmitPointerWithAlignment (pointerOperand, BaseInfo, TBAAInfo,
1349
+ NotKnownNonNull);
1350
+ } else {
1351
+ BaseAddr = CGF.EmitPointerWithAlignment (pointerOperand, BaseInfo, TBAAInfo,
1352
+ NotKnownNonNull);
1353
+ index = CGF.EmitScalarExpr (indexOperand);
1354
+ }
1355
+
1356
+ llvm::Value *pointer = BaseAddr.getBasePointer ();
1357
+ llvm::Value *Res = CGF.EmitPointerArithmetic (
1358
+ BO, pointerOperand, pointer, indexOperand, index, isSubtraction);
1359
+ QualType PointeeTy = BO->getType ()->getPointeeType ();
1360
+ CharUnits Align =
1361
+ getArrayElementAlign (BaseAddr.getAlignment (), index,
1362
+ CGF.getContext ().getTypeSizeInChars (PointeeTy));
1363
+ return Address (Res, CGF.ConvertTypeForMem (PointeeTy), Align,
1364
+ CGF.CGM .getPointerAuthInfoForPointeeType (PointeeTy),
1365
+ /* Offset=*/ nullptr , IsKnownNonNull);
1366
+ }
1367
+
1317
1368
static Address EmitPointerWithAlignment (const Expr *E, LValueBaseInfo *BaseInfo,
1318
1369
TBAAAccessInfo *TBAAInfo,
1319
1370
KnownNonNull_t IsKnownNonNull,
@@ -1376,6 +1427,13 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
1376
1427
if (CE->getCastKind () == CK_AddressSpaceConversion)
1377
1428
Addr = CGF.Builder .CreateAddrSpaceCast (
1378
1429
Addr, CGF.ConvertType (E->getType ()), ElemTy);
1430
+ // Note: Workaround for PR114062. See also the special handling in
1431
+ // ScalarExprEmitter::VisitCastExpr.
1432
+ if (auto *A = dyn_cast<llvm::Argument>(Addr.getBasePointer ());
1433
+ A && A->hasStructRetAttr ())
1434
+ Addr = CGF.Builder .CreateAddrSpaceCast (
1435
+ Addr, CGF.ConvertType (E->getType ()), ElemTy);
1436
+
1379
1437
return CGF.authPointerToPointerCast (Addr, CE->getSubExpr ()->getType (),
1380
1438
CE->getType ());
1381
1439
}
@@ -1436,6 +1494,12 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
1436
1494
}
1437
1495
}
1438
1496
1497
+ // Pointer arithmetic: pointer +/- index.
1498
+ if (auto *BO = dyn_cast<BinaryOperator>(E)) {
1499
+ if (BO->isAdditiveOp ())
1500
+ return emitPointerArithmetic (CGF, BO, BaseInfo, TBAAInfo, IsKnownNonNull);
1501
+ }
1502
+
1439
1503
// TODO: conditional operators, comma.
1440
1504
1441
1505
// Otherwise, use the alignment of the type.
@@ -4222,21 +4286,6 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr,
4222
4286
}
4223
4287
}
4224
4288
4225
- static CharUnits getArrayElementAlign (CharUnits arrayAlign,
4226
- llvm::Value *idx,
4227
- CharUnits eltSize) {
4228
- // If we have a constant index, we can use the exact offset of the
4229
- // element we're accessing.
4230
- if (auto constantIdx = dyn_cast<llvm::ConstantInt>(idx)) {
4231
- CharUnits offset = constantIdx->getZExtValue () * eltSize;
4232
- return arrayAlign.alignmentAtOffset (offset);
4233
-
4234
- // Otherwise, use the worst-case alignment for any element.
4235
- } else {
4236
- return arrayAlign.alignmentOfArrayElement (eltSize);
4237
- }
4238
- }
4239
-
4240
4289
static QualType getFixedSizeElementType (const ASTContext &ctx,
4241
4290
const VariableArrayType *vla) {
4242
4291
QualType eltType;
0 commit comments