1  /* Test __builtin_complex semantics.  */
       2  /* { dg-do run } */
       3  /* { dg-options "-std=c11 -pedantic-errors" } */
       4  /* { dg-require-effective-target inf } */
       5  /* { dg-add-options ieee } */
       6  
       7  extern void exit (int);
       8  extern void abort (void);
       9  
      10  #define COMPARE_BODY(A, B, TYPE, COPYSIGN)				\
      11    do {									\
      12      TYPE s1 = COPYSIGN ((TYPE) 1.0, A);					\
      13      TYPE s2 = COPYSIGN ((TYPE) 1.0, B);					\
      14      if (s1 != s2)							\
      15        abort ();								\
      16      if ((__builtin_isnan (A) != 0) != (__builtin_isnan (B) != 0))	\
      17        abort ();								\
      18      if ((A != B) != (__builtin_isnan (A) != 0))				\
      19        abort ();								\
      20    } while (0)
      21  
      22  void
      23  comparef (float a, float b)
      24  {
      25    COMPARE_BODY (a, b, float, __builtin_copysignf);
      26  }
      27  
      28  void
      29  compare (double a, double b)
      30  {
      31    COMPARE_BODY (a, b, double, __builtin_copysign);
      32  }
      33  
      34  void
      35  comparel (long double a, long double b)
      36  {
      37    COMPARE_BODY (a, b, long double, __builtin_copysignl);
      38  }
      39  
      40  void
      41  comparecf (_Complex float a, float r, float i)
      42  {
      43    comparef (__real__ a, r);
      44    comparef (__imag__ a, i);
      45  }
      46  
      47  void
      48  comparec (_Complex double a, double r, double i)
      49  {
      50    compare (__real__ a, r);
      51    compare (__imag__ a, i);
      52  }
      53  
      54  void
      55  comparecl (_Complex long double a, long double r, long double i)
      56  {
      57    comparel (__real__ a, r);
      58    comparel (__imag__ a, i);
      59  }
      60  
      61  #define VERIFY(A, B, TYPE, COMPARE)			\
      62    do {							\
      63      TYPE a = A;						\
      64      TYPE b = B;						\
      65      _Complex TYPE cr = __builtin_complex (a, b);	\
      66      static _Complex TYPE cs = __builtin_complex (A, B);	\
      67      COMPARE (cr, A, B);					\
      68      COMPARE (cs, A, B);					\
      69    } while (0)
      70  
      71  #define ALL_CHECKS(PZ, NZ, NAN, INF, TYPE, COMPARE)	\
      72    do {							\
      73      VERIFY (PZ, PZ, TYPE, COMPARE);			\
      74      VERIFY (PZ, NZ, TYPE, COMPARE);			\
      75      VERIFY (PZ, NAN, TYPE, COMPARE);			\
      76      VERIFY (PZ, INF, TYPE, COMPARE);			\
      77      VERIFY (NZ, PZ, TYPE, COMPARE);			\
      78      VERIFY (NZ, NZ, TYPE, COMPARE);			\
      79      VERIFY (NZ, NAN, TYPE, COMPARE);			\
      80      VERIFY (NZ, INF, TYPE, COMPARE);			\
      81      VERIFY (NAN, PZ, TYPE, COMPARE);			\
      82      VERIFY (NAN, NZ, TYPE, COMPARE);			\
      83      VERIFY (NAN, NAN, TYPE, COMPARE);			\
      84      VERIFY (NAN, INF, TYPE, COMPARE);			\
      85      VERIFY (INF, PZ, TYPE, COMPARE);			\
      86      VERIFY (INF, NZ, TYPE, COMPARE);			\
      87      VERIFY (INF, NAN, TYPE, COMPARE);			\
      88      VERIFY (INF, INF, TYPE, COMPARE);			\
      89    } while (0)
      90  
      91  void
      92  check_float (void)
      93  {
      94    ALL_CHECKS (0.0f, -0.0f, __builtin_nanf(""), __builtin_inff(),
      95  	      float, comparecf);
      96  }
      97  
      98  void
      99  check_double (void)
     100  {
     101    ALL_CHECKS (0.0, -0.0, __builtin_nan(""), __builtin_inf(),
     102  	      double, comparec);
     103  }
     104  
     105  void
     106  check_long_double (void)
     107  {
     108    ALL_CHECKS (0.0l, -0.0l, __builtin_nanl(""), __builtin_infl(),
     109  	      long double, comparecl);
     110  }
     111  
     112  int
     113  main (void)
     114  {
     115    check_float ();
     116    check_double ();
     117    check_long_double ();
     118    exit (0);
     119  }