xref: /llvm-project/clang/test/Sema/nullptr.c (revision 7fd58339b4c783f240904aa5c1007e017378ada1)
1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c2x -ffreestanding -Wno-null-conversion -Wno-tautological-compare %s
2 #include <stdint.h>
3 
4 typedef typeof(nullptr) nullptr_t;
5 
6 struct A {};
7 
8 __attribute__((overloadable)) int o1(char*);
9 __attribute__((overloadable)) void o1(uintptr_t);
10 
11 nullptr_t f(nullptr_t null)
12 {
13   // Implicit conversions.
14   null = nullptr;
15   void *p = nullptr;
16   p = null;
17   int *pi = nullptr;
18   pi = null;
19   null = 0;
20   bool b = nullptr;
21 
22   // Can't convert nullptr to integral implicitly.
23   uintptr_t i = nullptr; // expected-error-re {{initializing 'uintptr_t' (aka '{{.*}}') with an expression of incompatible type 'nullptr_t'}}
24 
25   // Operators
26   (void)(null == nullptr);
27   (void)(null <= nullptr); // expected-error {{invalid operands to binary expression}}
28   (void)(null == 0);
29   (void)(null == (void*)0);
30   (void)((void*)0 == nullptr);
31   (void)(null <= 0); // expected-error {{invalid operands to binary expression}}
32   (void)(null <= (void*)0); // expected-error {{invalid operands to binary expression}}
33   (void)((void*)0 <= nullptr); // expected-error {{invalid operands to binary expression}}
34   (void)(0 == nullptr);
35   (void)(nullptr == 0);
36   (void)(nullptr <= 0); // expected-error {{invalid operands to binary expression}}
37   (void)(0 <= nullptr); // expected-error {{invalid operands to binary expression}}
38   (void)(1 > nullptr); // expected-error {{invalid operands to binary expression}}
39   (void)(1 != nullptr); // expected-error {{invalid operands to binary expression}}
40   (void)(1 + nullptr); // expected-error {{invalid operands to binary expression}}
41   (void)(0 ? nullptr : 0); // expected-error {{non-pointer operand type 'int' incompatible with nullptr}}
42   (void)(0 ? nullptr : (void*)0);
43   (void)(0 ? nullptr : (struct A){}); // expected-error {{non-pointer operand type 'struct A' incompatible with nullptr}}
44   (void)(0 ? (struct A){} : nullptr); // expected-error {{non-pointer operand type 'struct A' incompatible with nullptr}}
45 
46   // Overloading
47   int t = o1(nullptr);
48   t = o1(null);
49 
50   // nullptr is an rvalue, null is an lvalue
51   (void)&nullptr; // expected-error {{cannot take the address of an rvalue of type 'nullptr_t'}}
52   nullptr_t *pn = &null;
53 
54   int *ip = *pn;
55   if (*pn) { }
56 }
57 
58 __attribute__((overloadable)) void *g(void*);
59 __attribute__((overloadable)) bool g(bool);
60 
61 // Test that we prefer g(void*) over g(bool).
62 static_assert(__builtin_types_compatible_p(typeof(g(nullptr)), void *), "");
63 
64 void sent(int, ...) __attribute__((sentinel));
65 
66 void g() {
67   // nullptr can be used as the sentinel value.
68   sent(10, nullptr);
69 }
70 
71 void printf(const char*, ...) __attribute__((format(printf, 1, 2)));
72 
73 void h() {
74   // Don't warn when using nullptr with %p.
75   printf("%p", nullptr);
76 }
77 
78 static_assert(sizeof(nullptr_t) == sizeof(void*), "");
79 
80 static_assert(!nullptr, "");
81 static_assert(!(bool){nullptr}, "");
82 
83 static_assert(!(nullptr < nullptr), ""); // expected-error {{invalid operands to binary expression}}
84 static_assert(!(nullptr > nullptr), ""); // expected-error {{invalid operands to binary expression}}
85 static_assert(  nullptr <= nullptr, ""); // expected-error {{invalid operands to binary expression}}
86 static_assert(  nullptr >= nullptr, ""); // expected-error {{invalid operands to binary expression}}
87 static_assert(  nullptr == nullptr, "");
88 static_assert(!(nullptr != nullptr), "");
89 
90 static_assert(!(0 < nullptr), ""); // expected-error {{invalid operands to binary expression}}
91 static_assert(!(0 > nullptr), ""); // expected-error {{invalid operands to binary expression}}
92 static_assert(  0 <= nullptr, ""); // expected-error {{invalid operands to binary expression}}
93 static_assert(  0 >= nullptr, ""); // expected-error {{invalid operands to binary expression}}
94 static_assert(  0 == nullptr, "");
95 static_assert(!(0 != nullptr), "");
96 
97 static_assert(!(nullptr < 0), ""); // expected-error {{invalid operands to binary expression}}
98 static_assert(!(nullptr > 0), ""); // expected-error {{invalid operands to binary expression}}
99 static_assert(  nullptr <= 0, ""); // expected-error {{invalid operands to binary expression}}
100 static_assert(  nullptr >= 0, ""); // expected-error {{invalid operands to binary expression}}
101 static_assert(  nullptr == 0, "");
102 static_assert(!(nullptr != 0), "");
103 
104 __attribute__((overloadable)) int f1(int*);
105 __attribute__((overloadable)) float f1(bool);
106 
107 void test_f1() {
108   int ir = (f1)(nullptr);
109 }
110 
111 // __nullptr keyword in C
112 void foo(void *);
113 void bar() { foo(__nullptr); }
114 static_assert(nullptr == __nullptr);
115 static_assert(__nullptr == 0);  // Test that its value matches that of NULL
116 static_assert(_Generic(typeof(__nullptr), nullptr_t: true, default: false));
117 static_assert(_Generic(__typeof(__nullptr), int : 0, void * : 0, default : 1)); // Test that it's type is not the same as what NULL would generally have.
118