blob: 9c7bd3e9aa6890a98eb3b9fecb6463dc08e8310a [file] [log] [blame]
/* APPLE LOCAL file radar 3742561 */
/* Test that we generate void * objc_memmove_collectable(void *dst, const void *src, size_t size)
API when struct has a 'strong' object pointer in a variety of situations. */
/* { dg-options "-fobjc-gc -mmacosx-version-min=10.5 -framework Cocoa" } */
/* { dg-do run { target *-*-darwin* } } */
/* { dg-require-effective-target objc_gc } */
#define objc_copyStruct X_objc_copyStruct
#define objc_memmove_collectable X_objc_memmove_collectable
#include <Cocoa/Cocoa.h>
#undef objc_memmove_collectable
#undef objc_copyStruct
static int count;
/* Only ppc32 API for property assignment makes the call to objc_copyStruct. */
static void
objc_copyStruct (void *dst, const void * src, size_t size, bool arg, bool arg2)
{
memcpy (dst, src, size);
count++;
}
typedef struct S {
int ii;
} SS;
struct type_s {
SS may_recurse;
id id_val;
};
struct nono {
nono & operator = (const nono & arg)
{
memcpy (this, &arg, sizeof(nono));
return *this;
}
struct type_s nono_val;
id id_nono;
nono (int val)
{
nono_val.may_recurse.ii = val;
}
};
@interface NamedObject : NSObject
{
struct type_s type_s_ivar;
}
- (void) setSome : (struct type_s) arg;
- (struct type_s) getSome;
@property(assign) struct type_s aggre_prop;
@end
@implementation NamedObject
- (void) setSome : (struct type_s) arg
{
type_s_ivar = arg;
}
- (struct type_s) getSome
{
return type_s_ivar;
}
@synthesize aggre_prop = type_s_ivar;
@end
struct type_s some = {{1234}, (id)0};
struct type_s get(void)
{
return some;
}
struct type_s GlobalVariable;
static void *
objc_memmove_collectable(void *dst, const void *src, size_t size)
{
memcpy (dst, src, size);
count++;
}
int main(void) {
struct type_s local;
struct type_s *p;
int old_count;
NamedObject *object = [[NamedObject alloc] init];
/* Assigning into a global */
GlobalVariable = get();
if (count != 1 || GlobalVariable.may_recurse.ii != 1234)
abort ();
/* Assigning into a local */
local = GlobalVariable;
if (count != 2 || local.may_recurse.ii != 1234)
abort ();
p = (struct type_s *) malloc (sizeof (struct type_s));
/* Assigning thourgh a pointer */
*p = local;
if (count != 3 || p->may_recurse.ii != 1234)
abort ();
/* Assigning to an ivar */
[object setSome:GlobalVariable];
if (count != 4 || [object getSome].may_recurse.ii != 1234)
abort ();
local.may_recurse.ii = 6578;
object.aggre_prop = local;
if (count != 5 || object.aggre_prop.may_recurse.ii != 6578)
abort ();
/* class assignment with overloaded '=' operator must NOT call the new API. */
old_count = count;
nono nono_rhs (89);
nono nono_lhs (100);
nono_lhs = nono_rhs;
if (count != old_count || nono_lhs.nono_val.may_recurse.ii != 89)
abort ();
return 0;
}