1 // RUN: %clang_cc1 -std=c99 -DOPEN_MPI -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -std=c99 -DMPICH -fsyntax-only -verify %s
3 // RUN: %clang_cc1 -x c++ -std=c++98 -DOPEN_MPI -fsyntax-only -verify %s
4 // RUN: %clang_cc1 -x c++ -std=c++98 -DMPICH -fsyntax-only -verify %s
6 // RUN: %clang_cc1 -std=c99 -DOPEN_MPI -fno-signed-char -fsyntax-only -verify %s
7 // RUN: %clang_cc1 -std=c99 -DMPICH -fno-signed-char -fsyntax-only -verify %s
9 //===--- limits.h mock ----------------------------------------------------===//
11 #ifdef __CHAR_UNSIGNED__
13 #define CHAR_MAX (__SCHAR_MAX__*2 +1)
15 #define CHAR_MIN (-__SCHAR_MAX__-1)
16 #define CHAR_MAX __SCHAR_MAX__
19 //===--- mpi.h mock -------------------------------------------------------===//
21 #define NULL ((void *)0)
24 typedef struct ompi_datatype_t
*MPI_Datatype
;
28 typedef int MPI_Datatype
;
31 int MPI_Send(void *buf
, int count
, MPI_Datatype datatype
)
32 __attribute__(( pointer_with_type_tag(mpi
,1,3) ));
34 int MPI_Gather(void *sendbuf
, int sendcount
, MPI_Datatype sendtype
,
35 void *recvbuf
, int recvcount
, MPI_Datatype recvtype
)
36 __attribute__(( pointer_with_type_tag(mpi
,1,3), pointer_with_type_tag(mpi
,4,6) ));
39 // OpenMPI and LAM/MPI-style datatype definitions
41 #define OMPI_PREDEFINED_GLOBAL(type, global) ((type) &(global))
43 #define MPI_DATATYPE_NULL OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_datatype_null)
44 #define MPI_FLOAT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float)
45 #define MPI_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_int)
46 #define MPI_LONG OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_long)
47 #define MPI_LONG_LONG_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_long_long_int)
48 #define MPI_CHAR OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_char)
50 #define MPI_FLOAT_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float_int)
51 #define MPI_2INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_2int)
53 #define MPI_IN_PLACE ((void *) 1)
55 extern struct ompi_predefined_datatype_t ompi_mpi_datatype_null
__attribute__(( type_tag_for_datatype(mpi
,void,must_be_null
) ));
56 extern struct ompi_predefined_datatype_t ompi_mpi_float
__attribute__(( type_tag_for_datatype(mpi
,float) ));
57 extern struct ompi_predefined_datatype_t ompi_mpi_int
__attribute__(( type_tag_for_datatype(mpi
,int) ));
58 extern struct ompi_predefined_datatype_t ompi_mpi_long
__attribute__(( type_tag_for_datatype(mpi
,long) ));
59 extern struct ompi_predefined_datatype_t ompi_mpi_long_long_int
__attribute__(( type_tag_for_datatype(mpi
,long long int) ));
60 extern struct ompi_predefined_datatype_t ompi_mpi_char
__attribute__(( type_tag_for_datatype(mpi
,char) ));
62 struct ompi_struct_mpi_float_int
{float f
; int i
;};
63 extern struct ompi_predefined_datatype_t ompi_mpi_float_int
__attribute__(( type_tag_for_datatype(mpi
, struct ompi_struct_mpi_float_int
, layout_compatible
) ));
65 struct ompi_struct_mpi_2int
{int i1
; int i2
;};
66 extern struct ompi_predefined_datatype_t ompi_mpi_2int
__attribute__(( type_tag_for_datatype(mpi
, struct ompi_struct_mpi_2int
, layout_compatible
) ));
70 // MPICH2 and MVAPICH2-style datatype definitions
72 #define MPI_COMM_WORLD ((MPI_Comm) 0x44000000)
74 #define MPI_DATATYPE_NULL ((MPI_Datatype) 0xa0000000)
75 #define MPI_FLOAT ((MPI_Datatype) 0xa0000001)
76 #define MPI_INT ((MPI_Datatype) 0xa0000002)
77 #define MPI_LONG ((MPI_Datatype) 0xa0000003)
78 #define MPI_LONG_LONG_INT ((MPI_Datatype) 0xa0000004)
79 #define MPI_CHAR ((MPI_Datatype) 0xa0000005)
81 #define MPI_FLOAT_INT ((MPI_Datatype) 0xa0000006)
82 #define MPI_2INT ((MPI_Datatype) 0xa0000007)
84 #define MPI_IN_PLACE (void *) -1
86 static const MPI_Datatype mpich_mpi_datatype_null
__attribute__(( type_tag_for_datatype(mpi
,void,must_be_null
) )) = 0xa0000000;
87 static const MPI_Datatype mpich_mpi_float
__attribute__(( type_tag_for_datatype(mpi
,float) )) = 0xa0000001;
88 static const MPI_Datatype mpich_mpi_int
__attribute__(( type_tag_for_datatype(mpi
,int) )) = 0xa0000002;
89 static const MPI_Datatype mpich_mpi_long
__attribute__(( type_tag_for_datatype(mpi
,long) )) = 0xa0000003;
90 static const MPI_Datatype mpich_mpi_long_long_int
__attribute__(( type_tag_for_datatype(mpi
,long long int) )) = 0xa0000004;
91 static const MPI_Datatype mpich_mpi_char
__attribute__(( type_tag_for_datatype(mpi
,char) )) = 0xa0000005;
93 struct mpich_struct_mpi_float_int
{ float f
; int i
; };
94 struct mpich_struct_mpi_2int
{ int i1
; int i2
; };
95 static const MPI_Datatype mpich_mpi_float_int
__attribute__(( type_tag_for_datatype(mpi
, struct mpich_struct_mpi_float_int
, layout_compatible
) )) = 0xa0000006;
96 static const MPI_Datatype mpich_mpi_2int
__attribute__(( type_tag_for_datatype(mpi
, struct mpich_struct_mpi_2int
, layout_compatible
) )) = 0xa0000007;
99 //===--- HDF5 headers mock ------------------------------------------------===//
105 #define H5OPEN H5open(),
110 #define H5T_NATIVE_CHAR (CHAR_MIN?H5T_NATIVE_SCHAR:H5T_NATIVE_UCHAR)
111 #define H5T_NATIVE_SCHAR (H5OPEN H5T_NATIVE_SCHAR_g)
112 #define H5T_NATIVE_UCHAR (H5OPEN H5T_NATIVE_UCHAR_g)
113 #define H5T_NATIVE_INT (H5OPEN H5T_NATIVE_INT_g)
114 #define H5T_NATIVE_LONG (H5OPEN H5T_NATIVE_LONG_g)
116 hid_t H5T_NATIVE_SCHAR_g
__attribute__(( type_tag_for_datatype(hdf5
,signed char) ));
117 hid_t H5T_NATIVE_UCHAR_g
__attribute__(( type_tag_for_datatype(hdf5
,unsigned char) ));
118 hid_t H5T_NATIVE_INT_g
__attribute__(( type_tag_for_datatype(hdf5
,int) ));
119 hid_t H5T_NATIVE_LONG_g
__attribute__(( type_tag_for_datatype(hdf5
,long) ));
121 void H5Dwrite(hid_t mem_type_id
, const void *buf
) __attribute__(( pointer_with_type_tag(hdf5
,2,1) ));
123 //===--- Tests ------------------------------------------------------------===//
127 struct pair_float_int
137 void test_mpi_predefined_types(
142 struct pair_float_int
*pfi
,
143 struct pair_int_int
*pii
)
147 // Layout-compatible scalar types.
148 MPI_Send(int_buf
, 1, MPI_INT
); // no-warning
150 // Null pointer constant.
151 MPI_Send(0, 0, MPI_INT
); // no-warning
152 MPI_Send(NULL
, 0, MPI_INT
); // no-warning
154 // Layout-compatible class types.
155 MPI_Send(pfi
, 1, MPI_FLOAT_INT
); // no-warning
156 MPI_Send(pii
, 1, MPI_2INT
); // no-warning
158 // Layout-incompatible scalar types.
159 MPI_Send(long_buf1
, 1, MPI_INT
); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'int *'}}
161 // Layout-incompatible class types.
162 MPI_Send(pii
, 1, MPI_FLOAT_INT
); // expected-warning {{argument type 'struct pair_int_int *' doesn't match specified 'mpi' type tag}}
163 MPI_Send(pfi
, 1, MPI_2INT
); // expected-warning {{argument type 'struct pair_float_int *' doesn't match specified 'mpi' type tag}}
165 // Layout-incompatible class-scalar types.
166 MPI_Send(long_buf1
, 1, MPI_2INT
); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag}}
168 // Function with two buffers.
169 MPI_Gather(long_buf1
, 1, MPI_INT
, // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'int *'}}
170 long_buf2
, 1, MPI_INT
); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'int *'}}
172 // Array buffers should work like pointer buffers.
173 MPI_Send(char_buf
, 255, MPI_CHAR
); // no-warning
175 // Explicit casts should not be dropped.
176 MPI_Send((int *) char_buf
, 255, MPI_INT
); // no-warning
177 MPI_Send((int *) char_buf
, 255, MPI_CHAR
); // expected-warning {{argument type 'int *' doesn't match specified 'mpi' type tag that requires 'char *'}}
179 // `void*' buffer should never warn.
180 MPI_Send(void_buf
, 255, MPI_CHAR
); // no-warning
182 // We expect that MPI_IN_PLACE is `void*', shouldn't warn.
183 MPI_Gather(MPI_IN_PLACE
, 0, MPI_INT
,
184 int_buf
, 1, MPI_INT
);
186 // Special handling for MPI_DATATYPE_NULL: buffer pointer should be either
187 // a `void*' pointer or a null pointer constant.
188 MPI_Gather(NULL
, 0, MPI_DATATYPE_NULL
, // no-warning
189 int_buf
, 1, MPI_INT
);
191 MPI_Gather(int_buf
, 0, MPI_DATATYPE_NULL
, // expected-warning {{specified mpi type tag requires a null pointer}}
192 int_buf
, 1, MPI_INT
);
195 MPI_Datatype my_int_datatype
__attribute__(( type_tag_for_datatype(mpi
,int) ));
197 struct S1
{ int a
; int b
; };
198 MPI_Datatype my_s1_datatype
__attribute__(( type_tag_for_datatype(mpi
,struct S1
) ));
200 // Layout-compatible to S1, but should be treated as a different type.
201 struct S2
{ int a
; int b
; };
202 MPI_Datatype my_s2_datatype
__attribute__(( type_tag_for_datatype(mpi
,struct S2
) ));
205 MPI_Datatype my_e1_datatype
__attribute__(( type_tag_for_datatype(mpi
,enum E1
) ));
207 void test_user_types(int *int_buf
,
213 MPI_Send(int_buf
, 1, my_int_datatype
); // no-warning
214 MPI_Send(long_buf
, 1, my_int_datatype
); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'int *'}}
216 MPI_Send(s1_buf
, 1, my_s1_datatype
); // no-warning
217 MPI_Send(s1_buf
, 1, my_s2_datatype
); // expected-warning {{argument type 'struct S1 *' doesn't match specified 'mpi' type tag that requires 'struct S2 *'}}
219 MPI_Send(long_buf
, 1, my_s1_datatype
); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'struct S1 *'}}
220 MPI_Send(s1_buf
, 1, MPI_INT
); // expected-warning {{argument type 'struct S1 *' doesn't match specified 'mpi' type tag that requires 'int *'}}
222 MPI_Send(e1_buf
, 1, my_e1_datatype
); // no-warning
223 MPI_Send(e1_buf
, 1, MPI_INT
); // expected-warning {{argument type 'enum E1 *' doesn't match specified 'mpi' type tag that requires 'int *'}}
224 MPI_Send(int_buf
, 1, my_e1_datatype
); // expected-warning {{argument type 'int *' doesn't match specified 'mpi' type tag that requires 'enum E1 *'}}
227 MPI_Datatype my_unknown_datatype
;
229 void test_not_annotated(int *int_buf
,
233 // Using 'MPI_Datatype's without attributes should not produce warnings.
234 MPI_Send(long_buf
, 1, my_unknown_datatype
); // no-warning
235 MPI_Send(int_buf
, 1, type
); // no-warning
238 struct S1_compat
{ int a
; int b
; };
239 MPI_Datatype my_s1_compat_datatype
240 __attribute__(( type_tag_for_datatype(mpi
, struct S1_compat
, layout_compatible
) ));
242 struct S3
{ int a
; long b
; double c
; double d
; struct S1 s1
; };
243 struct S3_compat
{ int a
; long b
; double c
; double d
; struct S2 s2
; };
244 MPI_Datatype my_s3_compat_datatype
245 __attribute__(( type_tag_for_datatype(mpi
, struct S3_compat
, layout_compatible
) ));
247 struct S4
{ char c
; };
248 struct S4_compat
{ signed char c
; };
249 MPI_Datatype my_s4_compat_datatype
250 __attribute__(( type_tag_for_datatype(mpi
, struct S4_compat
, layout_compatible
) ));
252 union U1
{ int a
; long b
; double c
; double d
; struct S1 s1
; };
253 union U1_compat
{ long b
; double c
; struct S2 s
; int a
; double d
; };
254 MPI_Datatype my_u1_compat_datatype
255 __attribute__(( type_tag_for_datatype(mpi
, union U1_compat
, layout_compatible
) ));
257 union U2
{ int a
; long b
; double c
; struct S1 s1
; };
258 MPI_Datatype my_u2_datatype
259 __attribute__(( type_tag_for_datatype(mpi
, union U2
, layout_compatible
) ));
261 void test_layout_compatibility(struct S1
*s1_buf
, struct S3
*s3_buf
,
263 union U1
*u1_buf
, union U2
*u2_buf
)
265 MPI_Send(s1_buf
, 1, my_s1_compat_datatype
); // no-warning
266 MPI_Send(s3_buf
, 1, my_s3_compat_datatype
); // no-warning
267 MPI_Send(s1_buf
, 1, my_s3_compat_datatype
); // expected-warning {{argument type 'struct S1 *' doesn't match specified 'mpi' type tag}}
268 MPI_Send(s4_buf
, 1, my_s4_compat_datatype
); // expected-warning {{argument type 'struct S4 *' doesn't match specified 'mpi' type tag}}
269 MPI_Send(u1_buf
, 1, my_u1_compat_datatype
); // no-warning
270 MPI_Send(u1_buf
, 1, my_u2_datatype
); // expected-warning {{argument type 'union U1 *' doesn't match specified 'mpi' type tag}}
271 MPI_Send(u2_buf
, 1, my_u1_compat_datatype
); // expected-warning {{argument type 'union U2 *' doesn't match specified 'mpi' type tag}}
274 // There is an MPI_REAL predefined in MPI, but some existing MPI programs do
277 #define MPI_REAL MPI_FLOAT
279 void test_mpi_real_user_type(real
*real_buf
, float *float_buf
)
281 MPI_Send(real_buf
, 1, MPI_REAL
); // no-warning
282 MPI_Send(real_buf
, 1, MPI_FLOAT
); // no-warning
283 MPI_Send(float_buf
, 1, MPI_REAL
); // no-warning
284 MPI_Send(float_buf
, 1, MPI_FLOAT
); // no-warning
289 void test_hdf5(char *char_buf
,
290 signed char *schar_buf
,
291 unsigned char *uchar_buf
,
295 H5Dwrite(H5T_NATIVE_CHAR
, char_buf
); // no-warning
296 #ifdef __CHAR_UNSIGNED__
297 H5Dwrite(H5T_NATIVE_CHAR
, schar_buf
); // expected-warning {{argument type 'signed char *' doesn't match specified 'hdf5' type tag that requires 'unsigned char *'}}
298 H5Dwrite(H5T_NATIVE_CHAR
, uchar_buf
); // no-warning
300 H5Dwrite(H5T_NATIVE_CHAR
, schar_buf
); // no-warning
301 H5Dwrite(H5T_NATIVE_CHAR
, uchar_buf
); // expected-warning {{argument type 'unsigned char *' doesn't match specified 'hdf5' type tag that requires 'signed char *'}}
303 H5Dwrite(H5T_NATIVE_SCHAR
, schar_buf
); // no-warning
304 H5Dwrite(H5T_NATIVE_UCHAR
, uchar_buf
); // no-warning
305 H5Dwrite(H5T_NATIVE_INT
, int_buf
); // no-warning
306 H5Dwrite(H5T_NATIVE_LONG
, long_buf
); // no-warning
308 #ifdef __CHAR_UNSIGNED__
309 H5Dwrite(H5T_NATIVE_CHAR
, int_buf
); // expected-warning {{argument type 'int *' doesn't match specified 'hdf5' type tag that requires 'unsigned char *'}}
311 H5Dwrite(H5T_NATIVE_CHAR
, int_buf
); // expected-warning {{argument type 'int *' doesn't match specified 'hdf5' type tag that requires 'signed char *'}}
313 H5Dwrite(H5T_NATIVE_INT
, long_buf
); // expected-warning {{argument type 'long *' doesn't match specified 'hdf5' type tag that requires 'int *'}}
315 // FIXME: we should warn here, but it will cause false positives because
316 // different kinds may use same magic values.
317 //H5Dwrite(MPI_INT, int_buf);