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
f(int x)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
test1(C * c,int * int_buf)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>
test2(C * c,int * int_buf,T tag)64 void test2(C *c, int *int_buf, T tag)
65 {
66 c->MPI_Send(int_buf, 1, tag); // no-warning
67 }
68
test3(C * c,int * int_buf)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