@@ -1591,6 +1591,10 @@ computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
15911591 return std::make_pair (BlockCaptureEntityKind::BlockObject, Flags);
15921592 }
15931593
1594+ if (T.hasAddressDiscriminatedPointerAuth ())
1595+ return std::make_pair (
1596+ BlockCaptureEntityKind::AddressDiscriminatedPointerAuth, Flags);
1597+
15941598 Flags = BLOCK_FIELD_IS_OBJECT;
15951599 bool isBlockPointer = T->isBlockPointerType ();
15961600 if (isBlockPointer)
@@ -1611,6 +1615,10 @@ computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
16111615 return std::make_pair (!isBlockPointer ? BlockCaptureEntityKind::ARCStrong
16121616 : BlockCaptureEntityKind::BlockObject,
16131617 Flags);
1618+ case QualType::PCK_PtrAuth:
1619+ return std::make_pair (
1620+ BlockCaptureEntityKind::AddressDiscriminatedPointerAuth,
1621+ BlockFieldFlags ());
16141622 case QualType::PCK_Trivial:
16151623 case QualType::PCK_VolatileTrivial: {
16161624 if (!T->isObjCRetainableType ())
@@ -1713,6 +1721,13 @@ static std::string getBlockCaptureStr(const CGBlockInfo::Capture &Cap,
17131721 case BlockCaptureEntityKind::ARCStrong:
17141722 Str += " s" ;
17151723 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+ }
17161731 case BlockCaptureEntityKind::BlockObject: {
17171732 const VarDecl *Var = CI.getVariable ();
17181733 unsigned F = Flags.getBitMask ();
@@ -1829,6 +1844,7 @@ static void pushCaptureCleanup(BlockCaptureEntityKind CaptureKind,
18291844 }
18301845 break ;
18311846 }
1847+ case BlockCaptureEntityKind::AddressDiscriminatedPointerAuth:
18321848 case BlockCaptureEntityKind::None:
18331849 break ;
18341850 }
@@ -1925,6 +1941,14 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
19251941 case BlockCaptureEntityKind::ARCWeak:
19261942 EmitARCCopyWeak (dstField, srcField);
19271943 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+ }
19281952 case BlockCaptureEntityKind::NonTrivialCStruct: {
19291953 // If this is a C struct that requires non-trivial copy construction,
19301954 // emit a call to its copy constructor.
@@ -2261,6 +2285,33 @@ class CXXByrefHelpers final : public BlockByrefHelpers {
22612285 }
22622286};
22632287
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+
22642315// / Emits the copy/dispose helpers for a __block variable that is a non-trivial
22652316// / C struct.
22662317class NonTrivialCStructByrefHelpers final : public BlockByrefHelpers {
@@ -2462,7 +2513,10 @@ CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,
24622513 return ::buildByrefHelpers (
24632514 CGM, byrefInfo, CXXByrefHelpers (valueAlignment, type, copyExpr));
24642515 }
2465-
2516+ if (type.hasAddressDiscriminatedPointerAuth ()) {
2517+ return ::buildByrefHelpers (
2518+ CGM, byrefInfo, AddressDiscriminatedByrefHelpers (valueAlignment, type));
2519+ }
24662520 // If type is a non-trivial C struct type that is non-trivial to
24672521 // destructly move or destroy, build the copy and dispose helpers.
24682522 if (type.isNonTrivialToPrimitiveDestructiveMove () == QualType::PCK_Struct ||
0 commit comments