1/* Test if instance methods of root classes are used as class methods, if no
2   "real" methods are found.  For receivers of type 'id' and 'Class', all
3   root classes must be considered.  */
4/* Author: Ziemowit Laski <zlaski@apple.com>.  */
5/* { dg-do run } */
6/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
7// { dg-additional-options "-Wno-objc-root-class" }
8#include <objc/objc.h>
9#include "../objc-obj-c++-shared/runtime.h"
10
11#include <stdlib.h>
12#include <string.h>
13
14#define CHECK_IF(expr) if(!(expr)) abort()
15
16@protocol Proto
17- (const char *) method4;
18@end
19
20@interface Root
21{ Class isa; }
22+ (const char *) method2;
23@end
24
25@interface Derived: Root
26- (const char *) method1;
27- (const char *) method2;
28- (const char *) method3;
29@end
30
31@interface Root (Categ)
32- (const char *) method3;
33@end
34
35@implementation Root (Categ)
36- (const char *) method3 { return "Root(Categ)::-method3"; }
37- (const char *) method4 { return "Root(Categ)::-method4"; }
38@end
39
40@implementation Derived
41- (const char *) method1 { return "Derived::-method1"; }
42- (const char *) method2 { return "Derived::-method2"; }
43- (const char *) method3 { return "Derived::-method3"; }
44@end
45
46@implementation Root
47+ initialize { return self; }
48- (const char *) method1 { return "Root::-method1"; }
49+ (const char *) method2 { return "Root::+method2"; }
50@end
51
52int main(void)
53{
54  Class obj = objc_getClass("Derived");
55
56  /* None of the following should elicit compiler-time warnings.  */
57
58  CHECK_IF(!strcmp([Root method1], "Root::-method1"));
59  CHECK_IF(!strcmp([Root method2], "Root::+method2"));
60  CHECK_IF(!strcmp([Root method3], "Root(Categ)::-method3"));
61  CHECK_IF(!strcmp([Root method4], "Root(Categ)::-method4"));
62  CHECK_IF(!strcmp([Derived method1], "Root::-method1"));
63  CHECK_IF(!strcmp([Derived method2], "Root::+method2"));
64  CHECK_IF(!strcmp([Derived method3], "Root(Categ)::-method3"));
65  CHECK_IF(!strcmp([Derived method4], "Root(Categ)::-method4"));
66  CHECK_IF(!strcmp([obj method1], "Root::-method1"));
67  CHECK_IF(!strcmp([obj method2], "Root::+method2"));
68  CHECK_IF(!strcmp([obj method3], "Root(Categ)::-method3"));
69  CHECK_IF(!strcmp([obj method4], "Root(Categ)::-method4"));
70
71  return 0;
72}
73
74