| 1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s |
| 2 | |
| 3 | typedef struct ompi_datatype_t *MPI_Datatype; |
| 4 | |
| 5 | #define OMPI_PREDEFINED_GLOBAL(type, global) ((type) &(global)) |
| 6 | |
| 7 | #define MPI_FLOAT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float) |
| 8 | #define MPI_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_int) |
| 9 | #define MPI_NULL OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_null) |
| 10 | |
| 11 | extern struct ompi_predefined_datatype_t ompi_mpi_float __attribute__(( type_tag_for_datatype(mpi,float) )); |
| 12 | extern struct ompi_predefined_datatype_t ompi_mpi_int __attribute__(( type_tag_for_datatype(mpi,int) )); |
| 13 | extern struct ompi_predefined_datatype_t ompi_mpi_null __attribute__(( type_tag_for_datatype(mpi,void,must_be_null) )); |
| 14 | |
| 15 | int f(int x) { return x; } |
| 16 | static const int wrong_init __attribute__(( type_tag_for_datatype(zzz,int) )) = f(100); // expected-error {{'type_tag_for_datatype' attribute requires the initializer to be an integral constant expression}} |
| 17 | |
| 18 | //===--- Tests ------------------------------------------------------------===// |
| 19 | // Check that hidden 'this' is handled correctly. |
| 20 | |
| 21 | class C |
| 22 | { |
| 23 | public: |
| 24 | void f1(void *buf, int count, MPI_Datatype datatype) |
| 25 | __attribute__(( pointer_with_type_tag(mpi,5,6) )); // expected-error {{attribute parameter 2 is out of bounds}} |
| 26 | |
| 27 | void f2(void *buf, int count, MPI_Datatype datatype) |
| 28 | __attribute__(( pointer_with_type_tag(mpi,2,5) )); // expected-error {{attribute parameter 3 is out of bounds}} |
| 29 | |
| 30 | void f3(void *buf, int count, MPI_Datatype datatype) |
| 31 | __attribute__(( pointer_with_type_tag(mpi,1,5) )); // expected-error {{attribute is invalid for the implicit this argument}} |
| 32 | |
| 33 | void f4(void *buf, int count, MPI_Datatype datatype) |
| 34 | __attribute__(( pointer_with_type_tag(mpi,2,1) )); // expected-error {{attribute is invalid for the implicit this argument}} |
| 35 | |
| 36 | void MPI_Send(void *buf, int count, MPI_Datatype datatype) |
| 37 | __attribute__(( pointer_with_type_tag(mpi,2,4) )); // no-error |
| 38 | }; |
| 39 | |
| 40 | // Check that we don't crash on type and value dependent expressions. |
| 41 | template<int a> |
| 42 | void value_dep(void *buf, int count, MPI_Datatype datatype) |
| 43 | __attribute__(( pointer_with_type_tag(mpi,a,5) )); // expected-error {{attribute requires parameter 2 to be an integer constant}} |
| 44 | |
| 45 | class OperatorIntStar |
| 46 | { |
| 47 | public: |
| 48 | operator int*(); |
| 49 | }; |
| 50 | |
| 51 | void test1(C *c, int *int_buf) |
| 52 | { |
| 53 | c->MPI_Send(int_buf, 1, MPI_INT); // no-warning |
| 54 | c->MPI_Send(int_buf, 1, MPI_FLOAT); // expected-warning {{argument type 'int *' doesn't match specified 'mpi' type tag that requires 'float *'}} |
| 55 | c->MPI_Send(0, 0, MPI_INT); // no-warning |
| 56 | c->MPI_Send(nullptr, 0, MPI_INT); // no-warning |
| 57 | |
| 58 | OperatorIntStar i; |
| 59 | c->MPI_Send(i, 1, MPI_INT); // no-warning |
| 60 | c->MPI_Send(i, 1, MPI_FLOAT); // expected-warning {{argument type 'int *' doesn't match specified 'mpi' type tag that requires 'float *'}} |
| 61 | } |
| 62 | |
| 63 | template<typename T> |
| 64 | void test2(C *c, int *int_buf, T tag) |
| 65 | { |
| 66 | c->MPI_Send(int_buf, 1, tag); // no-warning |
| 67 | } |
| 68 | |
| 69 | void test3(C *c, int *int_buf) { |
| 70 | test2(c, int_buf, MPI_INT); |
| 71 | test2(c, int_buf, MPI_NULL); |
| 72 | } |
| 73 | |
| 74 | |