(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
c2x-nullptr-1.c
       1  /* Test valid usage of C23 nullptr.  */
       2  /* { dg-do run } */
       3  /* { dg-options "-std=c2x -pedantic-errors -Wall -Wextra -Wno-unused-variable" } */
       4  
       5  #include <stdarg.h>
       6  
       7  typedef __typeof__(nullptr) nullptr_t;
       8  
       9  void f1 (nullptr_t) { }
      10  void f2 (int *) { }
      11  void f3 (_Bool) { }
      12  nullptr_t cmp (void) { return nullptr; }
      13  
      14  /* The type nullptr_t shall not be converted to any type other than void, bool
      15     or a pointer type.  No type other than nullptr_t or a null pointer constant
      16     shall be converted to nullptr_t.  */
      17  void
      18  test1 (void)
      19  {
      20    const nullptr_t nptr = nullptr;
      21    static nullptr_t static_nptr;
      22    int *p1 = nullptr;
      23    void *p2 = nullptr;
      24    float *p3 = nullptr;
      25    void (*p4)(int) = nullptr;
      26    int (*p5)[10] = nullptr;
      27    int *p6 = nptr;
      28    void *p7 = nptr;
      29    float *p8 = nptr;
      30    void (*p9)(int) = nptr;
      31    int (*p10)[10] = nptr;
      32    int *p11 = (int *) nullptr;
      33    int *p12 = (int *) nptr;
      34    int *p13 = (nullptr);
      35    int *p14 = _Generic(0, int : nullptr);
      36    if (nullptr || p1 || p2 || p3 || p4 || p5 || p6 || p7 || p8 || p9 || p10
      37        || p11 || p12 || p13 || p14)
      38      __builtin_abort ();
      39  
      40    _Bool b1 = nullptr;
      41    _Bool b2 = (_Bool) nullptr;
      42    _Bool b3 = nptr;
      43    _Bool b4 = (_Bool) nptr;
      44    _Bool b5 = _Generic(0, int : nullptr);
      45    if (b1 || b2 || b3 || b4 || b5 || (_Bool) nullptr || (_Bool) nptr)
      46     __builtin_abort ();
      47  
      48    __auto_type a1 = nullptr;
      49    __auto_type a2 = nptr;
      50  
      51    /* We can convert nullptr_t to nullptr_t.  */
      52    __typeof__(nullptr) x = nullptr;
      53    f1 (x);
      54    f1 (nullptr);
      55    f1 (_Generic(0, int : nullptr));
      56    f2 (x);
      57    f2 (nullptr);
      58    f3 (nullptr);
      59  
      60    const nullptr_t np1 = nullptr;
      61    const nullptr_t np2 = np1;
      62    (void) nullptr;
      63    (void) np1;
      64    (void) np2;
      65    (void) cmp ();
      66    (void)(nullptr_t) nullptr;
      67  
      68    const nullptr_t n = 0;
      69    (void) (nullptr_t) 0;
      70  
      71    f1 (0);
      72    f1 ((void *) 0);
      73    f1 (0L);
      74    nullptr_t n2;
      75    n2 = (void *) 0;
      76    n2 = 123 - 123;
      77    (void) n2;
      78  }
      79  
      80  /* Test valid comparison.  */
      81  void
      82  test2 (int *p)
      83  {
      84    /* If both operands have type nullptr_t or one operand has type nullptr_t
      85       and the other is a null pointer constant, they compare equal.  */
      86    const nullptr_t nptr = nullptr;
      87    int r = 0;
      88  
      89    /* Both operands have type nullptr_t.  */
      90    r |= nullptr != nullptr;
      91    r |= cmp () != nullptr;
      92    r |= nullptr != cmp ();
      93    r |= !(nullptr == nullptr);
      94    r |= !(cmp () == nullptr);
      95    r |= !(nullptr == cmp ());
      96    r |= nptr != nptr;
      97    r |= cmp () != nptr;
      98    r |= nptr != cmp ();
      99    r |= !(nptr == nptr);
     100    r |= !(cmp () == nptr);
     101    r |= !(nptr == cmp ());
     102  
     103   /* One operand has type nullptr_t and the other is a null pointer constant.  */
     104    r |= nullptr != (void *) 0;
     105    r |= _Generic(0, int : nullptr) != (void *) 0;
     106    r |= (nullptr) != (void *) 0;
     107    r |= !(nullptr == (void *) 0);
     108    r |= (void *) 0 != nullptr;
     109    r |= (void *) 0 != (nullptr);
     110    r |= !((void *) 0 == nullptr);
     111    r |= nullptr != 0;
     112    r |= _Generic(0, int : nullptr) != 0;
     113    r |= (nullptr) != 0;
     114    r |= 0 != nullptr;
     115    r |= 0 != (nullptr);
     116    r |= !(nullptr == 0);
     117    r |= !(0 == nullptr);
     118    r |= nullptr != 0u;
     119    r |= 0u != nullptr;
     120    r |= !(nullptr == 0u);
     121    r |= !(0u == nullptr);
     122    r |= nptr != (void *) 0;
     123    r |= !(nptr == (void *) 0);
     124    r |= (void *) 0 != nptr;
     125    r |= !((void *) 0 == nptr);
     126    r |= nptr != 0;
     127    r |= 0 != nptr;
     128    r |= !(nptr == 0);
     129    r |= !(0 == nptr);
     130    r |= nptr != 0u;
     131    r |= 0u != nptr;
     132    r |= !(nptr == 0u);
     133    r |= !(0u == nptr);
     134    r |= nptr != _Generic(0, int : nullptr);
     135    r |= _Generic(0, int : nullptr) != nptr;
     136    if (r)
     137      __builtin_abort ();
     138  
     139    /* One operand is a pointer and the other is a null pointer constant.  */
     140    (void) (p == nullptr);
     141    (void) (p != nullptr);
     142    (void) (nullptr == p);
     143    (void) (nullptr != p);
     144    (void) (p == (nullptr));
     145    (void) (p != (nullptr));
     146    (void) ((nullptr) == p);
     147    (void) ((nullptr) != p);
     148    (void) ((void *)nullptr == nullptr);
     149    (void) ((void *)nullptr != nullptr);
     150    (void) (nullptr == (void *)nullptr);
     151    (void) (nullptr != (void *)nullptr);
     152    (void) (p == _Generic(0, int : nullptr));
     153    (void) (p != _Generic(0, int : nullptr));
     154    (void) (_Generic(0, int : nullptr) == p);
     155    (void) (_Generic(0, int : nullptr) != p);
     156  
     157    /* "(nullptr_t)nullptr" has type nullptr_t but isn't an NPC; these
     158       comparisons are valid after C2X CD comments GB-071 and FR-073 were
     159       resolved by the wording in N3077.  */
     160    (void) ((nullptr_t)nullptr == p);
     161    (void) ((nullptr_t)nullptr != p);
     162    (void) (p == (nullptr_t)nullptr);
     163    (void) (p != (nullptr_t)nullptr);
     164    (void) (cmp () == p);
     165    (void) (cmp () != p);
     166    (void) (p == cmp ());
     167    (void) (p != cmp ());
     168    /* "(void *)nullptr" is not an NPC, either.  */
     169    (void) ((void *)nullptr == cmp ());
     170    (void) ((void *)nullptr != cmp ());
     171    (void) (cmp () == (void *)nullptr);
     172    (void) (cmp () != (void *)nullptr);
     173  }
     174  
     175  /* Test ?:.  */
     176  void
     177  test3 (int *p, _Bool b)
     178  {
     179    int x = nullptr ? 1 : 2;
     180    (void) x;
     181    const nullptr_t nptr = nullptr;
     182    /* One of the following shall hold for the second and third operands:
     183       -- both operands have nullptr_t type.  */
     184    __auto_type r1 = b ? nullptr : nullptr;
     185    __auto_type r2 = b ? nptr : nptr;
     186    /* -- one operand is a pointer and the other is a null pointer constant
     187       or has type nullptr_t;  */
     188    __auto_type r3 = b ? p : nullptr;
     189    __auto_type r4 = b ? nullptr : p;
     190    __auto_type r5 = b ? nptr : p;
     191    __auto_type r6 = b ? p : nptr;
     192    __auto_type r7 = b ? 0 : p;
     193    __auto_type r8 = b ? p : 0;
     194    __auto_type r9 = b ? p : cmp ();
     195    __auto_type r10 = b ?  cmp () : p;
     196    __auto_type r11 = b ? p : _Generic(0, int : nullptr);
     197    __auto_type r12 = b ? _Generic(0, int : nullptr) : p;
     198  }
     199  
     200  void test_arg1 (const nullptr_t, _Atomic nullptr_t, volatile nullptr_t) { }
     201  void test_arg2 (_Atomic int *, const int *, volatile int *) { }
     202  void test_arg3 (_Atomic _Bool, const _Bool, volatile _Bool) { }
     203  nullptr_t retn (void) { return nullptr; }
     204  _Atomic int *ai (void) { return nullptr; }
     205  const int *ci (void) { return nullptr; }
     206  volatile int *vi (void) { return nullptr; }
     207  _Bool retb (void) { return nullptr; }
     208  
     209  /* Simple assignment.  */
     210  void
     211  test4 (void)
     212  {
     213    /* -- the left operand has an atomic, qualified, or unqualified version of
     214       the nullptr_t type and the type of the right is nullptr_t;  */
     215    nullptr_t n1;
     216    const nullptr_t n2 = nullptr;
     217    _Atomic nullptr_t n3 = nullptr;
     218    volatile nullptr_t n4 = nullptr;
     219    _Atomic volatile nullptr_t n5 = nullptr;
     220    n1 = nullptr;
     221    n3 = nullptr;
     222    n4 = nullptr;
     223    n5 = nullptr;
     224    n5 = _Generic(0, int : nullptr);
     225    /* -- the left operand is an atomic, qualified, or unqualified pointer,
     226       and the type of the right is nullptr_t;  */
     227    int *p1 = cmp ();
     228    _Atomic int *p2 = cmp ();
     229    const int *volatile p3 = cmp ();
     230    const int *const *const p4 = cmp ();
     231    double (*const p5)(void) = n1;
     232    p2 = _Generic(0, int : nullptr);
     233    p3 = nullptr;
     234    /* -- the left operand is an atomic, qualified, or unqualified bool, and
     235       the type of the right is nullptr_t;  */
     236    _Bool b1;
     237    b1 = cmp ();
     238    const _Bool b2 = nullptr;
     239    _Atomic _Bool b3;
     240    b3 = n1;
     241    (void) b1;
     242    (void) b3;
     243    (void) n3;
     244    (void) n4;
     245    (void) n5;
     246    (void) p2;
     247    (void) p3;
     248  
     249    test_arg1 (nullptr, nullptr, nullptr);
     250    test_arg2 (nullptr, nullptr, nullptr);
     251    test_arg3 (nullptr, nullptr, nullptr);
     252  }
     253  
     254  /* var_arg etc.  */
     255  static void
     256  test5 (int i, ...)
     257  {
     258    (void) i;
     259    va_list ap;
     260    va_start (ap, i);
     261    if (va_arg (ap, void *))
     262      __builtin_abort ();
     263  }
     264  
     265  /* Operand of alignas, sizeof or typeof operators.  */
     266  void
     267  test6 (void)
     268  {
     269    _Static_assert (sizeof (nullptr) == sizeof (void *), "sizeof (nullptr)");
     270    _Static_assert (sizeof (nullptr_t) == sizeof (void *), "sizeof (nullptr_t)");
     271    _Static_assert (sizeof (nullptr) == sizeof (char *), "sizeof (nullptr)");
     272    _Static_assert (sizeof (nullptr_t) == sizeof (char *), "sizeof (nullptr_t)");
     273    _Static_assert (_Alignof (nullptr_t) == _Alignof (char *), "_Alignof (nullptr_t)");
     274    __typeof__(nullptr) t = nullptr;
     275    f1 (t);
     276    _Alignas (nullptr_t) char i1 = 'q';
     277  
     278    _Static_assert (_Generic (nullptr, nullptr_t: 1, default: 0) == 1, "_Generic");
     279    _Static_assert (_Generic (t, nullptr_t: 1, default: 0) == 1, "_Generic");
     280    _Static_assert (_Generic (cmp (), nullptr_t: 1, default: 0) == 1, "_Generic");
     281    _Static_assert (_Generic (0, nullptr_t: 1, int: 2, default: 0) == 2, "_Generic");
     282    _Static_assert (_Generic ((void *)0, nullptr_t: 1, void *: 2, default: 0) == 2, "_Generic");
     283    _Static_assert (_Generic (nullptr, nullptr_t: 1, void *: 2, default: 0) == 1, "_Generic");
     284  }
     285  
     286  /* Play with !, ||, &&. */
     287  void
     288  test7 (void)
     289  {
     290    if (nullptr)
     291      __builtin_abort ();
     292    if (1 && nullptr)
     293      __builtin_abort ();
     294    if (0 || nullptr)
     295      __builtin_abort ();
     296    if (nullptr && 1)
     297      __builtin_abort ();
     298    if (nullptr || 0)
     299      __builtin_abort ();
     300    if (!nullptr)
     301      {
     302      }
     303    else
     304      __builtin_abort ();
     305    while (nullptr)
     306      __builtin_abort ();
     307    int i = 0;
     308    do
     309      ++i;
     310    while (nullptr);
     311    if (i != 1)
     312      __builtin_abort ();
     313    for (;nullptr;)
     314      __builtin_abort ();
     315  }
     316  
     317  int
     318  main (void)
     319  {
     320    int i = 42;
     321    test1 ();
     322    test2 (&i);
     323    test3 (&i, 0);
     324    test4 ();
     325    test5 (42, nullptr);
     326    test6 ();
     327    test7 ();
     328  }