summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaCXX/builtin-constant-p.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaCXX/builtin-constant-p.cpp')
-rw-r--r--clang/test/SemaCXX/builtin-constant-p.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/builtin-constant-p.cpp b/clang/test/SemaCXX/builtin-constant-p.cpp
new file mode 100644
index 00000000000..252c7bbac57
--- /dev/null
+++ b/clang/test/SemaCXX/builtin-constant-p.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++17 -verify %s
+
+using intptr_t = __INTPTR_TYPE__;
+
+// Test interaction of constexpr and __builtin_constant_p.
+
+template<typename T> constexpr bool bcp(T t) {
+ return __builtin_constant_p(t);
+}
+template<typename T> constexpr bool bcp_fold(T t) {
+ return __builtin_constant_p(((void)(intptr_t)&t, t));
+}
+
+constexpr intptr_t ensure_fold_is_generally_not_enabled = // expected-error {{constant expression}}
+ (intptr_t)&ensure_fold_is_generally_not_enabled; // expected-note {{cast}}
+
+constexpr intptr_t ptr_to_int(const void *p) {
+ return __builtin_constant_p(1) ? (intptr_t)p : (intptr_t)p;
+}
+
+constexpr int *int_to_ptr(intptr_t n) {
+ return __builtin_constant_p(1) ? (int*)n : (int*)n;
+}
+
+int x;
+
+// Integer and floating point constants encountered during constant expression
+// evaluation are considered constant. So is nullptr_t.
+static_assert(bcp(1));
+static_assert(bcp_fold(1));
+static_assert(bcp(1.0));
+static_assert(bcp_fold(1.0));
+static_assert(bcp(nullptr));
+static_assert(bcp_fold(nullptr));
+
+// Pointers to the start of strings are considered constant.
+static_assert(bcp("foo"));
+static_assert(bcp_fold("foo"));
+
+// Null pointers are considered constant.
+static_assert(bcp<int*>(nullptr));
+static_assert(bcp_fold<int*>(nullptr));
+static_assert(bcp<const char*>(nullptr));
+static_assert(bcp_fold<const char*>(nullptr));
+
+// Other pointers are not.
+static_assert(!bcp(&x));
+static_assert(!bcp_fold(&x));
+
+// Pointers cast to integers follow the rules for pointers.
+static_assert(bcp(ptr_to_int("foo")));
+static_assert(bcp_fold(ptr_to_int("foo")));
+static_assert(!bcp(ptr_to_int(&x)));
+static_assert(!bcp_fold(ptr_to_int(&x)));
+
+// Integers cast to pointers follow the integer rules.
+static_assert(bcp(int_to_ptr(0)));
+static_assert(bcp_fold(int_to_ptr(0)));
+static_assert(bcp(int_to_ptr(123))); // GCC rejects these due to not recognizing
+static_assert(bcp_fold(int_to_ptr(123))); // the bcp conditional in 'int_to_ptr' ...
+static_assert(__builtin_constant_p((int*)123)); // ... but GCC accepts this
OpenPOWER on IntegriCloud