cxx0x-initializer-stdinitializerlist.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. // RUN: %clang_cc1 -std=c++11 -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
  2. namespace std {
  3. typedef decltype(sizeof(int)) size_t;
  4. // libc++'s implementation
  5. template <class _E>
  6. class initializer_list
  7. {
  8. const _E* __begin_;
  9. size_t __size_;
  10. initializer_list(const _E* __b, size_t __s)
  11. : __begin_(__b),
  12. __size_(__s)
  13. {}
  14. public:
  15. typedef _E value_type;
  16. typedef const _E& reference;
  17. typedef const _E& const_reference;
  18. typedef size_t size_type;
  19. typedef const _E* iterator;
  20. typedef const _E* const_iterator;
  21. initializer_list() : __begin_(nullptr), __size_(0) {}
  22. size_t size() const {return __size_;}
  23. const _E* begin() const {return __begin_;}
  24. const _E* end() const {return __begin_ + __size_;}
  25. };
  26. }
  27. struct destroyme1 {
  28. ~destroyme1();
  29. };
  30. struct destroyme2 {
  31. ~destroyme2();
  32. };
  33. struct witharg1 {
  34. witharg1(const destroyme1&);
  35. ~witharg1();
  36. };
  37. struct wantslist1 {
  38. wantslist1(std::initializer_list<destroyme1>);
  39. ~wantslist1();
  40. };
  41. // CHECK: @_ZGR15globalInitList1_ = internal constant [3 x i32] [i32 1, i32 2, i32 3]
  42. // CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32], [3 x i32]* @_ZGR15globalInitList1_, i32 0, i32 0), i{{32|64}} 3 }
  43. std::initializer_list<int> globalInitList1 = {1, 2, 3};
  44. namespace thread_local_global_array {
  45. // FIXME: We should be able to constant-evaluate this even though the
  46. // initializer is not a constant expression (pointers to thread_local
  47. // objects aren't really a problem).
  48. //
  49. // CHECK: @_ZN25thread_local_global_array1xE = thread_local global
  50. // CHECK: @_ZGRN25thread_local_global_array1xE_ = internal thread_local constant [4 x i32] [i32 1, i32 2, i32 3, i32 4]
  51. std::initializer_list<int> thread_local x = { 1, 2, 3, 4 };
  52. }
  53. // CHECK: @globalInitList2 = global %{{[^ ]+}} zeroinitializer
  54. // CHECK: @_ZGR15globalInitList2_ = internal global [2 x %[[WITHARG:[^ ]*]]] zeroinitializer
  55. // CHECK: @_ZN15partly_constant1kE = global i32 0, align 4
  56. // CHECK: @_ZN15partly_constant2ilE = global {{.*}} null, align 8
  57. // CHECK: @[[PARTLY_CONSTANT_OUTER:_ZGRN15partly_constant2ilE.*]] = internal global {{.*}} zeroinitializer, align 8
  58. // CHECK: @[[PARTLY_CONSTANT_INNER:_ZGRN15partly_constant2ilE.*]] = internal global [3 x {{.*}}] zeroinitializer, align 8
  59. // CHECK: @[[PARTLY_CONSTANT_FIRST:_ZGRN15partly_constant2ilE.*]] = internal constant [3 x i32] [i32 1, i32 2, i32 3], align 4
  60. // CHECK: @[[PARTLY_CONSTANT_SECOND:_ZGRN15partly_constant2ilE.*]] = internal global [2 x i32] zeroinitializer, align 4
  61. // CHECK: @[[PARTLY_CONSTANT_THIRD:_ZGRN15partly_constant2ilE.*]] = internal constant [4 x i32] [i32 5, i32 6, i32 7, i32 8], align 4
  62. // CHECK: @[[REFTMP1:.*]] = private constant [2 x i32] [i32 42, i32 43], align 4
  63. // CHECK: @[[REFTMP2:.*]] = private constant [3 x %{{.*}}] [%{{.*}} { i32 1 }, %{{.*}} { i32 2 }, %{{.*}} { i32 3 }], align 4
  64. // CHECK: appending global
  65. // thread_local initializer:
  66. // CHECK-LABEL: define internal void
  67. // CHECK: store i32* getelementptr inbounds ([4 x i32], [4 x i32]* @_ZGRN25thread_local_global_array1xE_, i64 0, i64 0),
  68. // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 0), align 8
  69. // CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}, {{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 1), align 8
  70. // CHECK-LABEL: define internal void
  71. // CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 0
  72. // CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 1
  73. // CHECK: __cxa_atexit
  74. // CHECK: store %[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i64 0, i64 0),
  75. // CHECK: %[[WITHARG]]** getelementptr inbounds (%{{.*}}, %{{.*}}* @globalInitList2, i32 0, i32 0), align 8
  76. // CHECK: store i64 2, i64* getelementptr inbounds (%{{.*}}, %{{.*}}* @globalInitList2, i32 0, i32 1), align 8
  77. // CHECK: call void @_ZN10destroyme1D1Ev
  78. // CHECK: call void @_ZN10destroyme1D1Ev
  79. std::initializer_list<witharg1> globalInitList2 = {
  80. witharg1(destroyme1()), witharg1(destroyme1())
  81. };
  82. void fn1(int i) {
  83. // CHECK-LABEL: define void @_Z3fn1i
  84. // temporary array
  85. // CHECK: [[array:%[^ ]+]] = alloca [3 x i32]
  86. // CHECK: getelementptr inbounds [3 x i32], [3 x i32]* [[array]], i{{32|64}} 0
  87. // CHECK-NEXT: store i32 1, i32*
  88. // CHECK-NEXT: getelementptr
  89. // CHECK-NEXT: store
  90. // CHECK-NEXT: getelementptr
  91. // CHECK-NEXT: load
  92. // CHECK-NEXT: store
  93. // init the list
  94. // CHECK-NEXT: getelementptr
  95. // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]*
  96. // CHECK-NEXT: store i32*
  97. // CHECK-NEXT: getelementptr
  98. // CHECK-NEXT: store i{{32|64}} 3
  99. std::initializer_list<int> intlist{1, 2, i};
  100. }
  101. void fn2() {
  102. // CHECK-LABEL: define void @_Z3fn2v
  103. void target(std::initializer_list<destroyme1>);
  104. // objects should be destroyed before dm2, after call returns
  105. // CHECK: call void @_Z6targetSt16initializer_listI10destroyme1E
  106. target({ destroyme1(), destroyme1() });
  107. // CHECK: call void @_ZN10destroyme1D1Ev
  108. destroyme2 dm2;
  109. // CHECK: call void @_ZN10destroyme2D1Ev
  110. }
  111. void fn3() {
  112. // CHECK-LABEL: define void @_Z3fn3v
  113. // objects should be destroyed after dm2
  114. auto list = { destroyme1(), destroyme1() };
  115. destroyme2 dm2;
  116. // CHECK: call void @_ZN10destroyme2D1Ev
  117. // CHECK: call void @_ZN10destroyme1D1Ev
  118. }
  119. void fn4() {
  120. // CHECK-LABEL: define void @_Z3fn4v
  121. void target(std::initializer_list<witharg1>);
  122. // objects should be destroyed before dm2, after call returns
  123. // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
  124. // CHECK: call void @_Z6targetSt16initializer_listI8witharg1E
  125. target({ witharg1(destroyme1()), witharg1(destroyme1()) });
  126. // CHECK: call void @_ZN8witharg1D1Ev
  127. // CHECK: call void @_ZN10destroyme1D1Ev
  128. destroyme2 dm2;
  129. // CHECK: call void @_ZN10destroyme2D1Ev
  130. }
  131. void fn5() {
  132. // CHECK-LABEL: define void @_Z3fn5v
  133. // temps should be destroyed before dm2
  134. // objects should be destroyed after dm2
  135. // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
  136. auto list = { witharg1(destroyme1()), witharg1(destroyme1()) };
  137. // CHECK: call void @_ZN10destroyme1D1Ev
  138. destroyme2 dm2;
  139. // CHECK: call void @_ZN10destroyme2D1Ev
  140. // CHECK: call void @_ZN8witharg1D1Ev
  141. }
  142. void fn6() {
  143. // CHECK-LABEL: define void @_Z3fn6v
  144. void target(const wantslist1&);
  145. // objects should be destroyed before dm2, after call returns
  146. // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
  147. // CHECK: call void @_Z6targetRK10wantslist1
  148. target({ destroyme1(), destroyme1() });
  149. // CHECK: call void @_ZN10wantslist1D1Ev
  150. // CHECK: call void @_ZN10destroyme1D1Ev
  151. destroyme2 dm2;
  152. // CHECK: call void @_ZN10destroyme2D1Ev
  153. }
  154. void fn7() {
  155. // CHECK-LABEL: define void @_Z3fn7v
  156. // temps should be destroyed before dm2
  157. // object should be destroyed after dm2
  158. // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
  159. wantslist1 wl = { destroyme1(), destroyme1() };
  160. // CHECK: call void @_ZN10destroyme1D1Ev
  161. destroyme2 dm2;
  162. // CHECK: call void @_ZN10destroyme2D1Ev
  163. // CHECK: call void @_ZN10wantslist1D1Ev
  164. }
  165. void fn8() {
  166. // CHECK-LABEL: define void @_Z3fn8v
  167. void target(std::initializer_list<std::initializer_list<destroyme1>>);
  168. // objects should be destroyed before dm2, after call returns
  169. // CHECK: call void @_Z6targetSt16initializer_listIS_I10destroyme1EE
  170. std::initializer_list<destroyme1> inner;
  171. target({ inner, { destroyme1() } });
  172. // CHECK: call void @_ZN10destroyme1D1Ev
  173. // Only one destroy loop, since only one inner init list is directly inited.
  174. // CHECK-NOT: call void @_ZN10destroyme1D1Ev
  175. destroyme2 dm2;
  176. // CHECK: call void @_ZN10destroyme2D1Ev
  177. }
  178. void fn9() {
  179. // CHECK-LABEL: define void @_Z3fn9v
  180. // objects should be destroyed after dm2
  181. std::initializer_list<destroyme1> inner;
  182. std::initializer_list<std::initializer_list<destroyme1>> list =
  183. { inner, { destroyme1() } };
  184. destroyme2 dm2;
  185. // CHECK: call void @_ZN10destroyme2D1Ev
  186. // CHECK: call void @_ZN10destroyme1D1Ev
  187. // Only one destroy loop, since only one inner init list is directly inited.
  188. // CHECK-NOT: call void @_ZN10destroyme1D1Ev
  189. // CHECK: ret void
  190. }
  191. struct haslist1 {
  192. std::initializer_list<int> il;
  193. haslist1(int i);
  194. };
  195. // CHECK-LABEL: define void @_ZN8haslist1C2Ei
  196. haslist1::haslist1(int i)
  197. // CHECK: alloca [3 x i32]
  198. // CHECK: store i32 %
  199. // CHECK: store i32 2
  200. // CHECK: store i32 3
  201. : il{i, 2, 3}
  202. {
  203. destroyme2 dm2;
  204. }
  205. struct haslist2 {
  206. std::initializer_list<destroyme1> il;
  207. haslist2();
  208. };
  209. // CHECK-LABEL: define void @_ZN8haslist2C2Ev
  210. haslist2::haslist2()
  211. : il{destroyme1(), destroyme1()}
  212. {
  213. destroyme2 dm2;
  214. // CHECK: call void @_ZN10destroyme2D1Ev
  215. // CHECK: call void @_ZN10destroyme1D1Ev
  216. }
  217. void fn10(int i) {
  218. // CHECK-LABEL: define void @_Z4fn10i
  219. // CHECK: alloca [3 x i32]
  220. // CHECK: call i8* @_Znw{{[jm]}}
  221. // CHECK: store i32 %
  222. // CHECK: store i32 2
  223. // CHECK: store i32 3
  224. // CHECK: store i32*
  225. (void) new std::initializer_list<int> {i, 2, 3};
  226. }
  227. void fn11() {
  228. // CHECK-LABEL: define void @_Z4fn11v
  229. (void) new std::initializer_list<destroyme1> {destroyme1(), destroyme1()};
  230. // CHECK: call void @_ZN10destroyme1D1Ev
  231. destroyme2 dm2;
  232. // CHECK: call void @_ZN10destroyme2D1Ev
  233. }
  234. namespace PR12178 {
  235. struct string {
  236. string(int);
  237. ~string();
  238. };
  239. struct pair {
  240. string a;
  241. int b;
  242. };
  243. struct map {
  244. map(std::initializer_list<pair>);
  245. };
  246. map m{ {1, 2}, {3, 4} };
  247. }
  248. namespace rdar13325066 {
  249. struct X { ~X(); };
  250. // CHECK-LABEL: define void @_ZN12rdar133250664loopERNS_1XES1_
  251. void loop(X &x1, X &x2) {
  252. // CHECK: br label
  253. // CHECK: br i1
  254. // CHECK: br label
  255. // CHECK: call void @_ZN12rdar133250661XD1Ev
  256. // CHECK: br label
  257. // CHECK: br label
  258. // CHECK: call void @_ZN12rdar133250661XD1Ev
  259. // CHECK: br i1
  260. // CHECK: br label
  261. // CHECK: ret void
  262. for (X x : { x1, x2 }) { }
  263. }
  264. }
  265. namespace dtors {
  266. struct S {
  267. S();
  268. ~S();
  269. };
  270. void z();
  271. // CHECK-LABEL: define void @_ZN5dtors1fEv(
  272. void f() {
  273. // CHECK: call void @_ZN5dtors1SC1Ev(
  274. // CHECK: call void @_ZN5dtors1SC1Ev(
  275. std::initializer_list<S>{ S(), S() };
  276. // Destruction loop for underlying array.
  277. // CHECK: br label
  278. // CHECK: call void @_ZN5dtors1SD1Ev(
  279. // CHECK: br i1
  280. // CHECK: call void @_ZN5dtors1zEv(
  281. z();
  282. // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
  283. }
  284. // CHECK-LABEL: define void @_ZN5dtors1gEv(
  285. void g() {
  286. // CHECK: call void @_ZN5dtors1SC1Ev(
  287. // CHECK: call void @_ZN5dtors1SC1Ev(
  288. auto x = std::initializer_list<S>{ S(), S() };
  289. // Destruction loop for underlying array.
  290. // CHECK: br label
  291. // CHECK: call void @_ZN5dtors1SD1Ev(
  292. // CHECK: br i1
  293. // CHECK: call void @_ZN5dtors1zEv(
  294. z();
  295. // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
  296. }
  297. // CHECK-LABEL: define void @_ZN5dtors1hEv(
  298. void h() {
  299. // CHECK: call void @_ZN5dtors1SC1Ev(
  300. // CHECK: call void @_ZN5dtors1SC1Ev(
  301. std::initializer_list<S> x = { S(), S() };
  302. // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
  303. // CHECK: call void @_ZN5dtors1zEv(
  304. z();
  305. // Destruction loop for underlying array.
  306. // CHECK: br label
  307. // CHECK: call void @_ZN5dtors1SD1Ev(
  308. // CHECK: br i1
  309. }
  310. }
  311. namespace partly_constant {
  312. int k;
  313. std::initializer_list<std::initializer_list<int>> &&il = { { 1, 2, 3 }, { 4, k }, { 5, 6, 7, 8 } };
  314. // First init list.
  315. // CHECK-NOT: @[[PARTLY_CONSTANT_FIRST]],
  316. // CHECK: store i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_FIRST]], i64 0, i64 0),
  317. // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0, i32 0)
  318. // CHECK: store i64 3, i64* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0, i32 1)
  319. // CHECK-NOT: @[[PARTLY_CONSTANT_FIRST]],
  320. //
  321. // Second init list array (non-constant).
  322. // CHECK: store i32 4, i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 0)
  323. // CHECK: load i32, i32* @_ZN15partly_constant1kE
  324. // CHECK: store i32 {{.*}}, i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 1)
  325. //
  326. // Second init list.
  327. // CHECK: store i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 0),
  328. // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 1, i32 0)
  329. // CHECK: store i64 2, i64* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 1, i32 1)
  330. //
  331. // Third init list.
  332. // CHECK-NOT: @[[PARTLY_CONSTANT_THIRD]],
  333. // CHECK: store i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_THIRD]], i64 0, i64 0),
  334. // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 2, i32 0)
  335. // CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}, {{.*}}* @_ZGRN15partly_constant2ilE4_, i64 0, i64 2, i32 1)
  336. // CHECK-NOT: @[[PARTLY_CONSTANT_THIRD]],
  337. //
  338. // Outer init list.
  339. // CHECK: store {{.*}}* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0),
  340. // CHECK: {{.*}}** getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_OUTER]], i32 0, i32 0)
  341. // CHECK: store i64 3, i64* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_OUTER]], i32 0, i32 1)
  342. //
  343. // 'il' reference.
  344. // CHECK: store {{.*}}* @[[PARTLY_CONSTANT_OUTER]], {{.*}}** @_ZN15partly_constant2ilE, align 8
  345. }
  346. namespace nested {
  347. struct A { A(); ~A(); };
  348. struct B { const A &a; ~B(); };
  349. struct C { std::initializer_list<B> b; ~C(); };
  350. void f();
  351. // CHECK-LABEL: define void @_ZN6nested1gEv(
  352. void g() {
  353. // CHECK: call void @_ZN6nested1AC1Ev(
  354. // CHECK-NOT: call
  355. // CHECK: call void @_ZN6nested1AC1Ev(
  356. // CHECK-NOT: call
  357. const C &c { { { A() }, { A() } } };
  358. // CHECK: call void @_ZN6nested1fEv(
  359. // CHECK-NOT: call
  360. f();
  361. // CHECK: call void @_ZN6nested1CD1Ev(
  362. // CHECK-NOT: call
  363. // Destroy B[2] array.
  364. // FIXME: This isn't technically correct: reverse construction order would
  365. // destroy the second B then the second A then the first B then the first A.
  366. // CHECK: call void @_ZN6nested1BD1Ev(
  367. // CHECK-NOT: call
  368. // CHECK: br
  369. // CHECK-NOT: call
  370. // CHECK: call void @_ZN6nested1AD1Ev(
  371. // CHECK-NOT: call
  372. // CHECK: call void @_ZN6nested1AD1Ev(
  373. // CHECK-NOT: call
  374. // CHECK: }
  375. }
  376. }
  377. namespace DR1070 {
  378. struct A {
  379. A(std::initializer_list<int>);
  380. };
  381. struct B {
  382. int i;
  383. A a;
  384. };
  385. B b = {1};
  386. struct C {
  387. std::initializer_list<int> a;
  388. B b;
  389. std::initializer_list<double> c;
  390. };
  391. C c = {};
  392. }
  393. namespace ArrayOfInitList {
  394. struct S {
  395. S(std::initializer_list<int>);
  396. };
  397. S x[1] = {};
  398. }
  399. namespace PR20445 {
  400. struct vector { vector(std::initializer_list<int>); };
  401. struct MyClass { explicit MyClass(const vector &v); };
  402. template<int x> void f() { new MyClass({42, 43}); }
  403. template void f<0>();
  404. // CHECK-LABEL: define {{.*}} @_ZN7PR204451fILi0EEEvv(
  405. // CHECK: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @[[REFTMP1]], i64 0, i64 0)
  406. // CHECK: call void @_ZN7PR204456vectorC1ESt16initializer_listIiE(
  407. // CHECK: call void @_ZN7PR204457MyClassC1ERKNS_6vectorE(
  408. }
  409. namespace ConstExpr {
  410. class C {
  411. int x;
  412. public:
  413. constexpr C(int x) : x(x) {}
  414. };
  415. void f(std::initializer_list<C>);
  416. void g() {
  417. // CHECK-LABEL: _ZN9ConstExpr1gEv
  418. // CHECK: store %"class.ConstExpr::C"* getelementptr inbounds ([3 x %"class.ConstExpr::C"], [3 x %"class.ConstExpr::C"]* @[[REFTMP2]], i64 0, i64 0)
  419. // CHECK: call void @_ZN9ConstExpr1fESt16initializer_listINS_1CEE
  420. f({C(1), C(2), C(3)});
  421. }
  422. }
  423. namespace B19773010 {
  424. template <class T1, class T2> struct pair {
  425. T1 first;
  426. T2 second;
  427. constexpr pair() : first(), second() {}
  428. constexpr pair(T1 a, T2 b) : first(a), second(b) {}
  429. };
  430. enum E { ENUM_CONSTANT };
  431. struct testcase {
  432. testcase(std::initializer_list<pair<const char *, E>>);
  433. };
  434. void f1() {
  435. // CHECK-LABEL: @_ZN9B197730102f1Ev
  436. testcase a{{"", ENUM_CONSTANT}};
  437. // CHECK: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* bitcast ([1 x { i8*, i32 }]* @.ref.tmp{{.*}} to [1 x %"struct.B19773010::pair"]*), i64 0, i64 0), %"struct.B19773010::pair"** %{{.*}}, align 8
  438. }
  439. void f2() {
  440. // CHECK-LABEL: @_ZN9B197730102f2Ev
  441. // CHECK: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* bitcast ([1 x { i8*, i32 }]* @_ZGRZN9B197730102f2EvE1p_ to [1 x %"struct.B19773010::pair"]*), i64 0, i64 0), %"struct.B19773010::pair"** getelementptr inbounds ([2 x %"class.std::initializer_list.10"], [2 x %"class.std::initializer_list.10"]* @_ZZN9B197730102f2EvE1p, i64 0, i64 1, i32 0), align 16
  442. static std::initializer_list<pair<const char *, E>> a, p[2] =
  443. {a, {{"", ENUM_CONSTANT}}};
  444. }
  445. void PR22940_helper(const pair<void*, int>&) { }
  446. void PR22940() {
  447. // CHECK-LABEL: @_ZN9B197730107PR22940Ev
  448. // CHECK: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev(
  449. // CHECK: call {{.*}} @_ZN9B1977301014PR22940_helperERKNS_4pairIPviEE(
  450. PR22940_helper(pair<void*, int>());
  451. }
  452. }