xref: /aosp_15_r20/external/clang/test/Analysis/mpichecker.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=optin.mpi.MPI-Checker -verify %s
2*67e74705SXin Li 
3*67e74705SXin Li #include "MPIMock.h"
4*67e74705SXin Li 
matchedWait1()5*67e74705SXin Li void matchedWait1() {
6*67e74705SXin Li   int rank = 0;
7*67e74705SXin Li   double buf = 0;
8*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
9*67e74705SXin Li   if (rank >= 0) {
10*67e74705SXin Li     MPI_Request sendReq1, recvReq1;
11*67e74705SXin Li     MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1);
12*67e74705SXin Li     MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &recvReq1);
13*67e74705SXin Li 
14*67e74705SXin Li     MPI_Wait(&sendReq1, MPI_STATUS_IGNORE);
15*67e74705SXin Li     MPI_Wait(&recvReq1, MPI_STATUS_IGNORE);
16*67e74705SXin Li   }
17*67e74705SXin Li } // no error
18*67e74705SXin Li 
matchedWait2()19*67e74705SXin Li void matchedWait2() {
20*67e74705SXin Li   int rank = 0;
21*67e74705SXin Li   double buf = 0;
22*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
23*67e74705SXin Li   if (rank >= 0) {
24*67e74705SXin Li     MPI_Request sendReq1, recvReq1;
25*67e74705SXin Li     MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1);
26*67e74705SXin Li     MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &recvReq1);
27*67e74705SXin Li     MPI_Wait(&sendReq1, MPI_STATUS_IGNORE);
28*67e74705SXin Li     MPI_Wait(&recvReq1, MPI_STATUS_IGNORE);
29*67e74705SXin Li   }
30*67e74705SXin Li } // no error
31*67e74705SXin Li 
matchedWait3()32*67e74705SXin Li void matchedWait3() {
33*67e74705SXin Li   int rank = 0;
34*67e74705SXin Li   double buf = 0;
35*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
36*67e74705SXin Li   if (rank >= 0) {
37*67e74705SXin Li     MPI_Request sendReq1, recvReq1;
38*67e74705SXin Li     MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1);
39*67e74705SXin Li     MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &recvReq1);
40*67e74705SXin Li 
41*67e74705SXin Li     if (rank > 1000) {
42*67e74705SXin Li       MPI_Wait(&sendReq1, MPI_STATUS_IGNORE);
43*67e74705SXin Li       MPI_Wait(&recvReq1, MPI_STATUS_IGNORE);
44*67e74705SXin Li     } else {
45*67e74705SXin Li       MPI_Wait(&sendReq1, MPI_STATUS_IGNORE);
46*67e74705SXin Li       MPI_Wait(&recvReq1, MPI_STATUS_IGNORE);
47*67e74705SXin Li     }
48*67e74705SXin Li   }
49*67e74705SXin Li } // no error
50*67e74705SXin Li 
missingWait1()51*67e74705SXin Li void missingWait1() { // Check missing wait for dead region.
52*67e74705SXin Li   double buf = 0;
53*67e74705SXin Li   MPI_Request sendReq1;
54*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &sendReq1);
55*67e74705SXin Li } // expected-warning{{Request 'sendReq1' has no matching wait.}}
56*67e74705SXin Li 
missingWait2()57*67e74705SXin Li void missingWait2() {
58*67e74705SXin Li   int rank = 0;
59*67e74705SXin Li   double buf = 0;
60*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
61*67e74705SXin Li   if (rank == 0) {
62*67e74705SXin Li   } else {
63*67e74705SXin Li     MPI_Request sendReq1, recvReq1;
64*67e74705SXin Li 
65*67e74705SXin Li     MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1);
66*67e74705SXin Li     MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &recvReq1); // expected-warning{{Request 'sendReq1' has no matching wait.}}
67*67e74705SXin Li     MPI_Wait(&recvReq1, MPI_STATUS_IGNORE);
68*67e74705SXin Li   }
69*67e74705SXin Li }
70*67e74705SXin Li 
doubleNonblocking()71*67e74705SXin Li void doubleNonblocking() {
72*67e74705SXin Li   int rank = 0;
73*67e74705SXin Li   double buf = 0;
74*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
75*67e74705SXin Li   if (rank == 1) {
76*67e74705SXin Li   } else {
77*67e74705SXin Li     MPI_Request sendReq1;
78*67e74705SXin Li 
79*67e74705SXin Li     MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1);
80*67e74705SXin Li     MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &sendReq1); // expected-warning{{Double nonblocking on request 'sendReq1'.}}
81*67e74705SXin Li     MPI_Wait(&sendReq1, MPI_STATUS_IGNORE);
82*67e74705SXin Li   }
83*67e74705SXin Li }
84*67e74705SXin Li 
doubleNonblocking2()85*67e74705SXin Li void doubleNonblocking2() {
86*67e74705SXin Li   int rank = 0;
87*67e74705SXin Li   double buf = 0;
88*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
89*67e74705SXin Li 
90*67e74705SXin Li   MPI_Request req;
91*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &req);
92*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &req); // expected-warning{{Double nonblocking on request 'req'.}}
93*67e74705SXin Li   MPI_Wait(&req, MPI_STATUS_IGNORE);
94*67e74705SXin Li }
95*67e74705SXin Li 
doubleNonblocking3()96*67e74705SXin Li void doubleNonblocking3() {
97*67e74705SXin Li   typedef struct { MPI_Request req; } ReqStruct;
98*67e74705SXin Li 
99*67e74705SXin Li   ReqStruct rs;
100*67e74705SXin Li   int rank = 0;
101*67e74705SXin Li   double buf = 0;
102*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
103*67e74705SXin Li 
104*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &rs.req);
105*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &rs.req); // expected-warning{{Double nonblocking on request 'rs.req'.}}
106*67e74705SXin Li   MPI_Wait(&rs.req, MPI_STATUS_IGNORE);
107*67e74705SXin Li }
108*67e74705SXin Li 
doubleNonblocking4()109*67e74705SXin Li void doubleNonblocking4() {
110*67e74705SXin Li   int rank = 0;
111*67e74705SXin Li   double buf = 0;
112*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
113*67e74705SXin Li 
114*67e74705SXin Li   MPI_Request req;
115*67e74705SXin Li   for (int i = 0; i < 2; ++i) {
116*67e74705SXin Li     MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &req); // expected-warning{{Double nonblocking on request 'req'.}}
117*67e74705SXin Li   }
118*67e74705SXin Li   MPI_Wait(&req, MPI_STATUS_IGNORE);
119*67e74705SXin Li }
120*67e74705SXin Li 
tripleNonblocking()121*67e74705SXin Li void tripleNonblocking() {
122*67e74705SXin Li   double buf = 0;
123*67e74705SXin Li   MPI_Request sendReq;
124*67e74705SXin Li   MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq);
125*67e74705SXin Li   MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // expected-warning{{Double nonblocking on request 'sendReq'.}}
126*67e74705SXin Li   MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // expected-warning{{Double nonblocking on request 'sendReq'.}}
127*67e74705SXin Li   MPI_Wait(&sendReq, MPI_STATUS_IGNORE);
128*67e74705SXin Li }
129*67e74705SXin Li 
missingNonBlocking()130*67e74705SXin Li void missingNonBlocking() {
131*67e74705SXin Li   int rank = 0;
132*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
133*67e74705SXin Li   MPI_Request sendReq1[10][10][10];
134*67e74705SXin Li   MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // expected-warning{{Request 'sendReq1[1][7][9]' has no matching nonblocking call.}}
135*67e74705SXin Li }
136*67e74705SXin Li 
missingNonBlocking2()137*67e74705SXin Li void missingNonBlocking2() {
138*67e74705SXin Li   int rank = 0;
139*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
140*67e74705SXin Li   typedef struct { MPI_Request req[2][2]; } ReqStruct;
141*67e74705SXin Li   ReqStruct rs;
142*67e74705SXin Li   MPI_Request *r = &rs.req[0][1];
143*67e74705SXin Li   MPI_Wait(r, MPI_STATUS_IGNORE); // expected-warning{{Request 'rs.req[0][1]' has no matching nonblocking call.}}
144*67e74705SXin Li }
145*67e74705SXin Li 
missingNonBlocking3()146*67e74705SXin Li void missingNonBlocking3() {
147*67e74705SXin Li   int rank = 0;
148*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
149*67e74705SXin Li   MPI_Request sendReq;
150*67e74705SXin Li   MPI_Wait(&sendReq, MPI_STATUS_IGNORE); // expected-warning{{Request 'sendReq' has no matching nonblocking call.}}
151*67e74705SXin Li }
152*67e74705SXin Li 
missingNonBlockingMultiple()153*67e74705SXin Li void missingNonBlockingMultiple() {
154*67e74705SXin Li   int rank = 0;
155*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
156*67e74705SXin Li   MPI_Request sendReq[4];
157*67e74705SXin Li   for (int i = 0; i < 4; ++i) {
158*67e74705SXin Li     MPI_Wait(&sendReq[i], MPI_STATUS_IGNORE); // expected-warning-re 1+{{Request {{.*}} has no matching nonblocking call.}}
159*67e74705SXin Li   }
160*67e74705SXin Li }
161*67e74705SXin Li 
missingNonBlockingWaitall()162*67e74705SXin Li void missingNonBlockingWaitall() {
163*67e74705SXin Li   int rank = 0;
164*67e74705SXin Li   double buf = 0;
165*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
166*67e74705SXin Li   MPI_Request req[4];
167*67e74705SXin Li 
168*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
169*67e74705SXin Li       &req[0]);
170*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
171*67e74705SXin Li       &req[1]);
172*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
173*67e74705SXin Li       &req[3]);
174*67e74705SXin Li 
175*67e74705SXin Li   MPI_Waitall(4, req, MPI_STATUSES_IGNORE); // expected-warning{{Request 'req[2]' has no matching nonblocking call.}}
176*67e74705SXin Li }
177*67e74705SXin Li 
missingNonBlockingWaitall2()178*67e74705SXin Li void missingNonBlockingWaitall2() {
179*67e74705SXin Li   int rank = 0;
180*67e74705SXin Li   double buf = 0;
181*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
182*67e74705SXin Li   MPI_Request req[4];
183*67e74705SXin Li 
184*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
185*67e74705SXin Li       &req[0]);
186*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
187*67e74705SXin Li       &req[3]);
188*67e74705SXin Li 
189*67e74705SXin Li   MPI_Waitall(4, req, MPI_STATUSES_IGNORE); // expected-warning-re 2{{Request '{{(.*)[[1-2]](.*)}}' has no matching nonblocking call.}}
190*67e74705SXin Li }
191*67e74705SXin Li 
missingNonBlockingWaitall3()192*67e74705SXin Li void missingNonBlockingWaitall3() {
193*67e74705SXin Li   int rank = 0;
194*67e74705SXin Li   double buf = 0;
195*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
196*67e74705SXin Li   MPI_Request req[4];
197*67e74705SXin Li 
198*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
199*67e74705SXin Li       &req[0]);
200*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
201*67e74705SXin Li       &req[2]);
202*67e74705SXin Li 
203*67e74705SXin Li   MPI_Waitall(4, req, MPI_STATUSES_IGNORE); // expected-warning-re 2{{Request '{{(.*)[[1,3]](.*)}}' has no matching nonblocking call.}}
204*67e74705SXin Li }
205*67e74705SXin Li 
missingNonBlockingWaitall4()206*67e74705SXin Li void missingNonBlockingWaitall4() {
207*67e74705SXin Li   int rank = 0;
208*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
209*67e74705SXin Li   MPI_Request req[4];
210*67e74705SXin Li   MPI_Waitall(4, req, MPI_STATUSES_IGNORE); // expected-warning-re 4{{Request '{{(.*)[[0-3]](.*)}}' has no matching nonblocking call.}}
211*67e74705SXin Li }
212*67e74705SXin Li 
noDoubleRequestUsage()213*67e74705SXin Li void noDoubleRequestUsage() {
214*67e74705SXin Li   typedef struct {
215*67e74705SXin Li     MPI_Request req;
216*67e74705SXin Li     MPI_Request req2;
217*67e74705SXin Li   } ReqStruct;
218*67e74705SXin Li 
219*67e74705SXin Li   ReqStruct rs;
220*67e74705SXin Li   int rank = 0;
221*67e74705SXin Li   double buf = 0;
222*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
223*67e74705SXin Li 
224*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
225*67e74705SXin Li               &rs.req);
226*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
227*67e74705SXin Li               &rs.req2);
228*67e74705SXin Li   MPI_Wait(&rs.req, MPI_STATUS_IGNORE);
229*67e74705SXin Li   MPI_Wait(&rs.req2, MPI_STATUS_IGNORE);
230*67e74705SXin Li } // no error
231*67e74705SXin Li 
noDoubleRequestUsage2()232*67e74705SXin Li void noDoubleRequestUsage2() {
233*67e74705SXin Li   typedef struct {
234*67e74705SXin Li     MPI_Request req[2];
235*67e74705SXin Li     MPI_Request req2;
236*67e74705SXin Li   } ReqStruct;
237*67e74705SXin Li 
238*67e74705SXin Li   ReqStruct rs;
239*67e74705SXin Li   int rank = 0;
240*67e74705SXin Li   double buf = 0;
241*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
242*67e74705SXin Li 
243*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
244*67e74705SXin Li               &rs.req[0]);
245*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
246*67e74705SXin Li               &rs.req[1]);
247*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
248*67e74705SXin Li               &rs.req2);
249*67e74705SXin Li   MPI_Wait(&rs.req[0], MPI_STATUS_IGNORE);
250*67e74705SXin Li   MPI_Wait(&rs.req[1], MPI_STATUS_IGNORE);
251*67e74705SXin Li   MPI_Wait(&rs.req2, MPI_STATUS_IGNORE);
252*67e74705SXin Li } // no error
253*67e74705SXin Li 
nestedRequest()254*67e74705SXin Li void nestedRequest() {
255*67e74705SXin Li   typedef struct {
256*67e74705SXin Li     MPI_Request req[2];
257*67e74705SXin Li     MPI_Request req2;
258*67e74705SXin Li   } ReqStruct;
259*67e74705SXin Li 
260*67e74705SXin Li   ReqStruct rs;
261*67e74705SXin Li   int rank = 0;
262*67e74705SXin Li   double buf = 0;
263*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
264*67e74705SXin Li 
265*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
266*67e74705SXin Li               &rs.req[0]);
267*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
268*67e74705SXin Li               &rs.req[1]);
269*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
270*67e74705SXin Li               &rs.req2);
271*67e74705SXin Li   MPI_Waitall(2, rs.req, MPI_STATUSES_IGNORE);
272*67e74705SXin Li   MPI_Wait(&rs.req2, MPI_STATUS_IGNORE);
273*67e74705SXin Li } // no error
274*67e74705SXin Li 
singleRequestInWaitall()275*67e74705SXin Li void singleRequestInWaitall() {
276*67e74705SXin Li   MPI_Request r;
277*67e74705SXin Li   int rank = 0;
278*67e74705SXin Li   double buf = 0;
279*67e74705SXin Li   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
280*67e74705SXin Li 
281*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
282*67e74705SXin Li               &r);
283*67e74705SXin Li   MPI_Waitall(1, &r, MPI_STATUSES_IGNORE);
284*67e74705SXin Li } // no error
285*67e74705SXin Li 
multiRequestUsage()286*67e74705SXin Li void multiRequestUsage() {
287*67e74705SXin Li   double buf = 0;
288*67e74705SXin Li   MPI_Request req;
289*67e74705SXin Li 
290*67e74705SXin Li   MPI_Isend(&buf, 1, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD, &req);
291*67e74705SXin Li   MPI_Wait(&req, MPI_STATUS_IGNORE);
292*67e74705SXin Li 
293*67e74705SXin Li   MPI_Irecv(&buf, 1, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD, &req);
294*67e74705SXin Li   MPI_Wait(&req, MPI_STATUS_IGNORE);
295*67e74705SXin Li } // no error
296*67e74705SXin Li 
multiRequestUsage2()297*67e74705SXin Li void multiRequestUsage2() {
298*67e74705SXin Li   double buf = 0;
299*67e74705SXin Li   MPI_Request req;
300*67e74705SXin Li 
301*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
302*67e74705SXin Li               &req);
303*67e74705SXin Li   MPI_Wait(&req, MPI_STATUS_IGNORE);
304*67e74705SXin Li 
305*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
306*67e74705SXin Li               &req);
307*67e74705SXin Li   MPI_Wait(&req, MPI_STATUS_IGNORE);
308*67e74705SXin Li } // no error
309*67e74705SXin Li 
310*67e74705SXin Li // wrapper function
callNonblocking(MPI_Request * req)311*67e74705SXin Li void callNonblocking(MPI_Request *req) {
312*67e74705SXin Li   double buf = 0;
313*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
314*67e74705SXin Li              req);
315*67e74705SXin Li }
316*67e74705SXin Li 
317*67e74705SXin Li // wrapper function
callWait(MPI_Request * req)318*67e74705SXin Li void callWait(MPI_Request *req) {
319*67e74705SXin Li   MPI_Wait(req, MPI_STATUS_IGNORE);
320*67e74705SXin Li }
321*67e74705SXin Li 
322*67e74705SXin Li // Call nonblocking, wait wrapper functions.
callWrapperFunctions()323*67e74705SXin Li void callWrapperFunctions() {
324*67e74705SXin Li   MPI_Request req;
325*67e74705SXin Li   callNonblocking(&req);
326*67e74705SXin Li   callWait(&req);
327*67e74705SXin Li } // no error
328*67e74705SXin Li 
externFunctions1()329*67e74705SXin Li void externFunctions1() {
330*67e74705SXin Li   double buf = 0;
331*67e74705SXin Li   MPI_Request req;
332*67e74705SXin Li   MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
333*67e74705SXin Li               &req);
334*67e74705SXin Li   void callWaitExtern(MPI_Request *req);
335*67e74705SXin Li   callWaitExtern(&req);
336*67e74705SXin Li } // expected-warning{{Request 'req' has no matching wait.}}
337*67e74705SXin Li 
externFunctions2()338*67e74705SXin Li void externFunctions2() {
339*67e74705SXin Li   MPI_Request req;
340*67e74705SXin Li   void callNonblockingExtern(MPI_Request *req);
341*67e74705SXin Li   callNonblockingExtern(&req);
342*67e74705SXin Li }
343