[clang] [Clang] Make __builtin_assume_dereferenceable constexpr (PR #169869)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 28 00:18:00 PST 2025
================
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 -triple x86_64-unknown-unknown %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 -triple x86_64-unknown-unknown %s -fexperimental-new-constant-interpreter
+
+constexpr int arr[10] = {};
+
+constexpr bool test_constexpr_valid() {
+ __builtin_assume_dereferenceable(arr, 40);
+ return true;
+}
+static_assert(test_constexpr_valid(), "");
+
+constexpr bool test_constexpr_partial() {
+ __builtin_assume_dereferenceable(&arr[5], 20);
+ return true;
+}
+static_assert(test_constexpr_partial(), "");
+
+constexpr bool test_constexpr_nullptr() {
+ __builtin_assume_dereferenceable(nullptr, 4);
+ return true;
+}
+static_assert(test_constexpr_nullptr(), ""); // expected-error {{not an integral constant expression}}
+
+constexpr bool test_constexpr_too_large() {
+ __builtin_assume_dereferenceable(arr, 100);
+ return true;
+}
+static_assert(test_constexpr_too_large(), ""); // expected-error {{not an integral constant expression}}
+
+constexpr int single_var = 42;
+constexpr bool test_single_var() {
+ __builtin_assume_dereferenceable(&single_var, 4);
+ return true;
+}
+static_assert(test_single_var(), "");
+
+constexpr bool test_exact_boundary() {
+ __builtin_assume_dereferenceable(&arr[9], 4);
+ return true;
+}
+static_assert(test_exact_boundary(), "");
+
+constexpr bool test_one_over() {
+ __builtin_assume_dereferenceable(&arr[9], 5);
+ return true;
+}
+static_assert(test_one_over(), ""); // expected-error {{not an integral constant expression}}
+
+constexpr bool test_zero_size() {
+ __builtin_assume_dereferenceable(arr, 0);
+ return true;
+}
+static_assert(test_zero_size(), ""); // expected-error {{not an integral constant expression}}
+
+struct S {
+ int x;
+ int y;
+};
+constexpr S s = {1, 2};
+constexpr bool test_struct_member() {
+ __builtin_assume_dereferenceable(&s.x, 4);
+ return true;
+}
+static_assert(test_struct_member(), "");
----------------
tbaederr wrote:
You're only testing constant contexts.
For e.g.
```c++
const int f = (__builtin_assume_dereferenceable((int*)123, 4), 12);
int a = f;
```
should we get a global initializer? I _can_ read 4 bytes from that pointers, right?
I'm not 100% sure how this builtin is supposed to work in any case. I initially thought it would return the status but if it doesn't, does it make sense to just ignore it in constant expressions? All actual reads will be checked as usual. @philnik777?
https://github.com/llvm/llvm-project/pull/169869
More information about the cfe-commits
mailing list