343 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=optin.mpi.MPI-Checker -verify %s2 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 error18 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 error31 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 error50 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 error231 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 error253 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 error274 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 error285 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 error296 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 error309 310// wrapper function311void 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 function318void 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 error328 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