runtime.m 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. TEST_BUILD_OUTPUT
  3. .*runtime.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
  4. .*runtime.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
  5. .*runtime.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
  6. END
  7. TEST_RUN_OUTPUT
  8. objc\[\d+\]: class `SwiftV1Class\' not linked into application
  9. objc\[\d+\]: class `DoesNotExist\' not linked into application
  10. OK: runtime.m
  11. OR
  12. confused by Foundation
  13. OK: runtime.m
  14. END
  15. */
  16. #include "test.h"
  17. #include "testroot.i"
  18. #include <string.h>
  19. #include <dlfcn.h>
  20. #include <mach-o/ldsyms.h>
  21. #include <objc/objc-runtime.h>
  22. #if __has_feature(objc_arc)
  23. int main()
  24. {
  25. // provoke the same nullability warnings as the real test
  26. objc_getClass(nil);
  27. objc_getClass(nil);
  28. objc_getClass(nil);
  29. testwarn("rdar://11368528 confused by Foundation");
  30. fprintf(stderr, "confused by Foundation\n");
  31. succeed(__FILE__);
  32. }
  33. #else
  34. @interface Sub : TestRoot @end
  35. @implementation Sub @end
  36. #define SwiftV1MangledName "_TtC6Module12SwiftV1Class"
  37. #define SwiftV1MangledName2 "_TtC2Sw13SwiftV1Class2"
  38. #define SwiftV1MangledName3 "_TtCs13SwiftV1Class3"
  39. #define SwiftV1MangledName4 "_TtC6Swiftt13SwiftV1Class4"
  40. __attribute__((objc_runtime_name(SwiftV1MangledName)))
  41. @interface SwiftV1Class : TestRoot @end
  42. @implementation SwiftV1Class @end
  43. __attribute__((objc_runtime_name(SwiftV1MangledName2)))
  44. @interface SwiftV1Class2 : TestRoot @end
  45. @implementation SwiftV1Class2 @end
  46. __attribute__((objc_runtime_name(SwiftV1MangledName3)))
  47. @interface SwiftV1Class3 : TestRoot @end
  48. @implementation SwiftV1Class3 @end
  49. __attribute__((objc_runtime_name(SwiftV1MangledName4)))
  50. @interface SwiftV1Class4 : TestRoot @end
  51. @implementation SwiftV1Class4 @end
  52. int main()
  53. {
  54. Class list[100];
  55. Class *list2;
  56. unsigned int count, count0, count2;
  57. unsigned int i;
  58. int foundTestRoot;
  59. int foundSub;
  60. int foundSwiftV1;
  61. int foundSwiftV1class2;
  62. int foundSwiftV1class3;
  63. int foundSwiftV1class4;
  64. const char **names;
  65. const char **namesFromHeader;
  66. Dl_info info;
  67. [TestRoot class];
  68. // This shouldn't touch any classes.
  69. dladdr(&_mh_execute_header, &info);
  70. names = objc_copyClassNamesForImage(info.dli_fname, &count);
  71. testassert(names);
  72. testassert(count == 6);
  73. testassert(names[count] == NULL);
  74. foundTestRoot = 0;
  75. foundSub = 0;
  76. foundSwiftV1 = 0;
  77. foundSwiftV1class2 = 0;
  78. foundSwiftV1class3 = 0;
  79. foundSwiftV1class4 = 0;
  80. for (i = 0; i < count; i++) {
  81. if (0 == strcmp(names[i], "TestRoot")) foundTestRoot++;
  82. if (0 == strcmp(names[i], "Sub")) foundSub++;
  83. if (0 == strcmp(names[i], "Module.SwiftV1Class")) foundSwiftV1++;
  84. if (0 == strcmp(names[i], "Sw.SwiftV1Class2")) foundSwiftV1class2++;
  85. if (0 == strcmp(names[i], "Swift.SwiftV1Class3")) foundSwiftV1class3++;
  86. if (0 == strcmp(names[i], "Swiftt.SwiftV1Class4")) foundSwiftV1class4++;
  87. }
  88. testassert(foundTestRoot == 1);
  89. testassert(foundSub == 1);
  90. testassert(foundSwiftV1 == 1);
  91. testassert(foundSwiftV1class2 == 1);
  92. testassert(foundSwiftV1class3 == 1);
  93. testassert(foundSwiftV1class4 == 1);
  94. // Getting the names using the header should give us the same list.
  95. namesFromHeader = objc_copyClassNamesForImage(info.dli_fname, &count0);
  96. testassert(namesFromHeader);
  97. testassert(count == count0);
  98. for (i = 0; i < count; i++) {
  99. testassert(!strcmp(names[i], namesFromHeader[i]));
  100. }
  101. // class Sub hasn't been touched - make sure it's in the class list too
  102. count0 = objc_getClassList(NULL, 0);
  103. testassert(count0 >= 2 && count0 < 100);
  104. list[count0-1] = NULL;
  105. count = objc_getClassList(list, count0-1);
  106. testassert(list[count0-1] == NULL);
  107. testassert(count == count0);
  108. count = objc_getClassList(list, count0);
  109. testassert(count == count0);
  110. for (i = 0; i < count; i++) {
  111. testprintf("%s\n", class_getName(list[i]));
  112. }
  113. foundTestRoot = 0;
  114. foundSub = 0;
  115. foundSwiftV1 = 0;
  116. foundSwiftV1class2 = 0;
  117. foundSwiftV1class3 = 0;
  118. foundSwiftV1class4 = 0;
  119. for (i = 0; i < count; i++) {
  120. if (0 == strcmp(class_getName(list[i]), "TestRoot")) foundTestRoot++;
  121. if (0 == strcmp(class_getName(list[i]), "Sub")) foundSub++;
  122. if (0 == strcmp(class_getName(list[i]), "Module.SwiftV1Class")) foundSwiftV1++;
  123. if (0 == strcmp(class_getName(list[i]), "Sw.SwiftV1Class2")) foundSwiftV1class2++;
  124. if (0 == strcmp(class_getName(list[i]), "Swift.SwiftV1Class3")) foundSwiftV1class3++;
  125. if (0 == strcmp(class_getName(list[i]), "Swiftt.SwiftV1Class4")) foundSwiftV1class4++;
  126. // list should be non-meta classes only
  127. testassert(!class_isMetaClass(list[i]));
  128. }
  129. testassert(foundTestRoot == 1);
  130. testassert(foundSub == 1);
  131. testassert(foundSwiftV1 == 1);
  132. testassert(foundSwiftV1class2 == 1);
  133. testassert(foundSwiftV1class3 == 1);
  134. testassert(foundSwiftV1class4 == 1);
  135. // fixme check class handler
  136. testassert(objc_getClass("TestRoot") == [TestRoot class]);
  137. testassert(objc_getClass("Module.SwiftV1Class") == [SwiftV1Class class]);
  138. testassert(objc_getClass(SwiftV1MangledName) == [SwiftV1Class class]);
  139. testassert(objc_getClass("Sw.SwiftV1Class2") == [SwiftV1Class2 class]);
  140. testassert(objc_getClass(SwiftV1MangledName2) == [SwiftV1Class2 class]);
  141. testassert(objc_getClass("Swift.SwiftV1Class3") == [SwiftV1Class3 class]);
  142. testassert(objc_getClass(SwiftV1MangledName3) == [SwiftV1Class3 class]);
  143. testassert(objc_getClass("Swiftt.SwiftV1Class4") == [SwiftV1Class4 class]);
  144. testassert(objc_getClass(SwiftV1MangledName4) == [SwiftV1Class4 class]);
  145. testassert(objc_getClass("SwiftV1Class") == nil);
  146. testassert(objc_getClass("DoesNotExist") == nil);
  147. testassert(objc_getClass(NULL) == nil);
  148. testassert(objc_getMetaClass("TestRoot") == object_getClass([TestRoot class]));
  149. testassert(objc_getMetaClass("Module.SwiftV1Class") == object_getClass([SwiftV1Class class]));
  150. testassert(objc_getMetaClass(SwiftV1MangledName) == object_getClass([SwiftV1Class class]));
  151. testassert(objc_getMetaClass("SwiftV1Class") == nil);
  152. testassert(objc_getMetaClass("DoesNotExist") == nil);
  153. testassert(objc_getMetaClass(NULL) == nil);
  154. // fixme check class no handler
  155. testassert(objc_lookUpClass("TestRoot") == [TestRoot class]);
  156. testassert(objc_lookUpClass("Module.SwiftV1Class") == [SwiftV1Class class]);
  157. testassert(objc_lookUpClass(SwiftV1MangledName) == [SwiftV1Class class]);
  158. testassert(objc_lookUpClass("SwiftV1Class") == nil);
  159. testassert(objc_lookUpClass("DoesNotExist") == nil);
  160. testassert(objc_lookUpClass(NULL) == nil);
  161. testassert(! object_isClass(nil));
  162. testassert(! object_isClass([TestRoot new]));
  163. testassert(object_isClass([TestRoot class]));
  164. testassert(object_isClass(object_getClass([TestRoot class])));
  165. testassert(object_isClass([Sub class]));
  166. testassert(object_isClass(object_getClass([Sub class])));
  167. testassert(object_isClass([SwiftV1Class class]));
  168. testassert(object_isClass(object_getClass([SwiftV1Class class])));
  169. list2 = objc_copyClassList(&count2);
  170. testassert(count2 == count);
  171. testassert(list2);
  172. testassert(malloc_size(list2) >= (1+count2) * sizeof(Class));
  173. for (i = 0; i < count; i++) {
  174. testassert(list[i] == list2[i]);
  175. }
  176. testassert(list2[count] == NULL);
  177. free(list2);
  178. free(objc_copyClassList(NULL));
  179. succeed(__FILE__);
  180. }
  181. #endif