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