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