@@ -188,13 +188,14 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM,
188188 // Optional copy/dispose helpers.
189189 bool hasInternalHelper = false ;
190190 if (blockInfo.NeedsCopyDispose ) {
191+ auto &Schema = CGM.getCodeGenOpts ().PointerAuth .BlockHelperFunctionPointers ;
191192 // copy_func_helper_decl
192193 llvm::Constant *copyHelper = buildCopyHelper (CGM, blockInfo);
193- elements.add (copyHelper);
194+ elements.addSignedPointer (copyHelper, Schema, GlobalDecl (), QualType () );
194195
195196 // destroy_func_decl
196197 llvm::Constant *disposeHelper = buildDisposeHelper (CGM, blockInfo);
197- elements.add (disposeHelper);
198+ elements.addSignedPointer (disposeHelper, Schema, GlobalDecl (), QualType () );
198199
199200 if (cast<llvm::Function>(copyHelper->stripPointerCasts ())
200201 ->hasInternalLinkage () ||
@@ -567,9 +568,8 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
567568 llvm::StructType::get (CGM.getLLVMContext (), elementTypes, true );
568569 info.CanBeGlobal = true ;
569570 return ;
570- }
571- else if (C.getLangOpts ().ObjC &&
572- CGM.getLangOpts ().getGC () == LangOptions::NonGC)
571+ } else if (C.getLangOpts ().ObjC &&
572+ CGM.getLangOpts ().getGC () == LangOptions::NonGC)
573573 info.HasCapturedVariableLayout = true ;
574574
575575 if (block->doesNotEscape ())
@@ -783,7 +783,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) {
783783
784784llvm::Value *CodeGenFunction::EmitBlockLiteral (const CGBlockInfo &blockInfo) {
785785 bool IsOpenCL = CGM.getContext ().getLangOpts ().OpenCL ;
786- auto GenVoidPtrTy =
786+ llvm::PointerType * GenVoidPtrTy =
787787 IsOpenCL ? CGM.getOpenCLRuntime ().getGenericVoidPointerType () : VoidPtrTy;
788788 LangAS GenVoidPtrAddr = IsOpenCL ? LangAS::opencl_generic : LangAS::Default;
789789 auto GenVoidPtrSize = CharUnits::fromQuantity (
@@ -817,9 +817,6 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
817817 : CGM.getNSConcreteStackBlock ();
818818 isa = blockISA;
819819
820- // Build the block descriptor.
821- descriptor = buildBlockDescriptor (CGM, blockInfo);
822-
823820 // Compute the initial on-stack block flags.
824821 if (!CGM.getCodeGenOpts ().DisableBlockSignatureString )
825822 flags = BLOCK_HAS_SIGNATURE;
@@ -833,6 +830,9 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
833830 flags |= BLOCK_USE_STRET;
834831 if (blockInfo.NoEscape )
835832 flags |= BLOCK_IS_NOESCAPE | BLOCK_IS_GLOBAL;
833+
834+ // Build the block descriptor.
835+ descriptor = buildBlockDescriptor (CGM, blockInfo);
836836 }
837837
838838 auto projectField = [&](unsigned index, const Twine &name) -> Address {
@@ -883,19 +883,34 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
883883 llvm::ConstantInt::get (IntTy, blockInfo.BlockAlign .getQuantity ()),
884884 getIntSize (), " block.align" );
885885 }
886- addHeaderField (blockFn, GenVoidPtrSize, " block.invoke" );
887- if (!IsOpenCL)
888- addHeaderField (descriptor, getPointerSize (), " block.descriptor" );
889- else if (auto *Helper =
890- CGM.getTargetCodeGenInfo ().getTargetOpenCLBlockHelper ()) {
886+
887+ if (!IsOpenCL) {
888+ llvm::Value *blockFnPtr =
889+ llvm::ConstantExpr::getBitCast (InvokeFn, VoidPtrTy);
890+ QualType type = blockInfo.getBlockExpr ()
891+ ->getType ()
892+ ->castAs <BlockPointerType>()
893+ ->getPointeeType ();
894+ addSignedHeaderField (
895+ blockFnPtr,
896+ CGM.getCodeGenOpts ().PointerAuth .BlockInvocationFunctionPointers ,
897+ GlobalDecl (), type, getPointerSize (), " block.invoke" );
898+
899+ addSignedHeaderField (
900+ descriptor, CGM.getCodeGenOpts ().PointerAuth .BlockDescriptorPointers ,
901+ GlobalDecl (), type, getPointerSize (), " block.descriptor" );
902+ } else if (auto *Helper =
903+ CGM.getTargetCodeGenInfo ().getTargetOpenCLBlockHelper ()) {
904+ addHeaderField (blockFn, GenVoidPtrSize, " block.invoke" );
891905 for (auto I : Helper->getCustomFieldValues (*this , blockInfo)) {
892906 addHeaderField (
893907 I.first ,
894908 CharUnits::fromQuantity (
895909 CGM.getDataLayout ().getTypeAllocSize (I.first ->getType ())),
896910 I.second );
897911 }
898- }
912+ } else
913+ addHeaderField (blockFn, GenVoidPtrSize, " block.invoke" );
899914 }
900915
901916 // Finally, capture all the values into the block.
@@ -1166,6 +1181,8 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
11661181 ASTContext &Ctx = getContext ();
11671182 CallArgList Args;
11681183
1184+ llvm::Value *FuncPtr = nullptr ;
1185+
11691186 if (getLangOpts ().OpenCL ) {
11701187 // For OpenCL, BlockPtr is already casted to generic block literal.
11711188
@@ -1185,7 +1202,7 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
11851202 if (!isa<ParmVarDecl>(E->getCalleeDecl ()))
11861203 Func = CGM.getOpenCLRuntime ().getInvokeFunction (E->getCallee ());
11871204 else {
1188- llvm::Value * FuncPtr = Builder.CreateStructGEP (GenBlockTy, BlockPtr, 2 );
1205+ FuncPtr = Builder.CreateStructGEP (GenBlockTy, BlockPtr, 2 );
11891206 Func = Builder.CreateAlignedLoad (GenericVoidPtrTy, FuncPtr,
11901207 getPointerAlign ());
11911208 }
@@ -1194,7 +1211,7 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
11941211 BlockPtr =
11951212 Builder.CreatePointerCast (BlockPtr, UnqualPtrTy, " block.literal" );
11961213 // Get pointer to the block invoke function
1197- llvm::Value * FuncPtr = Builder.CreateStructGEP (GenBlockTy, BlockPtr, 3 );
1214+ FuncPtr = Builder.CreateStructGEP (GenBlockTy, BlockPtr, 3 );
11981215
11991216 // First argument is a block literal casted to a void pointer
12001217 BlockPtr = Builder.CreatePointerCast (BlockPtr, VoidPtrTy);
@@ -1211,7 +1228,15 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
12111228 CGM.getTypes ().arrangeBlockFunctionCall (Args, FuncTy);
12121229
12131230 // Prepare the callee.
1214- CGCallee Callee (CGCalleeInfo (), Func);
1231+ CGPointerAuthInfo PointerAuth;
1232+ if (auto &AuthSchema =
1233+ CGM.getCodeGenOpts ().PointerAuth .BlockInvocationFunctionPointers ) {
1234+ assert (FuncPtr != nullptr && " Missing function pointer for AuthInfo" );
1235+ PointerAuth =
1236+ EmitPointerAuthInfo (AuthSchema, FuncPtr, GlobalDecl (), FnType);
1237+ }
1238+
1239+ CGCallee Callee (CGCalleeInfo (), Func, PointerAuth);
12151240
12161241 // And call the block.
12171242 return EmitCall (FnInfo, Callee, ReturnValue, Args, CallOrInvoke);
@@ -1295,14 +1320,15 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
12951320
12961321 bool IsOpenCL = CGM.getLangOpts ().OpenCL ;
12971322 bool IsWindows = CGM.getTarget ().getTriple ().isOSWindows ();
1323+ auto &CGOPointerAuth = CGM.getCodeGenOpts ().PointerAuth ;
12981324 if (!IsOpenCL) {
12991325 // isa
13001326 if (IsWindows)
13011327 fields.addNullPointer (CGM.Int8PtrPtrTy );
13021328 else
13031329 fields.addSignedPointer (CGM.getNSConcreteGlobalBlock (),
1304- CGM. getCodeGenOpts (). PointerAuth . ObjCIsaPointers ,
1305- GlobalDecl (), QualType ());
1330+ CGOPointerAuth. ObjCIsaPointers , GlobalDecl () ,
1331+ QualType ());
13061332
13071333 // __flags
13081334 BlockFlags flags = BLOCK_IS_GLOBAL;
@@ -1321,11 +1347,20 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
13211347 }
13221348
13231349 // Function
1324- fields.add (blockFn);
1350+ if (auto &Schema = CGOPointerAuth.BlockInvocationFunctionPointers ) {
1351+ QualType FnType = blockInfo.getBlockExpr ()
1352+ ->getType ()
1353+ ->castAs <BlockPointerType>()
1354+ ->getPointeeType ();
1355+ fields.addSignedPointer (blockFn, Schema, GlobalDecl (), FnType);
1356+ } else
1357+ fields.add (blockFn);
13251358
13261359 if (!IsOpenCL) {
13271360 // Descriptor
1328- fields.add (buildBlockDescriptor (CGM, blockInfo));
1361+ llvm::Constant *Descriptor = buildBlockDescriptor (CGM, blockInfo);
1362+ fields.addSignedPointer (Descriptor, CGOPointerAuth.BlockDescriptorPointers ,
1363+ GlobalDecl (), QualType ());
13291364 } else if (auto *Helper =
13301365 CGM.getTargetCodeGenInfo ().getTargetOpenCLBlockHelper ()) {
13311366 for (auto *I : Helper->getCustomFieldValues (CGM, blockInfo)) {
@@ -1995,8 +2030,8 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
19952030 // it. It's not quite worth the annoyance to avoid creating it in the
19962031 // first place.
19972032 if (!needsEHCleanup (captureType.isDestructedType ()))
1998- if (auto *I =
1999- cast_or_null<llvm::Instruction>( dstField.getBasePointer ()))
2033+ if (auto *I = cast_or_null<llvm::Instruction>(
2034+ dstField.getPointerIfNotSigned ()))
20002035 I->eraseFromParent ();
20012036 }
20022037 break ;
@@ -2730,8 +2765,16 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {
27302765 unsigned nextHeaderIndex = 0 ;
27312766 CharUnits nextHeaderOffset;
27322767 auto storeHeaderField = [&](llvm::Value *value, CharUnits fieldSize,
2733- const Twine &name) {
2768+ const Twine &name, bool isFunction = false ) {
27342769 auto fieldAddr = Builder.CreateStructGEP (addr, nextHeaderIndex, name);
2770+ if (isFunction) {
2771+ if (auto &Schema = CGM.getCodeGenOpts ()
2772+ .PointerAuth .BlockByrefHelperFunctionPointers ) {
2773+ auto PointerAuth = EmitPointerAuthInfo (
2774+ Schema, fieldAddr.emitRawPointer (*this ), GlobalDecl (), QualType ());
2775+ value = EmitPointerAuthSign (PointerAuth, value);
2776+ }
2777+ }
27352778 Builder.CreateStore (value, fieldAddr);
27362779
27372780 nextHeaderIndex++;
@@ -2814,10 +2857,10 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {
28142857 storeHeaderField (V, getIntSize (), " byref.size" );
28152858
28162859 if (helpers) {
2817- storeHeaderField (helpers->CopyHelper , getPointerSize (),
2818- " byref.copyHelper " );
2860+ storeHeaderField (helpers->CopyHelper , getPointerSize (), " byref.copyHelper " ,
2861+ /* isFunction= */ true );
28192862 storeHeaderField (helpers->DisposeHelper , getPointerSize (),
2820- " byref.disposeHelper" );
2863+ " byref.disposeHelper" , /* isFunction= */ true );
28212864 }
28222865
28232866 if (ByRefHasLifetime && HasByrefExtendedLayout) {
0 commit comments