File: trivial-auto-var-init-skip-scalar-with-nonconst-init.cpp

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (121 lines) | stat: -rw-r--r-- 4,142 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s -check-prefix=UNINIT
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO

template<typename T> void used(T &) noexcept;

extern "C" {

extern int get_int(int) noexcept;
struct C {
  int x;
  int y;
};
extern C make_c() noexcept;

// Scalar with a self-reference: does need auto-init.
// UNINIT-LABEL:  test_selfinit_call(
// ZERO-LABEL:    test_selfinit_call(
// ZERO: store i32 0, ptr %self, align 4, !annotation [[AUTO_INIT:!.+]]
// PATTERN-LABEL: test_selfinit_call(
// PATTERN: store i32 -1431655766, ptr %self, align 4, !annotation [[AUTO_INIT:!.+]]
void test_selfinit_call() {
  int self = get_int(self);
  used(self);
}

// Scalar without a self-reference: no auto-init needed.
// UNINIT-LABEL:  test_nonself_call(
// ZERO-LABEL:    test_nonself_call(
// ZERO-NOT: !annotation [[AUTO_INIT:!.+]]
// PATTERN-LABEL: test_nonself_call(
// PATTERN-NOT: !annotation [[AUTO_INIT:!.+]]
void test_nonself_call() {
  int x = get_int(2);
  used(x);
}

// Scalar with a self-reference: does need auto-init.
// UNINIT-LABEL:  test_selfinit_lambda_call(
// ZERO-LABEL:    test_selfinit_lambda_call(
// ZERO: store i32 0, ptr %self, align 4, !annotation [[AUTO_INIT:!.+]]
// PATTERN-LABEL: test_selfinit_lambda_call(
// PATTERN: store i32 -1431655766, ptr %self, align 4, !annotation [[AUTO_INIT:!.+]]
void test_selfinit_lambda_call() {
  int self = [&](){ return self; }();
  used(self);
}

// Scalar with a self-reference: does need auto-init.
// UNINIT-LABEL:  test_selfinit_gnu_stmt_expression(
// ZERO-LABEL:    test_selfinit_gnu_stmt_expression(
// ZERO: store i32 0, ptr %self, align 4, !annotation [[AUTO_INIT:!.+]]
// PATTERN-LABEL: test_selfinit_gnu_stmt_expression(
// PATTERN: store i32 -1431655766, ptr %self, align 4, !annotation [[AUTO_INIT:!.+]]
void test_selfinit_gnu_stmt_expression() {
  int self = ({int x = self; x + 1; });
  used(self);
}

// Not a scalar: auto-init just in case
// UNINIT-LABEL:  test_nonscalar_call(
// ZERO-LABEL:    test_nonscalar_call(
// ZERO: call void @llvm.memset{{.*}}, i8 0, i64 8, {{.*}} !annotation [[AUTO_INIT:!.+]]
// PATTERN-LABEL: test_nonscalar_call(
// PATTERN: call void @llvm.memcpy{{.*}}, i64 8, {{.*}} !annotation [[AUTO_INIT:!.+]]
void test_nonscalar_call() {
  C c = make_c();
  used(c);
}

// Scalar with a self-reference: does need auto-init.
// UNINIT-LABEL:  test_self_ptr(
// ZERO-LABEL:    test_self_ptr(
// ZERO: store ptr null, ptr %self, align 8, !annotation [[AUTO_INIT:!.+]]
// PATTERN-LABEL: test_self_ptr(
// PATTERN: store ptr inttoptr (i64 -6148914691236517206 to ptr), ptr %self, align 8, !annotation [[AUTO_INIT:!.+]]
void test_self_ptr() {
  void* self = self;
  used(self);
}

// Scalar without a self-reference: no auto-init needed.
// UNINIT-LABEL:  test_nonself_ptr(
// ZERO-LABEL:    test_nonself_ptr(
// ZERO-NOT: !annotation [[AUTO_INIT:!.+]]
// PATTERN-LABEL: test_nonself_ptr(
// PATTERN-NOT: !annotation [[AUTO_INIT:!.+]]
void test_nonself_ptr() {
  int y = 0;
  void* x = &y;
  used(x);
}

// Scalar with a self-reference: does need auto-init.
// UNINIT-LABEL:  test_self_complex(
// ZERO-LABEL:    test_self_complex(
// ZERO: call void @llvm.memset{{.*}} !annotation [[AUTO_INIT:!.+]]
// PATTERN-LABEL: test_self_complex(
// PATTERN: call void @llvm.memcpy{{.*}} !annotation [[AUTO_INIT:!.+]]
void test_self_complex() {
  _Complex float self = 3.0 * 3.0 * self;
  used(self);
}

// Scalar without a self-reference: no auto-init needed.
// UNINIT-LABEL:  test_nonself_complex(
// ZERO-LABEL:    test_nonself_complex(
// ZERO-NOT: !annotation [[AUTO_INIT:!.+]]
// PATTERN-LABEL: test_nonself_complex(
// PATTERN-NOT: !annotation [[AUTO_INIT:!.+]]
void test_nonself_complex() {
  _Complex float y = 0.0;
  _Complex float x = 3.0 * 3.0 * y;
  used(x);
}

} // extern "C"

// ZERO: [[AUTO_INIT]] = !{!"auto-init"}
// PATTERN: [[AUTO_INIT]] = !{!"auto-init"}