1 // RUN: %clang_cc1 -std=c++17 -verify %s
2 // RUN: %clang_cc1 -std=c++20 -verify %s
3 
4 using intptr_t = __INTPTR_TYPE__;
5 
6 // Test interaction of constexpr and __builtin_constant_p.
7 
bcp(T t)8 template<typename T> constexpr bool bcp(T t) {
9   return __builtin_constant_p(t);
10 }
bcp_fold(T t)11 template<typename T> constexpr bool bcp_fold(T t) {
12   return __builtin_constant_p(((void)(intptr_t)&t, t));
13 }
14 
15 constexpr intptr_t ensure_fold_is_generally_not_enabled = // expected-error {{constant expression}}
16     (intptr_t)&ensure_fold_is_generally_not_enabled; // expected-note {{cast}}
17 
ptr_to_int(const void * p)18 constexpr intptr_t ptr_to_int(const void *p) {
19   return __builtin_constant_p(1) ? (intptr_t)p : (intptr_t)p;
20 }
21 
int_to_ptr(intptr_t n)22 constexpr int *int_to_ptr(intptr_t n) {
23   return __builtin_constant_p(1) ? (int*)n : (int*)n;
24 }
25 
26 int x;
27 
28 // Integer and floating point constants encountered during constant expression
29 // evaluation are considered constant. So is nullptr_t.
30 static_assert(bcp(1));
31 static_assert(bcp_fold(1));
32 static_assert(bcp(1.0));
33 static_assert(bcp_fold(1.0));
34 static_assert(bcp(nullptr));
35 static_assert(bcp_fold(nullptr));
36 
37 // Pointers to the start of strings are considered constant.
38 static_assert(bcp("foo"));
39 static_assert(bcp_fold("foo"));
40 
41 // Null pointers are considered constant.
42 static_assert(bcp<int*>(nullptr));
43 static_assert(bcp_fold<int*>(nullptr));
44 static_assert(bcp<const char*>(nullptr));
45 static_assert(bcp_fold<const char*>(nullptr));
46 
47 // Other pointers are not.
48 static_assert(!bcp(&x));
49 static_assert(!bcp_fold(&x));
50 
51 // Pointers cast to integers follow the rules for pointers.
52 static_assert(bcp(ptr_to_int("foo")));
53 static_assert(bcp_fold(ptr_to_int("foo")));
54 static_assert(!bcp(ptr_to_int(&x)));
55 static_assert(!bcp_fold(ptr_to_int(&x)));
56 
57 // Integers cast to pointers follow the integer rules.
58 static_assert(bcp(int_to_ptr(0)));
59 static_assert(bcp_fold(int_to_ptr(0)));
60 static_assert(bcp(int_to_ptr(123)));      // GCC rejects these due to not recognizing
61 static_assert(bcp_fold(int_to_ptr(123))); // the bcp conditional in 'int_to_ptr' ...
62 static_assert(__builtin_constant_p((int*)123)); // ... but GCC accepts this
63 
64 // State mutations in the operand are not permitted.
65 //
66 // The rule GCC uses for this is not entirely understood, but seems to depend
67 // in some way on what local state is mentioned in the operand of
68 // __builtin_constant_p and where.
69 //
70 // We approximate GCC's rule by evaluating the operand in a speculative
71 // evaluation context; only state created within the evaluation can be
72 // modified.
mutate1()73 constexpr int mutate1() {
74   int n = 1;
75   int m = __builtin_constant_p(++n);
76   return n * 10 + m;
77 }
78 static_assert(mutate1() == 10);
79 
80 // FIXME: GCC treats this as being non-constant because of the "n = 2", even
81 // though evaluation in the context of the enclosing constant expression
82 // succeeds without mutating any state.
mutate2()83 constexpr int mutate2() {
84   int n = 1;
85   int m = __builtin_constant_p(n ? n + 1 : n = 2);
86   return n * 10 + m;
87 }
88 static_assert(mutate2() == 11);
89 
internal_mutation(int unused)90 constexpr int internal_mutation(int unused) {
91   int x = 1;
92   ++x;
93   return x;
94 }
95 
mutate3()96 constexpr int mutate3() {
97   int n = 1;
98   int m = __builtin_constant_p(internal_mutation(0));
99   return n * 10 + m;
100 }
101 static_assert(mutate3() == 11);
102 
mutate4()103 constexpr int mutate4() {
104   int n = 1;
105   int m = __builtin_constant_p(n ? internal_mutation(0) : 0);
106   return n * 10 + m;
107 }
108 static_assert(mutate4() == 11);
109 
110 // FIXME: GCC treats this as being non-constant because of something to do with
111 // the 'n' in the argument to internal_mutation.
mutate5()112 constexpr int mutate5() {
113   int n = 1;
114   int m = __builtin_constant_p(n ? internal_mutation(n) : 0);
115   return n * 10 + m;
116 }
117 static_assert(mutate5() == 11);
118 
mutate_param(bool mutate,int & param)119 constexpr int mutate_param(bool mutate, int &param) {
120   mutate = mutate; // Mutation of internal state is OK
121   if (mutate)
122     ++param;
123   return param;
124 }
mutate6(bool mutate)125 constexpr int mutate6(bool mutate) {
126   int n = 1;
127   int m = __builtin_constant_p(mutate_param(mutate, n));
128   return n * 10 + m;
129 }
130 // No mutation of state outside __builtin_constant_p: evaluates to true.
131 static_assert(mutate6(false) == 11);
132 // Mutation of state outside __builtin_constant_p: evaluates to false.
133 static_assert(mutate6(true) == 10);
134 
135 // GCC strangely returns true for the address of a type_info object, despite it
136 // not being a pointer to the start of a string literal.
137 namespace std { struct type_info; }
138 static_assert(__builtin_constant_p(&typeid(int)));
139 
mutate_as_side_effect()140 void mutate_as_side_effect() {
141   int a;
142   static_assert(!__builtin_constant_p(((void)++a, 1)));
143 }
144 
145 namespace dtor_side_effect {
146   struct A {
Adtor_side_effect::A147     constexpr A() {}
148     ~A();
149   };
150   static_assert(!__builtin_constant_p((A{}, 123)));
151 }
152 
153 #if __cplusplus >= 202002L
154 namespace constexpr_dtor {
155   struct A {
156     int *p;
~Aconstexpr_dtor::A157     constexpr ~A() { *p = 0; }
158   };
getconstexpr_dtor::Q159   struct Q { int n; constexpr int *get() { return &n; } };
160   static_assert(!__builtin_constant_p((A{}, 123)));
161   // FIXME: We should probably accept this. GCC does.
162   // However, GCC appears to do so by running the destructors at the end of the
163   // enclosing full-expression, which seems broken; running them at the end of
164   // the evaluation of the __builtin_constant_p argument would be more
165   // defensible.
166   static_assert(!__builtin_constant_p((A{Q().get()}, 123)));
167 }
168 #endif
169