1  /* { dg-do run } */
       2  /* { dg-options "-O1 -Wall" } */
       3  
       4  #define choose __builtin_choose_expr
       5  
       6  /* Check the type of __builtin_choose_expr between E1 and E2, both
       7     ways round and with both 0 and 1 as the condition.  */
       8  #define ASSERT_COND_TYPE(E1, E2)				\
       9          do {							\
      10            typedef __typeof(E1) T1;				\
      11            typedef __typeof(E2) T2;				\
      12            typedef T1 **T1pp;					\
      13            typedef T2 **T2pp;					\
      14            typedef __typeof(choose (1, (E1), (E2))) T1a;		\
      15            typedef __typeof(choose (0, (E2), (E1))) T1b;		\
      16            typedef __typeof(choose (1, (E2), (E1))) T2a;		\
      17            typedef __typeof(choose (0, (E1), (E2))) T2b;		\
      18            typedef T1a **T1app;					\
      19            typedef T1b **T1bpp;					\
      20            typedef T2a **T2app;					\
      21            typedef T2b **T2bpp;					\
      22            T1pp t1 = 0;						\
      23            T2pp t2 = 0;						\
      24            T1app t1a = 0;					\
      25            T1bpp t1b = 0;					\
      26            T2app t2a = 0;					\
      27            T2bpp t2b = 0;					\
      28            t1 = t1a;						\
      29            t1 = t1b;						\
      30            t2 = t2a;						\
      31            t2 = t2b;						\
      32            (void) t1;						\
      33            (void) t2;						\
      34          } while (0)
      35  
      36  
      37  extern void abort ();
      38  extern void exit ();
      39  
      40  void bad ()
      41  {
      42    abort ();
      43  }
      44  
      45  void good ()
      46  {
      47    exit (0);
      48  }
      49  
      50  int main (void)
      51  {
      52    signed char sc1, sc2;
      53    void *v1;
      54    int i, j;
      55    double dd;
      56    float f;
      57    typedef void (*fpt)(void);
      58    fpt triple;
      59    struct S { int x, y; } pour, some, sugar;
      60    union u { int p; } united, nations;
      61  
      62    if (__builtin_choose_expr (0, 12, 0)
      63        || !__builtin_choose_expr (45, 5, 0)
      64        || !__builtin_choose_expr (45, 3, 0))
      65      abort ();
      66  
      67    ASSERT_COND_TYPE (sc1, sc2);
      68    ASSERT_COND_TYPE (v1, sc1);
      69    ASSERT_COND_TYPE (i, j);
      70    ASSERT_COND_TYPE (dd, main);
      71    ASSERT_COND_TYPE ((float)dd, i);
      72    ASSERT_COND_TYPE (4, f);
      73    ASSERT_COND_TYPE (triple, some);
      74    ASSERT_COND_TYPE (united, nations);
      75    ASSERT_COND_TYPE (nations, main);
      76  
      77    pour.y = 69;
      78    __builtin_choose_expr (0, bad (), sugar) = pour;
      79    if (sugar.y != 69)
      80      abort ();
      81  
      82    __builtin_choose_expr (sizeof (int), f, bad ()) = 3.5F;
      83  
      84    if (f != 3.5F)
      85      abort ();
      86  
      87    __builtin_choose_expr (1, good, bad)();
      88  
      89    exit (0);
      90  }