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 | |