[clang] Set dllimport on Objective C ivar offsets (PR #107604)

David Chisnall via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 11 04:38:00 PDT 2024


https://github.com/davidchisnall updated https://github.com/llvm/llvm-project/pull/107604

>From 5fa137ce295b369b3d652e9538a4f3c13e592ad3 Mon Sep 17 00:00:00 2001
From: Frederik Carlier <frederik.carlier at keysight.com>
Date: Fri, 6 Sep 2024 11:54:59 +0000
Subject: [PATCH 1/2] Set dllimport on Objective C ivar offsets

This commit ensures that offsets for instance variables are marked with `dllimport` if the interface to which they belong have this attribute.
---
 clang/lib/CodeGen/CGObjCGNU.cpp     | 11 +++++++++--
 clang/test/CodeGenObjC/dllstorage.m |  4 ++--
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
index adc7cdbfded880..6280e9465ecba6 100644
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ b/clang/lib/CodeGen/CGObjCGNU.cpp
@@ -1699,11 +1699,18 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
   llvm::Value *EmitIvarOffset(CodeGenFunction &CGF,
                               const ObjCInterfaceDecl *Interface,
                               const ObjCIvarDecl *Ivar) override {
-    const std::string Name = GetIVarOffsetVariableName(Ivar->getContainingInterface(), Ivar);
+    const ObjCInterfaceDecl *ContainingInterface =
+        Ivar->getContainingInterface();
+    const std::string Name =
+        GetIVarOffsetVariableName(ContainingInterface, Ivar);
     llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
-    if (!IvarOffsetPointer)
+    if (!IvarOffsetPointer) {
       IvarOffsetPointer = new llvm::GlobalVariable(TheModule, IntTy, false,
               llvm::GlobalValue::ExternalLinkage, nullptr, Name);
+      if (Ivar->getAccessControl() != ObjCIvarDecl::Private &&
+          Ivar->getAccessControl() != ObjCIvarDecl::Package)
+        CGM.setGVProperties(IvarOffsetPointer, ContainingInterface);
+    }
     CharUnits Align = CGM.getIntAlign();
     llvm::Value *Offset =
         CGF.Builder.CreateAlignedLoad(IntTy, IvarOffsetPointer, Align);
diff --git a/clang/test/CodeGenObjC/dllstorage.m b/clang/test/CodeGenObjC/dllstorage.m
index c94f4c9b5804d0..a6c591b2d79302 100644
--- a/clang/test/CodeGenObjC/dllstorage.m
+++ b/clang/test/CodeGenObjC/dllstorage.m
@@ -112,7 +112,7 @@ @interface M : I {
 // CHECK-IR-DAG: @"OBJC_IVAR_$_M._ivar" = external dllimport global i32
 
 // CHECK-NF-DAG: @"$_OBJC_REF_CLASS_M" = external dllimport global ptr
-// CHECK-NF-DAG: @"__objc_ivar_offset_M._ivar.@" = external global i32
+// CHECK-NF-DAG: @"__objc_ivar_offset_M._ivar.@" = external dllimport global i32
 
 __declspec(dllexport)
 __attribute__((__objc_exception__))
@@ -151,7 +151,7 @@ id f(Q *q) {
 
 // CHECK-IR-DAG: @"OBJC_IVAR_$_M._ivar" = external dllimport global i32
 
-// CHECK-NF-DAG: @"__objc_ivar_offset_M._ivar.@" = external global i32
+// CHECK-NF-DAG: @"__objc_ivar_offset_M._ivar.@" = external dllimport global i32
 
 int g(void) {
   @autoreleasepool {

>From 93abb9bbc785d9ed6e86c0f1cfb22bc7982da252 Mon Sep 17 00:00:00 2001
From: Frederik Carlier <frederik.carlier at keysight.com>
Date: Sat, 7 Sep 2024 03:00:46 -0700
Subject: [PATCH 2/2] Add tests to ensure unmarked instance variables are
 considered protected

---
 clang/test/SemaObjC/ivar-access-tests.m | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/clang/test/SemaObjC/ivar-access-tests.m b/clang/test/SemaObjC/ivar-access-tests.m
index cd7e09d406adaa..6060dea5ab0f0e 100644
--- a/clang/test/SemaObjC/ivar-access-tests.m
+++ b/clang/test/SemaObjC/ivar-access-tests.m
@@ -2,6 +2,8 @@
 
 @interface MySuperClass
 {
+  int unmarked;
+
 @private
   int private;
 
@@ -17,6 +19,7 @@ @implementation MySuperClass
 - (void) test {
     int access;
     MySuperClass *s = 0;
+    access = s->unmarked;
     access = s->private;   
     access = s->protected;
 }
@@ -30,9 +33,11 @@ @implementation MyClass
 - (void) test {
     int access;
     MySuperClass *s = 0;
+    access = s->unmarked;
     access = s->private; // expected-error {{instance variable 'private' is private}}
     access = s->protected;
     MyClass *m=0;
+    access = m->unmarked;
     access = m->private; // expected-error {{instance variable 'private' is private}}
     access = m->protected;
 }
@@ -46,9 +51,11 @@ @implementation Deeper
 - (void) test {
     int access;
     MySuperClass *s = 0;
+    access = s->unmarked;
     access = s->private; // expected-error {{instance variable 'private' is private}}
     access = s->protected;
     MyClass *m=0;
+    access = m->unmarked;
     access = m->private; // expected-error {{instance variable 'private' is private}}
     access = m->protected;
 }
@@ -61,9 +68,11 @@ @implementation Unrelated
 - (void) test {
     int access;
     MySuperClass *s = 0;
+    access = s->unmarked; // expected-error {{instance variable 'unmarked' is protected}}
     access = s->private; // expected-error {{instance variable 'private' is private}}
     access = s->protected; // expected-error {{instance variable 'protected' is protected}}
     MyClass *m=0;
+    access = m->unmarked; // expected-error {{instance variable 'unmarked' is protected}}
     access = m->private; // expected-error {{instance variable 'private' is private}}
     access = m->protected; // expected-error {{instance variable 'protected' is protected}}
 }
@@ -73,6 +82,7 @@ int main (void)
 {
   MySuperClass *s = 0;
   int access;
+  access = s->unmarked; // expected-error {{instance variable 'unmarked' is protected}}
   access = s->private;   // expected-error {{instance variable 'private' is private}}
   access = s->protected; // expected-error {{instance variable 'protected' is protected}}
   return 0;



More information about the cfe-commits mailing list