diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index adc7cdbfded88..6280e9465ecba 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 c94f4c9b5804d..a6c591b2d7930 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 { diff --git a/clang/test/SemaObjC/ivar-access-tests.m b/clang/test/SemaObjC/ivar-access-tests.m index cd7e09d406ada..6060dea5ab0f0 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;