@@ -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 () ||
@@ -568,9 +569,8 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
568569 llvm::StructType::get (CGM.getLLVMContext (), elementTypes, true );
569570 info.CanBeGlobal = true ;
570571 return ;
571- }
572- else if (C.getLangOpts ().ObjC &&
573- CGM.getLangOpts ().getGC () == LangOptions::NonGC)
572+ } else if (C.getLangOpts ().ObjC &&
573+ CGM.getLangOpts ().getGC () == LangOptions::NonGC)
574574 info.HasCapturedVariableLayout = true ;
575575
576576 if (block->doesNotEscape ())
@@ -784,7 +784,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) {
784784
785785llvm::Value *CodeGenFunction::EmitBlockLiteral (const CGBlockInfo &blockInfo) {
786786 bool IsOpenCL = CGM.getContext ().getLangOpts ().OpenCL ;
787- auto GenVoidPtrTy =
787+ llvm::PointerType * GenVoidPtrTy =
788788 IsOpenCL ? CGM.getOpenCLRuntime ().getGenericVoidPointerType () : VoidPtrTy;
789789 LangAS GenVoidPtrAddr = IsOpenCL ? LangAS::opencl_generic : LangAS::Default;
790790 auto GenVoidPtrSize = CharUnits::fromQuantity (
@@ -818,9 +818,6 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
818818 : CGM.getNSConcreteStackBlock ();
819819 isa = blockISA;
820820
821- // Build the block descriptor.
822- descriptor = buildBlockDescriptor (CGM, blockInfo);
823-
824821 // Compute the initial on-stack block flags.
825822 if (!CGM.getCodeGenOpts ().DisableBlockSignatureString )
826823 flags = BLOCK_HAS_SIGNATURE;
@@ -834,6 +831,9 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
834831 flags |= BLOCK_USE_STRET;
835832 if (blockInfo.NoEscape )
836833 flags |= BLOCK_IS_NOESCAPE | BLOCK_IS_GLOBAL;
834+
835+ // Build the block descriptor.
836+ descriptor = buildBlockDescriptor (CGM, blockInfo);
837837 }
838838
839839 auto projectField = [&](unsigned index, const Twine &name) -> Address {
@@ -884,19 +884,34 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
884884 llvm::ConstantInt::get (IntTy, blockInfo.BlockAlign .getQuantity ()),
885885 getIntSize (), " block.align" );
886886 }
887- addHeaderField (blockFn, GenVoidPtrSize, " block.invoke" );
888- if (!IsOpenCL)
889- addHeaderField (descriptor, getPointerSize (), " block.descriptor" );
890- else if (auto *Helper =
891- CGM.getTargetCodeGenInfo ().getTargetOpenCLBlockHelper ()) {
887+
888+ if (!IsOpenCL) {
889+ llvm::Value *blockFnPtr =
890+ llvm::ConstantExpr::getBitCast (InvokeFn, VoidPtrTy);
891+ QualType type = blockInfo.getBlockExpr ()
892+ ->getType ()
893+ ->castAs <BlockPointerType>()
894+ ->getPointeeType ();
895+ addSignedHeaderField (
896+ blockFnPtr,
897+ CGM.getCodeGenOpts ().PointerAuth .BlockInvocationFunctionPointers ,
898+ GlobalDecl (), type, getPointerSize (), " block.invoke" );
899+
900+ addSignedHeaderField (
901+ descriptor, CGM.getCodeGenOpts ().PointerAuth .BlockDescriptorPointers ,
902+ GlobalDecl (), type, getPointerSize (), " block.descriptor" );
903+ } else if (auto *Helper =
904+ CGM.getTargetCodeGenInfo ().getTargetOpenCLBlockHelper ()) {
905+ addHeaderField (blockFn, GenVoidPtrSize, " block.invoke" );
892906 for (auto I : Helper->getCustomFieldValues (*this , blockInfo)) {
893907 addHeaderField (
894908 I.first ,
895909 CharUnits::fromQuantity (
896910 CGM.getDataLayout ().getTypeAllocSize (I.first ->getType ())),
897911 I.second );
898912 }
899- }
913+ } else
914+ addHeaderField (blockFn, GenVoidPtrSize, " block.invoke" );
900915 }
901916
902917 // Finally, capture all the values into the block.
@@ -1167,6 +1182,8 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
11671182 ASTContext &Ctx = getContext ();
11681183 CallArgList Args;
11691184
1185+ llvm::Value *FuncPtr = nullptr ;
1186+
11701187 if (getLangOpts ().OpenCL ) {
11711188 // For OpenCL, BlockPtr is already casted to generic block literal.
11721189
@@ -1186,7 +1203,7 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
11861203 if (!isa<ParmVarDecl>(E->getCalleeDecl ()))
11871204 Func = CGM.getOpenCLRuntime ().getInvokeFunction (E->getCallee ());
11881205 else {
1189- llvm::Value * FuncPtr = Builder.CreateStructGEP (GenBlockTy, BlockPtr, 2 );
1206+ FuncPtr = Builder.CreateStructGEP (GenBlockTy, BlockPtr, 2 );
11901207 Func = Builder.CreateAlignedLoad (GenericVoidPtrTy, FuncPtr,
11911208 getPointerAlign ());
11921209 }
@@ -1195,7 +1212,7 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
11951212 BlockPtr =
11961213 Builder.CreatePointerCast (BlockPtr, UnqualPtrTy, " block.literal" );
11971214 // Get pointer to the block invoke function
1198- llvm::Value * FuncPtr = Builder.CreateStructGEP (GenBlockTy, BlockPtr, 3 );
1215+ FuncPtr = Builder.CreateStructGEP (GenBlockTy, BlockPtr, 3 );
11991216
12001217 // First argument is a block literal casted to a void pointer
12011218 BlockPtr = Builder.CreatePointerCast (BlockPtr, VoidPtrTy);
@@ -1212,7 +1229,15 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
12121229 CGM.getTypes ().arrangeBlockFunctionCall (Args, FuncTy);
12131230
12141231 // Prepare the callee.
1215- CGCallee Callee (CGCalleeInfo (), Func);
1232+ CGPointerAuthInfo PointerAuth;
1233+ if (auto &AuthSchema =
1234+ CGM.getCodeGenOpts ().PointerAuth .BlockInvocationFunctionPointers ) {
1235+ assert (FuncPtr != nullptr && " Missing function pointer for AuthInfo" );
1236+ PointerAuth =
1237+ EmitPointerAuthInfo (AuthSchema, FuncPtr, GlobalDecl (), FnType);
1238+ }
1239+
1240+ CGCallee Callee (CGCalleeInfo (), Func, PointerAuth);
12161241
12171242 // And call the block.
12181243 return EmitCall (FnInfo, Callee, ReturnValue, Args, CallOrInvoke);
@@ -1296,14 +1321,15 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
12961321
12971322 bool IsOpenCL = CGM.getLangOpts ().OpenCL ;
12981323 bool IsWindows = CGM.getTarget ().getTriple ().isOSWindows ();
1324+ auto &CGOPointerAuth = CGM.getCodeGenOpts ().PointerAuth ;
12991325 if (!IsOpenCL) {
13001326 // isa
13011327 if (IsWindows)
13021328 fields.addNullPointer (CGM.Int8PtrPtrTy );
13031329 else
13041330 fields.addSignedPointer (CGM.getNSConcreteGlobalBlock (),
1305- CGM. getCodeGenOpts (). PointerAuth . ObjCIsaPointers ,
1306- GlobalDecl (), QualType ());
1331+ CGOPointerAuth. ObjCIsaPointers , GlobalDecl () ,
1332+ QualType ());
13071333
13081334 // __flags
13091335 BlockFlags flags = BLOCK_IS_GLOBAL;
@@ -1322,11 +1348,20 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
13221348 }
13231349
13241350 // Function
1325- fields.add (blockFn);
1351+ if (auto &Schema = CGOPointerAuth.BlockInvocationFunctionPointers ) {
1352+ QualType FnType = blockInfo.getBlockExpr ()
1353+ ->getType ()
1354+ ->castAs <BlockPointerType>()
1355+ ->getPointeeType ();
1356+ fields.addSignedPointer (blockFn, Schema, GlobalDecl (), FnType);
1357+ } else
1358+ fields.add (blockFn);
13261359
13271360 if (!IsOpenCL) {
13281361 // Descriptor
1329- fields.add (buildBlockDescriptor (CGM, blockInfo));
1362+ llvm::Constant *Descriptor = buildBlockDescriptor (CGM, blockInfo);
1363+ fields.addSignedPointer (Descriptor, CGOPointerAuth.BlockDescriptorPointers ,
1364+ GlobalDecl (), QualType ());
13301365 } else if (auto *Helper =
13311366 CGM.getTargetCodeGenInfo ().getTargetOpenCLBlockHelper ()) {
13321367 for (auto *I : Helper->getCustomFieldValues (CGM, blockInfo)) {
@@ -1996,8 +2031,8 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
19962031 // it. It's not quite worth the annoyance to avoid creating it in the
19972032 // first place.
19982033 if (!needsEHCleanup (captureType.isDestructedType ()))
1999- if (auto *I =
2000- cast_or_null<llvm::Instruction>( dstField.getBasePointer ()))
2034+ if (auto *I = cast_or_null<llvm::Instruction>(
2035+ dstField.getPointerIfNotSigned ()))
20012036 I->eraseFromParent ();
20022037 }
20032038 break ;
@@ -2731,8 +2766,16 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {
27312766 unsigned nextHeaderIndex = 0 ;
27322767 CharUnits nextHeaderOffset;
27332768 auto storeHeaderField = [&](llvm::Value *value, CharUnits fieldSize,
2734- const Twine &name) {
2769+ const Twine &name, bool isFunction = false ) {
27352770 auto fieldAddr = Builder.CreateStructGEP (addr, nextHeaderIndex, name);
2771+ if (isFunction) {
2772+ if (auto &Schema = CGM.getCodeGenOpts ()
2773+ .PointerAuth .BlockByrefHelperFunctionPointers ) {
2774+ auto PointerAuth = EmitPointerAuthInfo (
2775+ Schema, fieldAddr.emitRawPointer (*this ), GlobalDecl (), QualType ());
2776+ value = EmitPointerAuthSign (PointerAuth, value);
2777+ }
2778+ }
27362779 Builder.CreateStore (value, fieldAddr);
27372780
27382781 nextHeaderIndex++;
@@ -2815,10 +2858,10 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {
28152858 storeHeaderField (V, getIntSize (), " byref.size" );
28162859
28172860 if (helpers) {
2818- storeHeaderField (helpers->CopyHelper , getPointerSize (),
2819- " byref.copyHelper " );
2861+ storeHeaderField (helpers->CopyHelper , getPointerSize (), " byref.copyHelper " ,
2862+ /* isFunction= */ true );
28202863 storeHeaderField (helpers->DisposeHelper , getPointerSize (),
2821- " byref.disposeHelper" );
2864+ " byref.disposeHelper" , /* isFunction= */ true );
28222865 }
28232866
28242867 if (ByRefHasLifetime && HasByrefExtendedLayout) {
0 commit comments