https://github.com/ahatanak updated https://github.com/llvm/llvm-project/pull/191091
>From 432c8c57a5ed4f06c97b18e1627b3991cf436d34 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka <[email protected]> Date: Wed, 8 Apr 2026 16:28:46 -0700 Subject: [PATCH 1/2] [ObjC] Fix missing ptrauth signing of isa in constant ObjC literals 154d2267b897 added support for emitting ObjC number, array, and dictionary literals as constants, but did not sign the class pointer fields in NSConstantIntegerNumber, NSConstantFloatNumber, NSConstantDoubleNumber, NSConstantArray, and NSConstantDictionary structs with the ObjCIsaPointers ptrauth schema on arm64e. Fix this by using addSignedPointer instead of add when emitting those fields. Also improves and adds comments to the GenerateConstantNS* functions in CGObjCMac.cpp. rdar://174359070 --- clang/lib/CodeGen/CGObjCMac.cpp | 62 ++++++++++++------- .../objc2-constant-literals-ptrauth.m | 32 ++++++++++ 2 files changed, 71 insertions(+), 23 deletions(-) create mode 100644 clang/test/CodeGenObjC/objc2-constant-literals-ptrauth.m diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index eeb61a6b12eb1..2a822a4132726 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -2285,7 +2285,7 @@ CGObjCCommonMac::GenerateConstantNSString(const StringLiteral *Literal) { // String length. Fields.addInt(CGM.IntTy, StringLength); - // The struct. + // The struct CharUnits Alignment = CGM.getPointerAlign(); GV = Fields.finishAndCreateGlobal("_unnamed_nsstring_", Alignment, /*constant*/ true, @@ -2302,7 +2302,7 @@ CGObjCCommonMac::GenerateConstantNSString(const StringLiteral *Literal) { return ConstantAddress(GV, GV->getValueType(), Alignment); } -/// Emit the boolean singletons for BOOL literals @YES @NO +/// Emit the boolean singletons for BOOL literals @YES and @NO. ConstantAddress CGObjCCommonMac::GenerateConstantNSNumber(const bool Value, const QualType &Ty) { llvm::GlobalVariable *Val = @@ -2310,7 +2310,8 @@ ConstantAddress CGObjCCommonMac::GenerateConstantNSNumber(const bool Value, return ConstantAddress(Val, Val->getValueType(), CGM.getPointerAlign()); } -/// Generate a constant NSConstantIntegerNumber from an ObjC integer literal +/// Generate a constant NSConstantIntegerNumber from an ObjC integer literal e.x +/// @2. /* struct __builtin_NSConstantIntegerNumber { struct._class_t *isa; // point to _NSConstantIntegerNumberClassReference @@ -2323,14 +2324,14 @@ CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APSInt &Value, const QualType &Ty) { CharUnits Alignment = CGM.getPointerAlign(); - // check if we've already emitted, if so emit a reference to it + // Check if we've already emitted, if so emit a reference to it. llvm::GlobalVariable *&Entry = NSConstantNumberMap[{CGM.getContext().getCanonicalType(Ty), Value}]; if (Entry) { return ConstantAddress(Entry, Entry->getValueType(), Alignment); } - // The encoding type + // The encoding type. std::string ObjCEncodingType; CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty, ObjCEncodingType); @@ -2351,9 +2352,11 @@ CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APSInt &Value, auto Fields = Builder.beginStruct(NSConstantIntegerNumberType); // Class pointer. - Fields.add(Class); + Fields.addSignedPointer(Class, + CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers, + GlobalDecl(), QualType()); - // add the @encode + // add the @encode. Fields.add(CGM.GetAddrOfConstantCString(ObjCEncodingType).getPointer()); // add the value stored. @@ -2376,14 +2379,16 @@ CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APSInt &Value, } /// Generate either a constant NSConstantFloatNumber or NSConstantDoubleNumber +/// from an ObjC literal based on it's encoding. @(2.2f) would be +/// NSConstantFloatNumber. @(2.222) would be NSConstantDoubleNumber. /* struct __builtin_NSConstantFloatNumber { - struct._class_t *isa; + struct._class_t *isa; // point to _NSConstantFloatNumberClassReference float const _value; }; struct __builtin_NSConstantDoubleNumber { - struct._class_t *isa; + struct._class_t *isa; // point to _NSConstantDoubleNumberClassReference double const _value; }; */ @@ -2392,14 +2397,14 @@ CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APFloat &Value, const QualType &Ty) { CharUnits Alignment = CGM.getPointerAlign(); - // check if we've already emitted, if so emit a reference to it + // Check if we've already emitted, if so emit a reference to it. llvm::GlobalVariable *&Entry = NSConstantNumberMap[{CGM.getContext().getCanonicalType(Ty), Value}]; if (Entry) { return ConstantAddress(Entry, Entry->getValueType(), Alignment); } - // @encode type used to pick which class type to use + // @encode type used to pick which class type to use. std::string ObjCEncodingType; CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty, ObjCEncodingType); @@ -2410,7 +2415,7 @@ CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APFloat &Value, llvm::GlobalValue::LinkageTypes Linkage = llvm::GlobalVariable::PrivateLinkage; - // Handle floats + // Handle floats. if (ObjCEncodingType == "f") { llvm::Constant *const Class = getNSConstantFloatNumberClassRef(); @@ -2427,7 +2432,9 @@ CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APFloat &Value, auto Fields = Builder.beginStruct(NSConstantFloatNumberType); // Class pointer. - Fields.add(Class); + Fields.addSignedPointer(Class, + CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers, + GlobalDecl(), QualType()); // add the value stored. llvm::Constant *FV = llvm::ConstantFP::get(CGM.FloatTy, Value); @@ -2448,7 +2455,7 @@ CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APFloat &Value, llvm::Constant *const Class = getNSConstantDoubleNumberClassRef(); if (!NSConstantDoubleNumberType) { - // NOTE: this will be padded on some 32-bit targets and is expected + // NOTE: this will be padded on some 32-bit targets and is expected. NSConstantDoubleNumberType = llvm::StructType::create( { CGM.DefaultPtrTy, // isa @@ -2461,7 +2468,9 @@ CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APFloat &Value, auto Fields = Builder.beginStruct(NSConstantDoubleNumberType); // Class pointer. - Fields.add(Class); + Fields.addSignedPointer(Class, + CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers, + GlobalDecl(), QualType()); // add the value stored. llvm::Constant *DV = llvm::ConstantFP::get(CGM.DoubleTy, Value); @@ -2481,7 +2490,7 @@ CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APFloat &Value, } /// Shared private method to emit the id array storage for constant NSArray and -/// NSDictionary literals +/// NSDictionary literals as they share the same sections and behavior. llvm::GlobalVariable * CGObjCCommonMac::EmitNSConstantCollectionLiteralArrayStorage( const ArrayRef<llvm::Constant *> &Elements) { @@ -2500,10 +2509,11 @@ CGObjCCommonMac::EmitNSConstantCollectionLiteralArrayStorage( return ObjectsGV; } -/// Generate a constant NSConstantArray from an ObjC array literal +/// Generate a constant NSConstantArray from an ObjC array literal, +/// e.x @[ @2 ] or the singleton for an empty `__NSArray0__struct`. /* struct __builtin_NSArray { - struct._class_t *isa; + struct._class_t *isa; // points to _NSConstantArrayClassReference NSUInteger const _count; id const *const _objects; }; @@ -2537,7 +2547,9 @@ ConstantAddress CGObjCCommonMac::GenerateConstantNSArray( auto Fields = Builder.beginStruct(NSConstantArrayType); // Class pointer. - Fields.add(Class); + Fields.addSignedPointer(Class, + CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers, + GlobalDecl(), QualType()); // count uint64_t ObjectCount = Objects.size(); @@ -2561,9 +2573,11 @@ ConstantAddress CGObjCCommonMac::GenerateConstantNSArray( } /// Generate a constant NSConstantDictionary from an ObjC dictionary literal +/// with string keys, e.x @{ @"someNum" : @2 } or the singleton for an empty +/// `__NSDictionary0__struct`. /* struct __builtin_NSDictionary { - struct._class_t *isa; + struct._class_t *isa; // point to _NSConstantDictionaryClassReference NSUInteger const _hashOptions; NSUInteger const _count; id const *const _keys; @@ -2603,13 +2617,15 @@ ConstantAddress CGObjCCommonMac::GenerateConstantNSDictionary( auto Fields = Builder.beginStruct(NSConstantDictionaryType); // Class pointer. - Fields.add(Class); + Fields.addSignedPointer(Class, + CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers, + GlobalDecl(), QualType()); - // Use the hashing helper to manage the keys and sorting + // Use the hashing helper to manage the keys and sorting. auto HashOpts(NSDictionaryBuilder::Options::Sorted); NSDictionaryBuilder DictBuilder(E, KeysAndObjects, HashOpts); - // Ask `HashBuilder` for the fully sorted keys / values and the count + // Ask `HashBuilder` for the fully sorted keys / values and the count. uint64_t const NumElements = DictBuilder.getNumElements(); llvm::Constant *OptionsConstant = llvm::ConstantInt::get( diff --git a/clang/test/CodeGenObjC/objc2-constant-literals-ptrauth.m b/clang/test/CodeGenObjC/objc2-constant-literals-ptrauth.m new file mode 100644 index 0000000000000..b62416a4e1112 --- /dev/null +++ b/clang/test/CodeGenObjC/objc2-constant-literals-ptrauth.m @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple arm64e-apple-macosx26.0.0 -fobjc-runtime=macosx-26.0.0 -fobjc-constant-literals -fconstant-nsnumber-literals -fconstant-nsarray-literals -fconstant-nsdictionary-literals -fptrauth-intrinsics -fptrauth-calls -fptrauth-objc-isa -I %S/Inputs -emit-llvm -o - %s | FileCheck %s +// rdar://174359070 + +#include "constant-literal-support.h" + +#if __has_feature(objc_bool) +#define YES __objc_yes +#define NO __objc_no +#else +#define YES ((BOOL)1) +#define NO ((BOOL)0) +#endif + +// Check that isa pointers in all ObjC constant literal structs are signed with +// ptrauth (key 2, discriminator 0x6AE1 = 27361, address-discriminated). + +// CHECK: @_unnamed_nsconstantintegernumber_ = private constant %struct.__builtin_NSConstantIntegerNumber { ptr ptrauth (ptr @"OBJC_CLASS_$_NSConstantIntegerNumber", i32 2, i64 27361, ptr @_unnamed_nsconstantintegernumber_), ptr @.str, i64 42 } +// CHECK: @_unnamed_nsconstantfloatnumber_ = private constant %struct.__builtin_NSConstantFloatNumber { ptr ptrauth (ptr @"OBJC_CLASS_$_NSConstantFloatNumber", i32 2, i64 27361, ptr @_unnamed_nsconstantfloatnumber_) +// CHECK: @_unnamed_nsconstantdoublenumber_ = private constant %struct.__builtin_NSConstantDoubleNumber { ptr ptrauth (ptr @"OBJC_CLASS_$_NSConstantDoubleNumber", i32 2, i64 27361, ptr @_unnamed_nsconstantdoublenumber_) +// CHECK: @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { ptr ptrauth (ptr @__CFConstantStringClassReference, i32 2, i64 27361, ptr @_unnamed_cfstring_) +// CHECK: @_unnamed_nsarray_ = private constant %struct.__builtin_NSArray { ptr ptrauth (ptr @"OBJC_CLASS_$_NSConstantArray", i32 2, i64 27361, ptr @_unnamed_nsarray_) +// CHECK: @_unnamed_nsdictionary_ = private constant %struct.__builtin_NSDictionary { ptr ptrauth (ptr @"OBJC_CLASS_$_NSConstantDictionary", i32 2, i64 27361, ptr @_unnamed_nsdictionary_) + +int main() { + NSNumber *n = @42; + NSNumber *f = @3.14f; + NSNumber *d = @3.14; + NSNumber *b = @YES; + NSArray *a = @[ @"foo" ]; + NSDictionary *dict = @{ @"a" : @1, @"b" : @2 }; + return 0; +} >From 1cf585bbd029b82645b480c6226c272e37c2881f Mon Sep 17 00:00:00 2001 From: Akira Hatanaka <[email protected]> Date: Thu, 9 Apr 2026 12:21:10 -0700 Subject: [PATCH 2/2] Fix comment punctuation in CGObjCMac.cpp Add missing periods to fragment comments added by 154d2267b897 and fix "e.x" to "e.g.," in three doc comments. --- clang/lib/CodeGen/CGObjCMac.cpp | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 2a822a4132726..69c5e88f3c768 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -930,15 +930,15 @@ class CGObjCCommonMac : public CodeGen::CGObjCRuntime { llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap; - /// Uniqued CF boolean singletons + /// Uniqued CF boolean singletons. llvm::GlobalVariable *DefinedCFBooleanTrue = nullptr; llvm::GlobalVariable *DefinedCFBooleanFalse = nullptr; - /// Uniqued `NSNumber`s + /// Uniqued `NSNumber`s. llvm::DenseMap<NSConstantNumberMapInfo, llvm::GlobalVariable *> NSConstantNumberMap; - /// Cached empty collection singletons + /// Cached empty collection singletons. llvm::GlobalVariable *DefinedEmptyNSDictionary = nullptr; llvm::GlobalVariable *DefinedEmptyNSArray = nullptr; @@ -2253,7 +2253,7 @@ CGObjCCommonMac::GenerateConstantNSString(const StringLiteral *Literal) { if (!NSConstantStringType) { // NOTE: The existing implementation used a pointer to a Int32Ty not a // struct pointer as the ISA type when emitting constant strings so this is - // maintained for now + // maintained for now. NSConstantStringType = llvm::StructType::create({CGM.DefaultPtrTy, CGM.Int8PtrTy, CGM.IntTy}, "struct.__builtin_NSString"); @@ -2285,7 +2285,7 @@ CGObjCCommonMac::GenerateConstantNSString(const StringLiteral *Literal) { // String length. Fields.addInt(CGM.IntTy, StringLength); - // The struct + // The struct. CharUnits Alignment = CGM.getPointerAlign(); GV = Fields.finishAndCreateGlobal("_unnamed_nsstring_", Alignment, /*constant*/ true, @@ -2310,8 +2310,8 @@ ConstantAddress CGObjCCommonMac::GenerateConstantNSNumber(const bool Value, return ConstantAddress(Val, Val->getValueType(), CGM.getPointerAlign()); } -/// Generate a constant NSConstantIntegerNumber from an ObjC integer literal e.x -/// @2. +/// Generate a constant NSConstantIntegerNumber from an ObjC integer literal, +/// e.g., @2. /* struct __builtin_NSConstantIntegerNumber { struct._class_t *isa; // point to _NSConstantIntegerNumberClassReference @@ -2365,7 +2365,7 @@ CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APSInt &Value, Fields.add(IntegerValue); - // The struct + // The struct. llvm::GlobalVariable *const GV = Fields.finishAndCreateGlobal( "_unnamed_nsconstantintegernumber_", Alignment, /* constant */ true, llvm::GlobalVariable::PrivateLinkage); @@ -2440,7 +2440,7 @@ CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APFloat &Value, llvm::Constant *FV = llvm::ConstantFP::get(CGM.FloatTy, Value); Fields.add(FV); - // The struct + // The struct. llvm::GlobalVariable *const GV = Fields.finishAndCreateGlobal( "_unnamed_nsconstantfloatnumber_", Alignment, /*constant*/ true, Linkage); @@ -2476,7 +2476,7 @@ CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APFloat &Value, llvm::Constant *DV = llvm::ConstantFP::get(CGM.DoubleTy, Value); Fields.add(DV); - // The struct + // The struct. llvm::GlobalVariable *const GV = Fields.finishAndCreateGlobal( "_unnamed_nsconstantdoublenumber_", Alignment, /*constant*/ true, Linkage); @@ -2510,7 +2510,7 @@ CGObjCCommonMac::EmitNSConstantCollectionLiteralArrayStorage( } /// Generate a constant NSConstantArray from an ObjC array literal, -/// e.x @[ @2 ] or the singleton for an empty `__NSArray0__struct`. +/// e.g., @[ @2 ] or the singleton for an empty `__NSArray0__struct`. /* struct __builtin_NSArray { struct._class_t *isa; // points to _NSConstantArrayClassReference @@ -2551,17 +2551,17 @@ ConstantAddress CGObjCCommonMac::GenerateConstantNSArray( CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers, GlobalDecl(), QualType()); - // count + // count. uint64_t ObjectCount = Objects.size(); llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, ObjectCount); Fields.add(Count); - // objects + // objects. llvm::GlobalVariable *ObjectsGV = EmitNSConstantCollectionLiteralArrayStorage(Objects); Fields.add(ObjectsGV); - // The struct + // The struct. llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal( "_unnamed_nsarray_", Alignment, /* constant */ true, llvm::GlobalValue::PrivateLinkage); @@ -2573,7 +2573,7 @@ ConstantAddress CGObjCCommonMac::GenerateConstantNSArray( } /// Generate a constant NSConstantDictionary from an ObjC dictionary literal -/// with string keys, e.x @{ @"someNum" : @2 } or the singleton for an empty +/// with string keys, e.g., @{ @"someNum" : @2 } or the singleton for an empty /// `__NSDictionary0__struct`. /* struct __builtin_NSDictionary { @@ -2632,7 +2632,7 @@ ConstantAddress CGObjCCommonMac::GenerateConstantNSDictionary( NSUIntegerTy, static_cast<uint64_t>(DictBuilder.getOptions())); Fields.add(OptionsConstant); - // count + // count. llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumElements); Fields.add(Count); @@ -2645,17 +2645,17 @@ ConstantAddress CGObjCCommonMac::GenerateConstantNSDictionary( SortedObjects.push_back(Obj); } - // keys + // keys. llvm::GlobalVariable *KeysGV = EmitNSConstantCollectionLiteralArrayStorage(SortedKeys); Fields.add(KeysGV); - // objects + // objects. llvm::GlobalVariable *ObjectsGV = EmitNSConstantCollectionLiteralArrayStorage(SortedObjects); Fields.add(ObjectsGV); - // The struct + // The struct. llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal( "_unnamed_nsdictionary_", Alignment, /* constant */ true, llvm::GlobalValue::PrivateLinkage); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
