@@ -1591,6 +1591,10 @@ computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
1591
1591
return std::make_pair (BlockCaptureEntityKind::BlockObject, Flags);
1592
1592
}
1593
1593
1594
+ if (T.hasAddressDiscriminatedPointerAuth ())
1595
+ return std::make_pair (
1596
+ BlockCaptureEntityKind::AddressDiscriminatedPointerAuth, Flags);
1597
+
1594
1598
Flags = BLOCK_FIELD_IS_OBJECT;
1595
1599
bool isBlockPointer = T->isBlockPointerType ();
1596
1600
if (isBlockPointer)
@@ -1611,6 +1615,10 @@ computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
1611
1615
return std::make_pair (!isBlockPointer ? BlockCaptureEntityKind::ARCStrong
1612
1616
: BlockCaptureEntityKind::BlockObject,
1613
1617
Flags);
1618
+ case QualType::PCK_PtrAuth:
1619
+ return std::make_pair (
1620
+ BlockCaptureEntityKind::AddressDiscriminatedPointerAuth,
1621
+ BlockFieldFlags ());
1614
1622
case QualType::PCK_Trivial:
1615
1623
case QualType::PCK_VolatileTrivial: {
1616
1624
if (!T->isObjCRetainableType ())
@@ -1713,6 +1721,13 @@ static std::string getBlockCaptureStr(const CGBlockInfo::Capture &Cap,
1713
1721
case BlockCaptureEntityKind::ARCStrong:
1714
1722
Str += " s" ;
1715
1723
break ;
1724
+ case BlockCaptureEntityKind::AddressDiscriminatedPointerAuth: {
1725
+ auto PtrAuth = CaptureTy.getPointerAuth ();
1726
+ assert (PtrAuth && PtrAuth.isAddressDiscriminated ());
1727
+ Str += " p" + llvm::to_string (PtrAuth.getKey ()) + " d" +
1728
+ llvm::to_string (PtrAuth.getExtraDiscriminator ());
1729
+ break ;
1730
+ }
1716
1731
case BlockCaptureEntityKind::BlockObject: {
1717
1732
const VarDecl *Var = CI.getVariable ();
1718
1733
unsigned F = Flags.getBitMask ();
@@ -1829,6 +1844,7 @@ static void pushCaptureCleanup(BlockCaptureEntityKind CaptureKind,
1829
1844
}
1830
1845
break ;
1831
1846
}
1847
+ case BlockCaptureEntityKind::AddressDiscriminatedPointerAuth:
1832
1848
case BlockCaptureEntityKind::None:
1833
1849
break ;
1834
1850
}
@@ -1925,6 +1941,14 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
1925
1941
case BlockCaptureEntityKind::ARCWeak:
1926
1942
EmitARCCopyWeak (dstField, srcField);
1927
1943
break ;
1944
+ case BlockCaptureEntityKind::AddressDiscriminatedPointerAuth: {
1945
+ QualType Type = CI.getVariable ()->getType ();
1946
+ PointerAuthQualifier PointerAuth = Type.getPointerAuth ();
1947
+ assert (PointerAuth && PointerAuth.isAddressDiscriminated ());
1948
+ EmitPointerAuthCopy (PointerAuth, Type, dstField, srcField);
1949
+ // We don't need to push cleanups for ptrauth types.
1950
+ continue ;
1951
+ }
1928
1952
case BlockCaptureEntityKind::NonTrivialCStruct: {
1929
1953
// If this is a C struct that requires non-trivial copy construction,
1930
1954
// emit a call to its copy constructor.
@@ -2261,6 +2285,33 @@ class CXXByrefHelpers final : public BlockByrefHelpers {
2261
2285
}
2262
2286
};
2263
2287
2288
+ // / Emits the copy/dispose helpers for a __block variable with
2289
+ // / address-discriminated pointer authentication.
2290
+ class AddressDiscriminatedByrefHelpers final : public BlockByrefHelpers {
2291
+ QualType VarType;
2292
+
2293
+ public:
2294
+ AddressDiscriminatedByrefHelpers (CharUnits Alignment, QualType Type)
2295
+ : BlockByrefHelpers(Alignment), VarType(Type) {
2296
+ assert (Type.hasAddressDiscriminatedPointerAuth ());
2297
+ }
2298
+
2299
+ void emitCopy (CodeGenFunction &CGF, Address DestField,
2300
+ Address SrcField) override {
2301
+ CGF.EmitPointerAuthCopy (VarType.getPointerAuth (), VarType, DestField,
2302
+ SrcField);
2303
+ }
2304
+
2305
+ bool needsDispose () const override { return false ; }
2306
+ void emitDispose (CodeGenFunction &CGF, Address Field) override {
2307
+ llvm_unreachable (" should never be called" );
2308
+ }
2309
+
2310
+ void profileImpl (llvm::FoldingSetNodeID &ID) const override {
2311
+ ID.AddPointer (VarType.getCanonicalType ().getAsOpaquePtr ());
2312
+ }
2313
+ };
2314
+
2264
2315
// / Emits the copy/dispose helpers for a __block variable that is a non-trivial
2265
2316
// / C struct.
2266
2317
class NonTrivialCStructByrefHelpers final : public BlockByrefHelpers {
@@ -2462,7 +2513,10 @@ CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,
2462
2513
return ::buildByrefHelpers (
2463
2514
CGM, byrefInfo, CXXByrefHelpers (valueAlignment, type, copyExpr));
2464
2515
}
2465
-
2516
+ if (type.hasAddressDiscriminatedPointerAuth ()) {
2517
+ return ::buildByrefHelpers (
2518
+ CGM, byrefInfo, AddressDiscriminatedByrefHelpers (valueAlignment, type));
2519
+ }
2466
2520
// If type is a non-trivial C struct type that is non-trivial to
2467
2521
// destructly move or destroy, build the copy and dispose helpers.
2468
2522
if (type.isNonTrivialToPrimitiveDestructiveMove () == QualType::PCK_Struct ||
0 commit comments