Home | History | Annotate | Download | only in Sema
      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