@@ -188,13 +188,14 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM,
188
188
// Optional copy/dispose helpers.
189
189
bool hasInternalHelper = false ;
190
190
if (blockInfo.NeedsCopyDispose ) {
191
+ auto &Schema = CGM.getCodeGenOpts ().PointerAuth .BlockHelperFunctionPointers ;
191
192
// copy_func_helper_decl
192
193
llvm::Constant *copyHelper = buildCopyHelper (CGM, blockInfo);
193
- elements.add (copyHelper);
194
+ elements.addSignedPointer (copyHelper, Schema, GlobalDecl (), QualType () );
194
195
195
196
// destroy_func_decl
196
197
llvm::Constant *disposeHelper = buildDisposeHelper (CGM, blockInfo);
197
- elements.add (disposeHelper);
198
+ elements.addSignedPointer (disposeHelper, Schema, GlobalDecl (), QualType () );
198
199
199
200
if (cast<llvm::Function>(copyHelper->stripPointerCasts ())
200
201
->hasInternalLinkage () ||
@@ -568,9 +569,8 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
568
569
llvm::StructType::get (CGM.getLLVMContext (), elementTypes, true );
569
570
info.CanBeGlobal = true ;
570
571
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)
574
574
info.HasCapturedVariableLayout = true ;
575
575
576
576
if (block->doesNotEscape ())
@@ -784,7 +784,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) {
784
784
785
785
llvm::Value *CodeGenFunction::EmitBlockLiteral (const CGBlockInfo &blockInfo) {
786
786
bool IsOpenCL = CGM.getContext ().getLangOpts ().OpenCL ;
787
- auto GenVoidPtrTy =
787
+ llvm::PointerType * GenVoidPtrTy =
788
788
IsOpenCL ? CGM.getOpenCLRuntime ().getGenericVoidPointerType () : VoidPtrTy;
789
789
LangAS GenVoidPtrAddr = IsOpenCL ? LangAS::opencl_generic : LangAS::Default;
790
790
auto GenVoidPtrSize = CharUnits::fromQuantity (
@@ -818,9 +818,6 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
818
818
: CGM.getNSConcreteStackBlock ();
819
819
isa = blockISA;
820
820
821
- // Build the block descriptor.
822
- descriptor = buildBlockDescriptor (CGM, blockInfo);
823
-
824
821
// Compute the initial on-stack block flags.
825
822
if (!CGM.getCodeGenOpts ().DisableBlockSignatureString )
826
823
flags = BLOCK_HAS_SIGNATURE;
@@ -834,6 +831,9 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
834
831
flags |= BLOCK_USE_STRET;
835
832
if (blockInfo.NoEscape )
836
833
flags |= BLOCK_IS_NOESCAPE | BLOCK_IS_GLOBAL;
834
+
835
+ // Build the block descriptor.
836
+ descriptor = buildBlockDescriptor (CGM, blockInfo);
837
837
}
838
838
839
839
auto projectField = [&](unsigned index, const Twine &name) -> Address {
@@ -884,19 +884,34 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
884
884
llvm::ConstantInt::get (IntTy, blockInfo.BlockAlign .getQuantity ()),
885
885
getIntSize (), " block.align" );
886
886
}
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" );
892
906
for (auto I : Helper->getCustomFieldValues (*this , blockInfo)) {
893
907
addHeaderField (
894
908
I.first ,
895
909
CharUnits::fromQuantity (
896
910
CGM.getDataLayout ().getTypeAllocSize (I.first ->getType ())),
897
911
I.second );
898
912
}
899
- }
913
+ } else
914
+ addHeaderField (blockFn, GenVoidPtrSize, " block.invoke" );
900
915
}
901
916
902
917
// Finally, capture all the values into the block.
@@ -1167,6 +1182,8 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
1167
1182
ASTContext &Ctx = getContext ();
1168
1183
CallArgList Args;
1169
1184
1185
+ llvm::Value *FuncPtr = nullptr ;
1186
+
1170
1187
if (getLangOpts ().OpenCL ) {
1171
1188
// For OpenCL, BlockPtr is already casted to generic block literal.
1172
1189
@@ -1186,7 +1203,7 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
1186
1203
if (!isa<ParmVarDecl>(E->getCalleeDecl ()))
1187
1204
Func = CGM.getOpenCLRuntime ().getInvokeFunction (E->getCallee ());
1188
1205
else {
1189
- llvm::Value * FuncPtr = Builder.CreateStructGEP (GenBlockTy, BlockPtr, 2 );
1206
+ FuncPtr = Builder.CreateStructGEP (GenBlockTy, BlockPtr, 2 );
1190
1207
Func = Builder.CreateAlignedLoad (GenericVoidPtrTy, FuncPtr,
1191
1208
getPointerAlign ());
1192
1209
}
@@ -1195,7 +1212,7 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
1195
1212
BlockPtr =
1196
1213
Builder.CreatePointerCast (BlockPtr, UnqualPtrTy, " block.literal" );
1197
1214
// Get pointer to the block invoke function
1198
- llvm::Value * FuncPtr = Builder.CreateStructGEP (GenBlockTy, BlockPtr, 3 );
1215
+ FuncPtr = Builder.CreateStructGEP (GenBlockTy, BlockPtr, 3 );
1199
1216
1200
1217
// First argument is a block literal casted to a void pointer
1201
1218
BlockPtr = Builder.CreatePointerCast (BlockPtr, VoidPtrTy);
@@ -1212,7 +1229,15 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
1212
1229
CGM.getTypes ().arrangeBlockFunctionCall (Args, FuncTy);
1213
1230
1214
1231
// 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);
1216
1241
1217
1242
// And call the block.
1218
1243
return EmitCall (FnInfo, Callee, ReturnValue, Args, CallOrInvoke);
@@ -1296,14 +1321,15 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
1296
1321
1297
1322
bool IsOpenCL = CGM.getLangOpts ().OpenCL ;
1298
1323
bool IsWindows = CGM.getTarget ().getTriple ().isOSWindows ();
1324
+ auto &CGOPointerAuth = CGM.getCodeGenOpts ().PointerAuth ;
1299
1325
if (!IsOpenCL) {
1300
1326
// isa
1301
1327
if (IsWindows)
1302
1328
fields.addNullPointer (CGM.Int8PtrPtrTy );
1303
1329
else
1304
1330
fields.addSignedPointer (CGM.getNSConcreteGlobalBlock (),
1305
- CGM. getCodeGenOpts (). PointerAuth . ObjCIsaPointers ,
1306
- GlobalDecl (), QualType ());
1331
+ CGOPointerAuth. ObjCIsaPointers , GlobalDecl () ,
1332
+ QualType ());
1307
1333
1308
1334
// __flags
1309
1335
BlockFlags flags = BLOCK_IS_GLOBAL;
@@ -1322,11 +1348,20 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
1322
1348
}
1323
1349
1324
1350
// 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);
1326
1359
1327
1360
if (!IsOpenCL) {
1328
1361
// Descriptor
1329
- fields.add (buildBlockDescriptor (CGM, blockInfo));
1362
+ llvm::Constant *Descriptor = buildBlockDescriptor (CGM, blockInfo);
1363
+ fields.addSignedPointer (Descriptor, CGOPointerAuth.BlockDescriptorPointers ,
1364
+ GlobalDecl (), QualType ());
1330
1365
} else if (auto *Helper =
1331
1366
CGM.getTargetCodeGenInfo ().getTargetOpenCLBlockHelper ()) {
1332
1367
for (auto *I : Helper->getCustomFieldValues (CGM, blockInfo)) {
@@ -1996,8 +2031,8 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
1996
2031
// it. It's not quite worth the annoyance to avoid creating it in the
1997
2032
// first place.
1998
2033
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 ()))
2001
2036
I->eraseFromParent ();
2002
2037
}
2003
2038
break ;
@@ -2731,8 +2766,16 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {
2731
2766
unsigned nextHeaderIndex = 0 ;
2732
2767
CharUnits nextHeaderOffset;
2733
2768
auto storeHeaderField = [&](llvm::Value *value, CharUnits fieldSize,
2734
- const Twine &name) {
2769
+ const Twine &name, bool isFunction = false ) {
2735
2770
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
+ }
2736
2779
Builder.CreateStore (value, fieldAddr);
2737
2780
2738
2781
nextHeaderIndex++;
@@ -2815,10 +2858,10 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {
2815
2858
storeHeaderField (V, getIntSize (), " byref.size" );
2816
2859
2817
2860
if (helpers) {
2818
- storeHeaderField (helpers->CopyHelper , getPointerSize (),
2819
- " byref.copyHelper " );
2861
+ storeHeaderField (helpers->CopyHelper , getPointerSize (), " byref.copyHelper " ,
2862
+ /* isFunction= */ true );
2820
2863
storeHeaderField (helpers->DisposeHelper , getPointerSize (),
2821
- " byref.disposeHelper" );
2864
+ " byref.disposeHelper" , /* isFunction= */ true );
2822
2865
}
2823
2866
2824
2867
if (ByRefHasLifetime && HasByrefExtendedLayout) {
0 commit comments