xref: /llvm-project/clang/test/AST/ByteCode/nullable.cpp (revision a07aba5d44204a7ca0d891a3da05af9960081e4c)
1*a07aba5dSTimm Baeder // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
2*a07aba5dSTimm Baeder // RUN: %clang_cc1 -verify=ref,both %s
3*a07aba5dSTimm Baeder 
4*a07aba5dSTimm Baeder 
5*a07aba5dSTimm Baeder constexpr int dummy = 1;
6*a07aba5dSTimm Baeder constexpr const int *null = nullptr;
7*a07aba5dSTimm Baeder 
8*a07aba5dSTimm Baeder namespace simple {
9*a07aba5dSTimm Baeder   __attribute__((nonnull))
10*a07aba5dSTimm Baeder   constexpr int simple1(const int*) {
11*a07aba5dSTimm Baeder     return 1;
12*a07aba5dSTimm Baeder   }
13*a07aba5dSTimm Baeder   static_assert(simple1(&dummy) == 1, "");
14*a07aba5dSTimm Baeder   static_assert(simple1(nullptr) == 1, ""); // both-error {{not an integral constant expression}} \
15*a07aba5dSTimm Baeder                                             // both-note {{null passed to a callee}}
16*a07aba5dSTimm Baeder   static_assert(simple1(null) == 1, ""); // both-error {{not an integral constant expression}} \
17*a07aba5dSTimm Baeder                                          // both-note {{null passed to a callee}}
18*a07aba5dSTimm Baeder 
19*a07aba5dSTimm Baeder   __attribute__((nonnull)) // both-warning {{applied to function with no pointer arguments}}
20*a07aba5dSTimm Baeder   constexpr int simple2(const int &a) {
21*a07aba5dSTimm Baeder     return 12;
22*a07aba5dSTimm Baeder   }
23*a07aba5dSTimm Baeder   static_assert(simple2(1) == 12, "");
24*a07aba5dSTimm Baeder }
25*a07aba5dSTimm Baeder 
26*a07aba5dSTimm Baeder namespace methods {
27*a07aba5dSTimm Baeder   struct S {
28*a07aba5dSTimm Baeder     __attribute__((nonnull(2))) // both-warning {{only applies to pointer arguments}}
29*a07aba5dSTimm Baeder     __attribute__((nonnull(3)))
30*a07aba5dSTimm Baeder     constexpr int foo(int a, const void *p) const {
31*a07aba5dSTimm Baeder       return 12;
32*a07aba5dSTimm Baeder     }
33*a07aba5dSTimm Baeder 
34*a07aba5dSTimm Baeder     __attribute__((nonnull(3)))
35*a07aba5dSTimm Baeder     constexpr int foo2(...) const {
36*a07aba5dSTimm Baeder       return 12;
37*a07aba5dSTimm Baeder     }
38*a07aba5dSTimm Baeder 
39*a07aba5dSTimm Baeder     __attribute__((nonnull))
40*a07aba5dSTimm Baeder     constexpr int foo3(...) const {
41*a07aba5dSTimm Baeder       return 12;
42*a07aba5dSTimm Baeder     }
43*a07aba5dSTimm Baeder   };
44*a07aba5dSTimm Baeder 
45*a07aba5dSTimm Baeder   constexpr S s{};
46*a07aba5dSTimm Baeder   static_assert(s.foo(8, &dummy) == 12, "");
47*a07aba5dSTimm Baeder 
48*a07aba5dSTimm Baeder   static_assert(s.foo2(nullptr) == 12, "");
49*a07aba5dSTimm Baeder   static_assert(s.foo2(1, nullptr) == 12, ""); // both-error {{not an integral constant expression}} \
50*a07aba5dSTimm Baeder                                                // both-note {{null passed to a callee}}
51*a07aba5dSTimm Baeder 
52*a07aba5dSTimm Baeder   constexpr S *s2 = nullptr;
53*a07aba5dSTimm Baeder   static_assert(s2->foo3() == 12, ""); // both-error {{not an integral constant expression}} \
54*a07aba5dSTimm Baeder                                        // both-note {{member call on dereferenced null pointer}}
55*a07aba5dSTimm Baeder }
56*a07aba5dSTimm Baeder 
57*a07aba5dSTimm Baeder namespace fnptrs {
58*a07aba5dSTimm Baeder   __attribute__((nonnull))
59*a07aba5dSTimm Baeder   constexpr int add(int a, const void *p) {
60*a07aba5dSTimm Baeder     return a + 1;
61*a07aba5dSTimm Baeder   }
62*a07aba5dSTimm Baeder   __attribute__((nonnull(3)))
63*a07aba5dSTimm Baeder   constexpr int applyBinOp(int a, int b, int (*op)(int, const void *)) {
64*a07aba5dSTimm Baeder     return op(a, nullptr); // both-note {{null passed to a callee}}
65*a07aba5dSTimm Baeder   }
66*a07aba5dSTimm Baeder   static_assert(applyBinOp(10, 20, add) == 11, ""); // both-error {{not an integral constant expression}} \
67*a07aba5dSTimm Baeder                                                     // both-note {{in call to}}
68*a07aba5dSTimm Baeder 
69*a07aba5dSTimm Baeder   static_assert(applyBinOp(10, 20, nullptr) == 11, ""); // both-error {{not an integral constant expression}} \
70*a07aba5dSTimm Baeder                                                         // both-note {{null passed to a callee}}
71*a07aba5dSTimm Baeder }
72*a07aba5dSTimm Baeder 
73*a07aba5dSTimm Baeder namespace lambdas {
74*a07aba5dSTimm Baeder   auto lstatic = [](const void *P) __attribute__((nonnull)) { return 3; };
75*a07aba5dSTimm Baeder   static_assert(lstatic(nullptr) == 3, ""); // both-error {{not an integral constant expression}} \
76*a07aba5dSTimm Baeder                                             // both-note {{null passed to a callee}}
77*a07aba5dSTimm Baeder }
78