/* APPLE LOCAL file ObjC GC */
/* A run-time test for insertion of write barriers. */

/* { dg-do run { target *-*-darwin* } } */
/* { dg-options "-fnext-runtime -fobjc-gc" } */
/* { dg-options "-fnext-runtime -fobjc-gc -mmacosx-version-min=10.3" { target powerpc*-*-darwin* } } */
/* { dg-skip-if "" { *-*-darwin* } { "-m64" } { "" } } */

#include <objc/objc.h>
#include <stdio.h>
#include <stdlib.h>

typedef const struct __CFDictionary * CFDictionaryRef;

// callouts to these are generated with cc -fobjc-gc

int GlobalAssigns;
int IvarAssigns;
int StrongCastAssigns;


id objc_assign_global(id value, __weak id *dest) {
  ++GlobalAssigns;
  return (*dest = value);
}

id objc_assign_ivar(id value, id dest, unsigned int offset) {
  id *slot = (id*) ((char *)dest + offset);

  ++IvarAssigns;
  return (*slot = value);
}

id objc_assign_strongCast(id value, __weak id *dest) {
  id base;

  ++StrongCastAssigns ;
  return (*dest = value);
}

// The test case elements;
@class NSObject;
@class NSString;

typedef struct {
  id  element;
  id elementArray[10];
  __strong CFDictionaryRef cfElement;
  __strong CFDictionaryRef cfElementArray[10];
} struct_with_ids_t;

@interface Foo  {
@public
// assignments to any/all of these fields should generate objc_assign_ivar
  __strong CFDictionaryRef dict;
  __strong CFDictionaryRef dictArray[3];
  id ivar;
  id array[10];
  NSObject *nsobject;
  NSString *stringArray[10];
  struct_with_ids_t inner;
}

@end

// assignments to these should generate objc_assign_global
id GlobalId;
id GlobalArray[20];
NSObject *GlobalObject;
NSObject *GlobalObjectArray[20];
__strong CFDictionaryRef Gdict;
__strong CFDictionaryRef Gdictarray[10];
struct_with_ids_t GlobalStruct;
struct_with_ids_t GlobalStructArray[10];


// The test cases
void *rhs = 0;

#define ASSIGNTEST(expr, global) expr = rhs; if (!global) { printf(# expr " is busted\n"); ++counter; }  global = 0

int testGlobals() {
  // Everything in this function generates assign_global intercepts
  int counter = 0;

  static id staticGlobalId;
  static id staticGlobalArray[20];
  static NSObject *staticGlobalObject;
  static NSObject *staticGlobalObjectArray[20];
  static __strong CFDictionaryRef staticGdict;
  static __strong CFDictionaryRef staticGdictarray[10];
  static struct_with_ids_t staticGlobalStruct;
  static struct_with_ids_t staticGlobalStructArray[10];

  ASSIGNTEST(GlobalId, GlobalAssigns);				// objc_assign_global
  ASSIGNTEST(GlobalArray[0], GlobalAssigns);			// objc_assign_global
  ASSIGNTEST(GlobalObject, GlobalAssigns);			// objc_assign_global
  ASSIGNTEST(GlobalObjectArray[0], GlobalAssigns);		// objc_assign_global
  ASSIGNTEST(Gdict, GlobalAssigns);				// objc_assign_global
  ASSIGNTEST(Gdictarray[1], GlobalAssigns);			// objc_assign_global

  ASSIGNTEST(GlobalStruct.element, GlobalAssigns);		// objc_assign_global
  ASSIGNTEST(GlobalStruct.elementArray[0], GlobalAssigns);	// objc_assign_global
  ASSIGNTEST(GlobalStruct.cfElement, GlobalAssigns);		// objc_assign_global
  ASSIGNTEST(GlobalStruct.cfElementArray[0], GlobalAssigns);	// objc_assign_global

  ASSIGNTEST(staticGlobalId, GlobalAssigns);			// objc_assign_global
  ASSIGNTEST(staticGlobalArray[0], GlobalAssigns);		// objc_assign_global
  ASSIGNTEST(staticGlobalObject, GlobalAssigns);		// objc_assign_global
  ASSIGNTEST(staticGlobalObjectArray[0], GlobalAssigns);	// objc_assign_global
  ASSIGNTEST(staticGdict, GlobalAssigns);			// objc_assign_global
  ASSIGNTEST(staticGdictarray[1], GlobalAssigns);		// objc_assign_global

  ASSIGNTEST(staticGlobalStruct.element, GlobalAssigns);		// objc_assign_global
  ASSIGNTEST(staticGlobalStruct.elementArray[0], GlobalAssigns);	// objc_assign_global
  ASSIGNTEST(staticGlobalStruct.cfElement, GlobalAssigns);		// objc_assign_global
  ASSIGNTEST(staticGlobalStruct.cfElementArray[0], GlobalAssigns);	// objc_assign_global
    
  return counter;
}


