Revert "[llvm] Improve llvm.objectsize computation by computing GEP, alloca and mallo...
[llvm-project.git] / clang / test / CodeGen / ignore-overflow-pattern.c
blobc4a9d07b07aaacd34161bf2abaa09f2716eca4ca
1 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsanitize=signed-integer-overflow,unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=all %s -emit-llvm -o - | FileCheck %s
2 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsanitize=signed-integer-overflow,unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=all -fwrapv %s -emit-llvm -o - | FileCheck %s
3 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsanitize=signed-integer-overflow,unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=add-signed-overflow-test,add-unsigned-overflow-test %s -emit-llvm -o - | FileCheck %s --check-prefix=ADD
4 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsanitize=signed-integer-overflow,unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=negated-unsigned-const %s -emit-llvm -o - | FileCheck %s --check-prefix=NEGATE
5 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsanitize=signed-integer-overflow,unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=unsigned-post-decr-while %s -emit-llvm -o - | FileCheck %s --check-prefix=WHILE
7 // Ensure some common overflow-dependent or overflow-prone code patterns don't
8 // trigger the overflow sanitizers. In many cases, overflow warnings caused by
9 // these patterns are seen as "noise" and result in users turning off
10 // sanitization all together.
12 // A pattern like "if (a + b < a)" simply checks for overflow and usually means
13 // the user is trying to handle it gracefully.
15 // Similarly, a pattern resembling "while (i--)" is extremely common and
16 // warning on its inevitable overflow can be seen as superfluous. Do note that
17 // using "i" in future calculations can be tricky because it will still
18 // wrap-around.
20 // Another common pattern that, in some cases, is found to be too noisy is
21 // unsigned negation, for example:
22 // unsigned long A = -1UL;
25 // CHECK-NOT: handle{{.*}}overflow
27 extern unsigned a, b, c;
28 extern int u, v;
29 extern unsigned some(void);
31 // ADD-LABEL: @basic_commutativity
32 // WHILE-LABEL: @basic_commutativity
33 // NEGATE-LABEL: @basic_commutativity
34 // WHILE: handler.add_overflow
35 // NEGATE: handler.add_overflow
36 // ADD-NOT: handler.add_overflow
37 void basic_commutativity(void) {
38 if (a + b < a)
39 c = 9;
40 if (a + b < b)
41 c = 9;
42 if (b + a < b)
43 c = 9;
44 if (b + a < a)
45 c = 9;
46 if (a > a + b)
47 c = 9;
48 if (a > b + a)
49 c = 9;
50 if (b > a + b)
51 c = 9;
52 if (b > b + a)
53 c = 9;
54 if (u + v < u)
55 c = 9;
58 // ADD-LABEL: @arguments_and_commutativity
59 // WHILE-LABEL: @arguments_and_commutativity
60 // NEGATE-LABEL: @arguments_and_commutativity
61 // WHILE: handler.add_overflow
62 // NEGATE: handler.add_overflow
63 // ADD-NOT: handler.add_overflow
64 void arguments_and_commutativity(unsigned V1, unsigned V2) {
65 if (V1 + V2 < V1)
66 c = 9;
67 if (V1 + V2 < V2)
68 c = 9;
69 if (V2 + V1 < V2)
70 c = 9;
71 if (V2 + V1 < V1)
72 c = 9;
73 if (V1 > V1 + V2)
74 c = 9;
75 if (V1 > V2 + V1)
76 c = 9;
77 if (V2 > V1 + V2)
78 c = 9;
79 if (V2 > V2 + V1)
80 c = 9;
83 // ADD-LABEL: @pointers
84 // WHILE-LABEL: @pointers
85 // NEGATE-LABEL: @pointers
86 // WHILE: handler.add_overflow
87 // NEGATE: handler.add_overflow
88 // ADD-NOT: handler.add_overflow
89 void pointers(unsigned *P1, unsigned *P2, unsigned V1) {
90 if (*P1 + *P2 < *P1)
91 c = 9;
92 if (*P1 + V1 < V1)
93 c = 9;
94 if (V1 + *P2 < *P2)
95 c = 9;
98 struct OtherStruct {
99 unsigned foo, bar;
102 struct MyStruct {
103 unsigned base, offset;
104 struct OtherStruct os;
107 extern struct MyStruct ms;
109 // ADD-LABEL: @structs
110 // WHILE-LABEL: @structs
111 // NEGATE-LABEL: @structs
112 // WHILE: handler.add_overflow
113 // NEGATE: handler.add_overflow
114 // ADD-NOT: handler.add_overflow
115 void structs(void) {
116 if (ms.base + ms.offset < ms.base)
117 c = 9;
120 // ADD-LABEL: @nestedstructs
121 // WHILE-LABEL: @nestedstructs
122 // NEGATE-LABEL: @nestedstructs
123 // WHILE: handler.add_overflow
124 // NEGATE: handler.add_overflow
125 // ADD-NOT: handler.add_overflow
126 void nestedstructs(void) {
127 if (ms.os.foo + ms.os.bar < ms.os.foo)
128 c = 9;
131 // ADD-LABEL: @constants
132 // WHILE-LABEL: @constants
133 // NEGATE-LABEL: @constants
134 // WHILE: handler.add_overflow
135 // NEGATE: handler.add_overflow
136 // ADD-NOT: handler.add_overflow
137 // Normally, this would be folded into a simple call to the overflow handler
138 // and a store. Excluding this pattern results in just a store.
139 void constants(void) {
140 unsigned base = 4294967295;
141 unsigned offset = 1;
142 if (base + offset < base)
143 c = 9;
145 // ADD-LABEL: @common_while
146 // NEGATE-LABEL: @common_while
147 // WHILE-LABEL: @common_while
148 // ADD: usub.with.overflow
149 // NEGATE: usub.with.overflow
150 // WHILE: %dec = add i32 %0, -1
151 void common_while(unsigned i) {
152 // This post-decrement usually causes overflow sanitizers to trip on the very
153 // last operation.
154 while (i--) {
155 some();
159 // ADD-LABEL: @negation
160 // NEGATE-LABEL: @negation
161 // WHILE-LABEL @negation
162 // ADD: negate_overflow
163 // NEGATE-NOT: negate_overflow
164 // WHILE: negate_overflow
165 // Normally, these assignments would trip the unsigned overflow sanitizer.
166 void negation(void) {
167 #define SOME -1UL
168 unsigned long A = -1UL;
169 unsigned long B = -2UL;
170 unsigned long C = -SOME;
171 (void)A;(void)B;(void)C;
175 // ADD-LABEL: @function_call
176 // WHILE-LABEL: @function_call
177 // NEGATE-LABEL: @function_call
178 // WHILE: handler.add_overflow
179 // NEGATE: handler.add_overflow
180 // ADD-NOT: handler.add_overflow
181 void function_call(void) {
182 if (b + some() < b)
183 c = 9;