(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
c2x-enum-6.c
       1  /* Test C2x enumerations with fixed underlying type.  Valid code.  */
       2  /* { dg-do run } */
       3  /* { dg-options "-std=c2x -pedantic-errors" } */
       4  
       5  /* Check a type while defining an enum (via a diagnostic for incompatible
       6     pointer types if the wrong type was chosen).  */
       7  #define TYPE_CHECK(cst, type)						\
       8    cst ## _type_check = sizeof (1 ? (type *) 0 : (typeof (cst) *) 0)
       9  
      10  extern int i;
      11  
      12  enum e1 : short { e1a = __SHRT_MAX__,
      13      TYPE_CHECK (e1a, short),
      14      e1z = (long long) 0,
      15      TYPE_CHECK (e1z, enum e1),
      16      e1b = -__SHRT_MAX__ - 1,
      17      e1c,
      18      TYPE_CHECK (e1c, enum e1) };
      19  extern enum e1 e1v;
      20  extern typeof (e1a) e1v;
      21  extern typeof (e1b) e1v;
      22  extern typeof (e1c) e1v;
      23  extern typeof (e1z) e1v;
      24  extern short e1v;
      25  static_assert (e1a == __SHRT_MAX__);
      26  static_assert (e1b == -__SHRT_MAX__ - 1);
      27  static_assert (e1c == -__SHRT_MAX__);
      28  static_assert (e1a > 0);
      29  static_assert (e1b < 0);
      30  static_assert (e1c < 0);
      31  static_assert (e1z == 0);
      32  extern typeof (+e1v) i;
      33  extern typeof (+e1a) i;
      34  extern typeof (e1a + e1b) i;
      35  enum e1 : short;
      36  enum e1 : volatile short;
      37  enum e1 : _Atomic short;
      38  enum e1 : typeof (short);
      39  
      40  enum e2 : bool { b0, b1, b0a = 0, b1a = 1 };
      41  extern enum e2 e2v;
      42  extern typeof (b0) e2v;
      43  extern typeof (b0a) e2v;
      44  extern typeof (b1) e2v;
      45  extern typeof (b1a) e2v;
      46  extern bool e2v;
      47  extern typeof (+e2v) i;
      48  extern typeof (+b0) i;
      49  static_assert (b0 == 0);
      50  static_assert (b1 == 1);
      51  static_assert (b0a == 0);
      52  static_assert (b1a == 1);
      53  
      54  enum e3 : volatile const _Atomic unsigned short;
      55  enum e3 : unsigned short { e3a, e3b };
      56  extern enum e3 e3v;
      57  extern typeof (e3a) e3v;
      58  extern typeof (e3b) e3v;
      59  extern unsigned short e3v;
      60  
      61  /* The enum type is complete from the end of the first enum type specifier
      62     (which is nested inside another enum type specifier in this example).  */
      63  enum e4 : typeof ((enum e4 : long { e4a = sizeof (enum e4) })0, 0L);
      64  extern enum e4 e4v;
      65  extern typeof (e4a) e4v;
      66  extern long e4v;
      67  
      68  enum e5 : unsigned int;
      69  extern enum e5 e5v;
      70  extern typeof (e5v + e5v) e5v;
      71  extern unsigned int e5v;
      72  
      73  enum : unsigned short { e6a, e6b, TYPE_CHECK (e6a, unsigned short) } e6v;
      74  extern typeof (e6a) e6v;
      75  extern typeof (e6b) e6v;
      76  extern unsigned short e6v;
      77  
      78  struct s1;
      79  struct s2 { int a; };
      80  union u1;
      81  union u2 { int a; };
      82  enum xe1 { XE1 };
      83  enum xe2 : long long { XE2 };
      84  enum xe3 : unsigned long;
      85  
      86  void
      87  f ()
      88  {
      89    /* Tags can be redeclared in an inner scope.  */
      90    enum s1 : char;
      91    enum s2 : int { S2 };
      92    enum u1 : long { U1 };
      93    enum u2 : unsigned char;
      94    enum xe1 : long long;
      95    enum xe2 : short;
      96    enum xe3 : char { XE3 };
      97    static_assert (sizeof (enum xe3) == 1);
      98    static_assert (sizeof (enum xe2) == sizeof (short));
      99    static_assert (sizeof (enum xe1) == sizeof (long long));
     100  }
     101  
     102  void *p;
     103  typeof (nullptr) np;
     104  
     105  extern void abort (void);
     106  extern void exit (int);
     107  
     108  int
     109  main ()
     110  {
     111    /* Conversions to enums with fixed underlying type have the same semantics as
     112       converting to the underlying type.  */
     113    volatile enum e1 e1vm;
     114    volatile enum e2 e2vm;
     115    e1vm = __LONG_LONG_MAX__; /* { dg-warning "overflow" } */
     116    if (e1vm != (short) __LONG_LONG_MAX__)
     117      abort ();
     118    e2vm = 10;
     119    if (e2vm != 1)
     120      abort ();
     121    e2vm = 0;
     122    if (e2vm != 0)
     123      abort ();
     124    /* Arithmetic on enums with fixed underlying type has the same semantics as
     125       arithmetic on the underlying type; in particular, the special semantics
     126       for bool apply to enums with bool as fixed underlying type.  */
     127    if (e2vm++ != 0)
     128      abort ();
     129    if (e2vm != 1)
     130      abort ();
     131    if (e2vm++ != 1)
     132      abort ();
     133    if (e2vm != 1)
     134      abort ();
     135    if (e2vm-- != 1)
     136      abort ();
     137    if (e2vm != 0)
     138      abort ();
     139    if (e2vm-- != 0)
     140      abort ();
     141    if (e2vm != 1)
     142      abort ();
     143    if (++e2vm != 1)
     144      abort ();
     145    if (e2vm != 1)
     146      abort ();
     147    e2vm = 0;
     148    if (++e2vm != 1)
     149      abort ();
     150    if (e2vm != 1)
     151      abort ();
     152    if (--e2vm != 0)
     153      abort ();
     154    if (e2vm != 0)
     155      abort ();
     156    if (--e2vm != 1)
     157      abort ();
     158    if (e2vm != 1)
     159      abort ();
     160    e2vm = p;
     161    e2vm = np;
     162    e2vm = (bool) p;
     163    e2vm = (bool) np;
     164    if (e2vm != 0)
     165      abort ();
     166    exit (0);
     167  }