int testIvars() {
  Foo *foo = (Foo *)malloc(sizeof(Foo)); // don't call in ObjC
  int counter = 0;

  ASSIGNTEST(foo->ivar, IvarAssigns);					// objc_assign_ivar
  ASSIGNTEST(foo->dict, IvarAssigns);					// objc_assign_ivar
  ASSIGNTEST(foo->dictArray[0], IvarAssigns);				// objc_assign_ivar
  ASSIGNTEST(foo->array[0], IvarAssigns);				// objc_assign_ivar
  ASSIGNTEST(foo->nsobject, IvarAssigns);				// objc_assign_ivar
  ASSIGNTEST(foo->stringArray[0], IvarAssigns);				// objc_assign_ivar
  ASSIGNTEST(foo->inner.element, IvarAssigns);				// objc_assign_ivar
  ASSIGNTEST(foo->inner.elementArray[0], IvarAssigns);			// objc_assign_ivar
  ASSIGNTEST(foo->inner.cfElement, IvarAssigns);			// objc_assign_ivar
  ASSIGNTEST(foo->inner.cfElementArray[0], IvarAssigns);		// objc_assign_ivar

  return counter;
}

int testStrongCasts() {
  id x = nil;
  int counter = 0;
  typedef struct { @defs(Foo) } Foo_defs;
  Foo_defs *foo = (Foo_defs *)malloc(sizeof(Foo));
    
  // strong casts should always be issued, even if the compiler could know better
    
  ASSIGNTEST((__strong id)foo->ivar, StrongCastAssigns);		// objc_assign_strongCast
  ASSIGNTEST((__strong id)foo->dict, StrongCastAssigns);		// objc_assign_strongCast
  ASSIGNTEST((__strong id)foo->dictArray[0], StrongCastAssigns);	// objc_assign_strongCast
  ASSIGNTEST((__strong id)foo->array[0], StrongCastAssigns);		// objc_assign_strongCast
  ASSIGNTEST((__strong id)foo->nsobject, StrongCastAssigns);		// objc_assign_strongCast
  ASSIGNTEST((__strong id)foo->stringArray[0], StrongCastAssigns);	// objc_assign_strongCast
  ASSIGNTEST((__strong id)foo->inner.element, StrongCastAssigns);	// objc_assign_strongCast
  ASSIGNTEST((__strong id)foo->inner.elementArray[0], StrongCastAssigns);// objc_assign_strongCast
  ASSIGNTEST((__strong id)foo->inner.cfElement, StrongCastAssigns);	// objc_assign_strongCast
  ASSIGNTEST((__strong id)foo->inner.cfElementArray[0], StrongCastAssigns);// objc_assign_strongCast

  // assignments to declared __strong on plain structure elements shouldn't work
    
  return counter;
}

@implementation Foo
@end

int main(int argc, char *argv[]) {
  int errors = 0;
  errors += testGlobals();
  errors += testIvars();
  errors += testStrongCasts();
  return (errors != 0);
}
