brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.3 KiB · 1a9c5b0 Raw
320 lines · c
1// RUN: %clang_cc1 -std=c99 -DOPEN_MPI -fsyntax-only -verify %s2// RUN: %clang_cc1 -std=c99 -DMPICH -fsyntax-only -verify %s3// RUN: %clang_cc1 -x c++ -std=c++98 -DOPEN_MPI -fsyntax-only -verify %s4// RUN: %clang_cc1 -x c++ -std=c++98 -DMPICH -fsyntax-only -verify %s5//6// RUN: %clang_cc1 -std=c99 -DOPEN_MPI -fno-signed-char -fsyntax-only -verify %s7// RUN: %clang_cc1 -std=c99 -DMPICH -fno-signed-char -fsyntax-only -verify %s8 9//===--- limits.h mock ----------------------------------------------------===//10 11#ifdef __CHAR_UNSIGNED__12#define CHAR_MIN 013#define CHAR_MAX (__SCHAR_MAX__*2  +1)14#else15#define CHAR_MIN (-__SCHAR_MAX__-1)16#define CHAR_MAX __SCHAR_MAX__17#endif18 19//===--- mpi.h mock -------------------------------------------------------===//20 21#define NULL ((void *)0)22 23#ifdef OPEN_MPI24typedef struct ompi_datatype_t *MPI_Datatype;25#endif26 27#ifdef MPICH28typedef int MPI_Datatype;29#endif30 31int MPI_Send(void *buf, int count, MPI_Datatype datatype)32    __attribute__(( pointer_with_type_tag(mpi,1,3) ));33 34int 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) ));37 38#ifdef OPEN_MPI39// OpenMPI and LAM/MPI-style datatype definitions40 41#define OMPI_PREDEFINED_GLOBAL(type, global) ((type) &(global))42 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)49 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)52 53#define MPI_IN_PLACE ((void *) 1)54 55extern struct ompi_predefined_datatype_t ompi_mpi_datatype_null __attribute__(( type_tag_for_datatype(mpi,void,must_be_null) ));56extern struct ompi_predefined_datatype_t ompi_mpi_float         __attribute__(( type_tag_for_datatype(mpi,float) ));57extern struct ompi_predefined_datatype_t ompi_mpi_int           __attribute__(( type_tag_for_datatype(mpi,int) ));58extern struct ompi_predefined_datatype_t ompi_mpi_long          __attribute__(( type_tag_for_datatype(mpi,long) ));59extern struct ompi_predefined_datatype_t ompi_mpi_long_long_int __attribute__(( type_tag_for_datatype(mpi,long long int) ));60extern struct ompi_predefined_datatype_t ompi_mpi_char          __attribute__(( type_tag_for_datatype(mpi,char) ));61 62struct ompi_struct_mpi_float_int {float f; int i;};63extern struct ompi_predefined_datatype_t ompi_mpi_float_int     __attribute__(( type_tag_for_datatype(mpi, struct ompi_struct_mpi_float_int, layout_compatible) ));64 65struct ompi_struct_mpi_2int {int i1; int i2;};66extern struct ompi_predefined_datatype_t ompi_mpi_2int          __attribute__(( type_tag_for_datatype(mpi, struct ompi_struct_mpi_2int, layout_compatible) ));67#endif68 69#ifdef MPICH70// MPICH2 and MVAPICH2-style datatype definitions71 72#define MPI_COMM_WORLD ((MPI_Comm) 0x44000000)73 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)80 81#define MPI_FLOAT_INT     ((MPI_Datatype) 0xa0000006)82#define MPI_2INT          ((MPI_Datatype) 0xa0000007)83 84#define MPI_IN_PLACE  (void *) -185 86static const MPI_Datatype mpich_mpi_datatype_null __attribute__(( type_tag_for_datatype(mpi,void,must_be_null) )) = 0xa0000000;87static const MPI_Datatype mpich_mpi_float         __attribute__(( type_tag_for_datatype(mpi,float) ))             = 0xa0000001;88static const MPI_Datatype mpich_mpi_int           __attribute__(( type_tag_for_datatype(mpi,int) ))               = 0xa0000002;89static const MPI_Datatype mpich_mpi_long          __attribute__(( type_tag_for_datatype(mpi,long) ))              = 0xa0000003;90static const MPI_Datatype mpich_mpi_long_long_int __attribute__(( type_tag_for_datatype(mpi,long long int) ))     = 0xa0000004;91static const MPI_Datatype mpich_mpi_char          __attribute__(( type_tag_for_datatype(mpi,char) ))              = 0xa0000005;92 93struct mpich_struct_mpi_float_int { float f; int i; };94struct mpich_struct_mpi_2int { int i1; int i2; };95static const MPI_Datatype mpich_mpi_float_int     __attribute__(( type_tag_for_datatype(mpi, struct mpich_struct_mpi_float_int, layout_compatible) )) = 0xa0000006;96static const MPI_Datatype mpich_mpi_2int          __attribute__(( type_tag_for_datatype(mpi, struct mpich_struct_mpi_2int, layout_compatible) )) = 0xa0000007;97#endif98 99//===--- HDF5 headers mock ------------------------------------------------===//100 101typedef int hid_t;102void H5open(void);103 104#ifndef HDF_PRIVATE105#define H5OPEN  H5open(),106#else107#define H5OPEN108#endif109 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)115 116hid_t H5T_NATIVE_SCHAR_g __attribute__(( type_tag_for_datatype(hdf5,signed char) ));117hid_t H5T_NATIVE_UCHAR_g __attribute__(( type_tag_for_datatype(hdf5,unsigned char) ));118hid_t H5T_NATIVE_INT_g   __attribute__(( type_tag_for_datatype(hdf5,int) ));119hid_t H5T_NATIVE_LONG_g  __attribute__(( type_tag_for_datatype(hdf5,long) ));120 121void H5Dwrite(hid_t mem_type_id, const void *buf) __attribute__(( pointer_with_type_tag(hdf5,2,1) ));122 123//===--- Tests ------------------------------------------------------------===//124 125//===--- MPI126 127struct pair_float_int128{129  float f; int i;130};131 132struct pair_int_int133{134  int i1; int i2;135};136 137void test_mpi_predefined_types(138    int *int_buf,139    long *long_buf1,140    long *long_buf2,141    void *void_buf,142    struct pair_float_int *pfi,143    struct pair_int_int *pii)144{145  char char_buf[255];146 147  // Layout-compatible scalar types.148  MPI_Send(int_buf,   1, MPI_INT); // no-warning149 150  // Null pointer constant.151  MPI_Send(0,         0, MPI_INT); // no-warning152  MPI_Send(NULL,      0, MPI_INT); // no-warning153 154  // Layout-compatible class types.155  MPI_Send(pfi, 1, MPI_FLOAT_INT); // no-warning156  MPI_Send(pii, 1, MPI_2INT); // no-warning157 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 *'}}160 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}}164 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}}167 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 *'}}171 172  // Array buffers should work like pointer buffers.173  MPI_Send(char_buf,  255, MPI_CHAR); // no-warning174 175  // Explicit casts should not be dropped.176  MPI_Send((int *) char_buf,  255, MPI_INT); // no-warning177  MPI_Send((int *) char_buf,  255, MPI_CHAR); // expected-warning {{argument type 'int *' doesn't match specified 'mpi' type tag that requires 'char *'}}178 179  // `void*' buffer should never warn.180  MPI_Send(void_buf,  255, MPI_CHAR); // no-warning181 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);185 186  // Special handling for MPI_DATATYPE_NULL: buffer pointer should be either187  // a `void*' pointer or a null pointer constant.188  MPI_Gather(NULL,    0, MPI_DATATYPE_NULL, // no-warning189             int_buf, 1, MPI_INT);190 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);193}194 195MPI_Datatype my_int_datatype __attribute__(( type_tag_for_datatype(mpi,int) ));196 197struct S1 { int a; int b; };198MPI_Datatype my_s1_datatype __attribute__(( type_tag_for_datatype(mpi,struct S1) ));199 200// Layout-compatible to S1, but should be treated as a different type.201struct S2 { int a; int b; };202MPI_Datatype my_s2_datatype __attribute__(( type_tag_for_datatype(mpi,struct S2) ));203 204enum E1 { Foo };205MPI_Datatype my_e1_datatype __attribute__(( type_tag_for_datatype(mpi,enum E1) ));206 207void test_user_types(int *int_buf,208                     long *long_buf,209                     struct S1 *s1_buf,210                     struct S2 *s2_buf,211                     enum E1 *e1_buf)212{213  MPI_Send(int_buf,  1, my_int_datatype); // no-warning214  MPI_Send(long_buf, 1, my_int_datatype); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'int *'}}215 216  MPI_Send(s1_buf, 1, my_s1_datatype); // no-warning217  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 *'}}218 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 *'}}221 222  MPI_Send(e1_buf, 1, my_e1_datatype); // no-warning223  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 *'}}225}226 227MPI_Datatype my_unknown_datatype;228 229void test_not_annotated(int *int_buf,230                        long *long_buf,231                        MPI_Datatype type)232{233  // Using 'MPI_Datatype's without attributes should not produce warnings.234  MPI_Send(long_buf, 1, my_unknown_datatype); // no-warning235  MPI_Send(int_buf, 1, type); // no-warning236}237 238struct S1_compat { int a; int b; };239MPI_Datatype my_s1_compat_datatype240    __attribute__(( type_tag_for_datatype(mpi, struct S1_compat, layout_compatible) ));241 242struct S3        { int a; long b; double c; double d; struct S1 s1; };243struct S3_compat { int a; long b; double c; double d; struct S2 s2; };244MPI_Datatype my_s3_compat_datatype245    __attribute__(( type_tag_for_datatype(mpi, struct S3_compat, layout_compatible) ));246 247struct S4        { char c; };248struct S4_compat { signed char c; };249MPI_Datatype my_s4_compat_datatype250    __attribute__(( type_tag_for_datatype(mpi, struct S4_compat, layout_compatible) ));251 252union U1        { int a; long b; double c; double d; struct S1 s1; };253union U1_compat { long b; double c; struct S2 s; int a; double d; };254MPI_Datatype my_u1_compat_datatype255    __attribute__(( type_tag_for_datatype(mpi, union U1_compat, layout_compatible) ));256 257union U2 { int a; long b; double c; struct S1 s1; };258MPI_Datatype my_u2_datatype259    __attribute__(( type_tag_for_datatype(mpi, union U2, layout_compatible) ));260 261void test_layout_compatibility(struct S1 *s1_buf, struct S3 *s3_buf,262                               struct S4 *s4_buf,263                               union U1 *u1_buf, union U2 *u2_buf)264{265  MPI_Send(s1_buf, 1, my_s1_compat_datatype); // no-warning266  MPI_Send(s3_buf, 1, my_s3_compat_datatype); // no-warning267  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-warning270  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}}272}273 274// There is an MPI_REAL predefined in MPI, but some existing MPI programs do275// this.276typedef float real;277#define MPI_REAL MPI_FLOAT278 279void test_mpi_real_user_type(real *real_buf, float *float_buf)280{281  MPI_Send(real_buf,  1, MPI_REAL);  // no-warning282  MPI_Send(real_buf,  1, MPI_FLOAT); // no-warning283  MPI_Send(float_buf, 1, MPI_REAL);  // no-warning284  MPI_Send(float_buf, 1, MPI_FLOAT); // no-warning285}286 287//===--- HDF5288 289void test_hdf5(char *char_buf,290               signed char *schar_buf,291               unsigned char *uchar_buf,292               int *int_buf,293               long *long_buf)294{295  H5Dwrite(H5T_NATIVE_CHAR,  char_buf);  // no-warning296#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-warning299#else300  H5Dwrite(H5T_NATIVE_CHAR,  schar_buf); // no-warning301  H5Dwrite(H5T_NATIVE_CHAR,  uchar_buf); // expected-warning {{argument type 'unsigned char *' doesn't match specified 'hdf5' type tag that requires 'signed char *'}}302#endif303  H5Dwrite(H5T_NATIVE_SCHAR, schar_buf); // no-warning304  H5Dwrite(H5T_NATIVE_UCHAR, uchar_buf); // no-warning305  H5Dwrite(H5T_NATIVE_INT,   int_buf);   // no-warning306  H5Dwrite(H5T_NATIVE_LONG,  long_buf);  // no-warning307 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 *'}}310#else311  H5Dwrite(H5T_NATIVE_CHAR,  int_buf);  // expected-warning {{argument type 'int *' doesn't match specified 'hdf5' type tag that requires 'signed char *'}}312#endif313  H5Dwrite(H5T_NATIVE_INT,   long_buf); // expected-warning {{argument type 'long *' doesn't match specified 'hdf5' type tag that requires 'int *'}}314 315  // FIXME: we should warn here, but it will cause false positives because316  // different kinds may use same magic values.317  //H5Dwrite(MPI_INT, int_buf);318}319 320