Skip to content

Commit 7d684e2

Browse files
committed
Add codegen tests to verify constexpr passthrough for non-constexpr const initialization
1 parent fb0af15 commit 7d684e2

File tree

2 files changed

+52
-23
lines changed

2 files changed

+52
-23
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs
2+
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++14 -emit-llvm -o - %s | FileCheck %s
3+
4+
constexpr int b = 10;
5+
int test_char_cast() {
6+
const int f = (__builtin_assume_dereferenceable((char*)&b + 1, 3), 12);
7+
return f;
8+
}
9+
10+
constexpr long long ll = 100;
11+
int test_void_cast() {
12+
const int h = (__builtin_assume_dereferenceable((void*)&ll, 8), 99);
13+
return h;
14+
}
15+
16+
constexpr int gb = 10;
17+
const int gf = (__builtin_assume_dereferenceable((char*)&gb + 1, 3), 12);
18+
int ga = gf;
19+
20+
// CHECK-LABEL: test_char_castv
21+
// CHECK: [[F:%.*]] = alloca i32, align 4
22+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr getelementptr inbounds (i8, ptr @_ZL1b, i64 1), i64 3) ]
23+
// CHECK-NEXT: store i32 12, ptr [[F]], align 4
24+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[F]], align 4
25+
// CHECK-NEXT: ret i32 [[TMP0]]
26+
//
27+
//
28+
// CHECK-LABEL: test_void_castv
29+
// CHECK: [[H:%.*]] = alloca i32, align 4
30+
// CHECK-NEXT: store i32 99, ptr [[H]], align 4
31+
// CHECK-NEXT: ret i32 99
32+
//
33+
//
34+
// CHECK-LABEL: __cxx_global_var_init
35+
// CHECK: [[TMP0:%.*]] = load i32, ptr @_ZL2gf, align 4
36+
// CHECK-NEXT: store i32 [[TMP0]], ptr @ga, align 4
37+
// CHECK-NEXT: ret void
38+
//
39+
//
40+
// CHECK-LABEL: __cxx_global_var_init.1
41+
// CHECK: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr getelementptr inbounds (i8, ptr @_ZL2gb, i64 1), i64 3) ]
42+
// CHECK-NEXT: store i32 12, ptr @_ZL2gf, align 4
43+
// CHECK-NEXT: ret void
44+
//
45+
//
46+
// CHECK-LABEL: _GLOBAL__sub_I_builtin_assume_dereferenceable_constexpr.cpp
47+
// CHECK: call void @__cxx_global_var_init.1()
48+
// CHECK-NEXT: call void @__cxx_global_var_init()
49+
// CHECK-NEXT: ret void
50+
//

clang/test/SemaCXX/builtin-assume-dereferenceable-constexpr.cpp

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ static_assert(test_zero_size(), "");
5858

5959
constexpr bool test_struct_member() {
6060
struct S {
61-
int x;
62-
int y;
61+
int x;
62+
int y;
6363
};
6464
constexpr S s = {1, 2};
6565
__builtin_assume_dereferenceable(&s.x, 4);
@@ -90,24 +90,3 @@ constexpr int arr2[5] = {1, 2, 3, 4, 5};
9090
constexpr int too_large = (__builtin_assume_dereferenceable(arr2, 6 * sizeof(int)), 12); // expected-error {{constexpr variable 'too_large' must be initialized by a constant expression}} expected-note {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
9191

9292
constexpr int null = (__builtin_assume_dereferenceable(nullptr, 4), 12); // expected-error {{constexpr variable 'null' must be initialized by a constant expression}} expected-note {{read of dereferenced null pointer is not allowed in a constant expression}}
93-
94-
int b = 10;
95-
const int f = (__builtin_assume_dereferenceable((char*)&b + 1, 3), 12);
96-
int a = f;
97-
98-
int c[10] = {};
99-
const int g = (__builtin_assume_dereferenceable((unsigned char*)c + 5, 35), 42);
100-
int d = g;
101-
102-
long long ll = 100;
103-
const int h = (__builtin_assume_dereferenceable((void*)&ll, 8), 99);
104-
int e = h;
105-
106-
struct Foo { int x; int y; int z; };
107-
Foo foo = {1, 2, 3};
108-
const int i = (__builtin_assume_dereferenceable((short*)&foo + 2, 8), 77);
109-
int j = i;
110-
111-
double darr[10] = {};
112-
const int k = (__builtin_assume_dereferenceable((int*)darr, 40), 55);
113-
int l = k;

0 commit comments

Comments
 (0)