--- /dev/null
+#include "test.h"
+#include <stdint.h>
+#include <string.h>
+#include <objc/objc-runtime.h>
+
+@interface Super {
+ @public
+ id isa;
+ char superIvar;
+}
+@end
+
+@implementation Super
++(void)initialize { }
++class { return self; }
++new { return class_createInstance(self, 0); }
+@end
+
+
+@interface Sub : Super {
+ @public
+ uintptr_t subIvar;
+}
+@end
+
+@implementation Sub @end
+
+
+int main()
+{
+ /*
+ Runtime layout of Sub:
+ [0] isa
+ [1] superIvar
+ [2] subIvar
+ */
+
+ Ivar ivar;
+ uintptr_t value;
+ Sub *sub = [Sub new];
+ sub->subIvar = 10;
+ testassert(((uintptr_t *)sub)[2] == 10);
+
+ ivar = class_getInstanceVariable([Sub class], "subIvar");
+ testassert(ivar);
+ testassert(2*sizeof(intptr_t) == ivar_getOffset(ivar));
+ testassert(0 == strcmp(ivar_getName(ivar), "subIvar"));
+#if __LP64__
+ testassert(0 == strcmp(ivar_getTypeEncoding(ivar), "Q"));
+#else
+ testassert(0 == strcmp(ivar_getTypeEncoding(ivar), "I"));
+#endif
+
+ ivar = class_getInstanceVariable([Super class], "superIvar");
+ testassert(ivar);
+ testassert(sizeof(intptr_t) == ivar_getOffset(ivar));
+ testassert(0 == strcmp(ivar_getName(ivar), "superIvar"));
+ testassert(0 == strcmp(ivar_getTypeEncoding(ivar), "c"));
+ testassert(ivar == class_getInstanceVariable([Sub class], "superIvar"));
+
+ ivar = class_getInstanceVariable([Super class], "subIvar");
+ testassert(!ivar);
+
+ ivar = class_getInstanceVariable([Sub class]->isa, "subIvar");
+ testassert(!ivar);
+
+
+ sub->subIvar = 10;
+ value = 0;
+ object_getInstanceVariable(sub, "subIvar", (void **)&value);
+ testassert(value == 10);
+
+ object_setInstanceVariable(sub, "subIvar", (void *)11);
+ testassert(sub->subIvar == 11);
+
+ ivar = class_getInstanceVariable([Sub class], "subIvar");
+ object_setIvar(sub, ivar, (id)12);
+ testassert(sub->subIvar == 12);
+ testassert((id)12 == object_getIvar(sub, ivar));
+
+ ivar = class_getInstanceVariable([Sub class], "subIvar");
+ testassert(ivar == object_getInstanceVariable(sub, "subIvar", NULL));
+
+
+ testassert(NULL == class_getInstanceVariable(NULL, "foo"));
+ testassert(NULL == class_getInstanceVariable([Sub class], NULL));
+ testassert(NULL == class_getInstanceVariable(NULL, NULL));
+
+ testassert(NULL == object_getIvar(sub, NULL));
+ testassert(NULL == object_getIvar(NULL, ivar));
+ testassert(NULL == object_getIvar(NULL, NULL));
+
+ testassert(NULL == object_getInstanceVariable(sub, NULL, NULL));
+ testassert(NULL == object_getInstanceVariable(NULL, "foo", NULL));
+ testassert(NULL == object_getInstanceVariable(NULL, NULL, NULL));
+ value = 10;
+ testassert(NULL == object_getInstanceVariable(sub, NULL, (void **)&value));
+ testassert(value == 0);
+ value = 10;
+ testassert(NULL == object_getInstanceVariable(NULL, "foo", (void **)&value));
+ testassert(value == 0);
+ value = 10;
+ testassert(NULL == object_getInstanceVariable(NULL, NULL, (void **)&value));
+ testassert(value == 0);
+
+ object_setIvar(sub, NULL, NULL);
+ object_setIvar(NULL, ivar, NULL);
+ object_setIvar(NULL, NULL, NULL);
+
+ testassert(NULL == object_setInstanceVariable(sub, NULL, NULL));
+ testassert(NULL == object_setInstanceVariable(NULL, "foo", NULL));
+ testassert(NULL == object_setInstanceVariable(NULL, NULL, NULL));
+
+ succeed(__FILE__);
+ return 0;
+}