diff --git a/Test/CMakeLists.txt b/Test/CMakeLists.txt index 16156ff..99e0ff7 100644 --- a/Test/CMakeLists.txt +++ b/Test/CMakeLists.txt @@ -26,6 +26,7 @@ set(TESTS WeakBlock_arc.m WeakReferences_arc.m ivar_arc.m + IVarOverlap.m objc_msgSend.m msgInterpose.m NilException.m diff --git a/Test/IVarOverlap.m b/Test/IVarOverlap.m new file mode 100644 index 0000000..bc07de6 --- /dev/null +++ b/Test/IVarOverlap.m @@ -0,0 +1,30 @@ +#import +#import "../objc/objc.h" +#import "../objc/runtime.h" +#import "../objc/Object.h" +#include "Test.h" + +#import +#import + +@interface Dummy : Test +{ + id objOne; + struct stat statBuf; + BOOL flagOne; +} +@end + +@implementation Dummy +- (void)test +{ + assert((char*)&statBuf+sizeof(struct stat) <= (char*)&flagOne); +} +@end + + +int main(int argc, char *argv[]) +{ + [[Dummy new] test]; + return 0; +} diff --git a/ivar.c b/ivar.c index d2670b5..d6556f9 100644 --- a/ivar.c +++ b/ivar.c @@ -47,6 +47,7 @@ PRIVATE void objc_compute_ivar_offsets(Class class) */ if (class->ivars) { + long cumulative_fudge = 0; for (i = 0 ; i < class->ivars->count ; i++) { struct objc_ivar *ivar = &class->ivars->ivar_list[i]; @@ -58,6 +59,7 @@ PRIVATE void objc_compute_ivar_offsets(Class class) ? (class_size - ivar->offset) : class->ivars->ivar_list[i+1].offset - ivar->offset ; assert(ivar_size > 0); + ivar->offset += cumulative_fudge; // We only need to do the realignment for things that are // bigger than a pointer, and we don't need to do it in GC mode // where we don't add any extra padding. @@ -71,6 +73,7 @@ PRIVATE void objc_compute_ivar_offsets(Class class) long fudge = 16 - (offset % 16); ivar->offset += fudge; class->instance_size += fudge; + cumulative_fudge += fudge; assert((ivar_start + ivar->offset + sizeof(intptr_t)) % 16 == 0); } ivar->offset += ivar_start;